本案例要求熟悉Linux Shell环境的特点,主要练习以下操作:
实现此案例需要按照如下步骤进行。
步骤一:切换用户的Shell环境
若需要临时使用另一种Shell环境,可以直接执行对应的Shell解释器程序,比如只要执行zsh可以切换到zsh命令行环境。
[root@svr5 ~]# yum -y install zsh //若缺少zsh请先安装zsh包 .. .. [root@svr5 ~]# cat /etc/shells /bin/sh /bin/bash /sbin/nologin /bin/tcsh /bin/csh /bin/ksh /bin/zsh //确认当前系统已识别zsh [root@svr5 ~]# zsh //进入zsh环境 [root@svr5]~# help help //尝试查看内部命令help的用法 zsh: command not found: help //失败,因为zsh未提供内部命令help [root@svr5]~# exit //返回到切换前的bash环境
若希望修改用户的登录Shell,管理员可以直接通过usermod命令设置。比如,以下操作可将用户zhangsan的登录Shell改为/bin/tcsh:
[root@svr5 ~]# grep 'zhangsan' /etc/passwd zhangsan:x:516:516::/home/zhangsan:/bin/bash //修改前 [root@svr5 ~]# usermod -s /bin/tcsh zhangsan //执行修改操作 [root@svr5 ~]# grep 'zhangsan' /etc/passwd zhangsan:x:516:516::/home/zhangsan:/bin/tcsh //修改后
如果需要临时修改登录Shell可以直接在命令行中,输入新的Shell命令即可,如直接通过输入ksh切换:
[root@ svr5 ~]# yum –y install ksh //安装新的ksh [root@ svr5 ~]# ksh //切换Shell # //进入新的Shell
步骤二:练习命令历史
1)检查历史命令的容量。
默认记录1000条,通过全局变量HISTSIZE设置,对所有用户有效:
[root@svr5 ~]# grep HISTSIZE /etc/profile HISTSIZE=1000 export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC
查看已为当前用户记录的历史命令条数:
[root@svr5 ~]# history | wc -l 1000
2)查看历史命令列表。
列出最近执行的10条历史命令:
[root@svr5 ~]# history | tail 1028 grep 'zhangsan' /etc/passwd 1029 cat /etc/redhat-release 1030 usermod -s /bin/tcsh zhangsan 1031 grep 'zhangsan' /etc/passwd 1032 su - zhangsan 1033 echo 1234567 | passwd --stdin zhangsan 1034 su - zhangsan 1035 grep HISTSIZE /etc/profile 1036 history | wc -l 1037 history | tail
3)调用指定的历史命令。
重新执行历史命令列表中的第1028条操作:
[root@svr5 ~]# !1028 grep 'zhangsan' /etc/passwd zhangsan:x:516:516::/home/zhangsan:/bin/bash
重新执行最近一次以cat开头(根据实际情况变更)的历史命令操作:
[root@svr5 ~]# !cat cat /etc/redhat-release Red Hat Enterprise Linux Server release 5.9 (Tikanga)
4)清空已记录的历史命令。
[root@svr5 ~]# history -c //清空自己的历史命令 [root@svr5 ~]# > ~/.bash_history //清空记录文件 [root@svr5 ~]# history //再次检查历史命令列表 42 > ~/.bash_history 43 history
步骤三:练习命令别名
1)查看已经定义的命令别名列表。
当前的别名列表:
[root@svr5 ~]# alias alias cp='cp -i' alias l.='ls -d .* --color=tty' alias ll='ls -l --color=tty' alias ls='ls --color=tty' alias mv='mv -i' alias rm='rm -i' alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
别名设置一般存放在用户的.bashrc文件内:
[root@svr5 ~]# grep '^alias' ~/.bashrc alias rm='rm -i' alias cp='cp -i' alias mv='mv -i'
2)自定义新的命令别名
添加一个名为lh的命令别名,实际执行的是“ls –lh –color=tty”:
[root@svr5 ~]# alias lh='ls -lh' //定义别名命令lh [root@svr5 ~]# alias lh //确认定义结果 alias lh='ls -lh'
验证别名命令的效果:
[root@svr5 ~]# lh /etc/fstab //使用别名 -rw-r--r-- 1 root root 733 10-09 15:34 /etc/fstab [root@svr5 ~]# ls -lh /etc/fstab //使用完整的命令 -rw-r--r-- 1 root root 733 10-09 15:34 /etc/fstab
3)取消别名
取消单个别名:
[root@svr5 ~]# unalias lh //取消名为lh的命令别名 [root@svr5 ~]# alias lh //查询时已没有lh -bash: alias: lh: not found
取消所有别名:
[root@svr5 ~]# unalias -a //取消所有别名 [root@svr5 ~]# alias //查询时已无任何别名 [root@svr5 ~]#
步骤四:重定向标准输入/输出/错误输出
标准输入(stdin),描述号为0;标准输出(stdout),描述号为1;标准错误(stderr),描述号为2。
1)重定向标准输出。
使用 > 将命令执行的正常输出重定向到文件:
[root@svr5 ~]# ls -l /dev/pts/0 //正常应输出到屏幕 crw--w---- 1 root tty 136, 0 12-10 14:04 /dev/pts/0 [root@svr5 ~]# ls -l /dev/pts/0 > stdout.txt //重定向到文件 [root@svr5 ~]# cat stdout.txt //确认重定向输出的结果 crw--w---- 1 root tty 136, 0 12-10 14:04 /dev/pts/0
> 操作会覆盖目标文件(先清空、再写入):
[root@svr5 ~]# echo "I am the king." > stdout.txt //覆盖目标文件 [root@svr5 ~]# cat stdout.txt //确认结果 I am the king.
改用 >> 可实现追加重定向输出:
[root@svr5 ~]# ls -l /dev/pts/0 >> stdout.txt //追加输出 [root@svr5 ~]# cat stdout.txt I am the king. //原有内容还保留 crw--w---- 1 root tty 136, 0 12-10 14:08 /dev/pts/0 //新加的内容
2)重定向标准错误。
对于命令执行出错的信息,使用 > 无法保存,仍然会输出到屏幕。比如,可使用ls命令同时查看两个对象(其中nofile并不存在),重定向输出:
[root@svr5 ~]# ls -lh nofile.txt /etc/fstab > stderr.txt ls: nofile.txt: 没有那个文件或目录 //出错信息仍显示到屏幕 [root@svr5 ~]# cat stderr.txt //正常信息成功重定向到目标文件 -rw-r--r-- 1 root root 733 10-09 15:34 /etc/fstab
使用 2> 可重定向错误信息,比如,可执行一个错误的命令:
[root@svr5 ~]# ipconfig /all -bash: ipconfig: command not found //正常情况下,错误显示到屏幕 [root@svr5 ~]# ipconfig /all 2> stderr.txt //将错误信息重定向到目标文件 [root@svr5 ~]# cat stderr.txt //确认重定向结果 -bash: ipconfig: command not found
类似的,2>> 可实现追加输出:
[root@svr5 ~]# ls nofile 2>> stderr.txt [root@svr5 ~]# cat stderr.txt -bash: ipconfig: command not found ls: nofile: 没有那个文件或目录
若希望将正常输出、错误输出重定向同一个文件,可使用 &> :
[root@svr5 ~]# ls -lh nofile.txt /etc/fstab &> stderr.txt [root@svr5 ~]# cat stderr.txt ls: nofile.txt: 没有那个文件或目录 -rw-r--r-- 1 root root 733 10-09 15:34 /etc/fstab
3)重定向标准输入。
[root@svr5 ~]# mail –s Error root < /etc/passwd
4)案例
[root@svr5 ~]# cat /root/test.sh #!/bin/bash for i in {1..10} do useradd user$i 2>>/root/user.log echo '123456' | passwd --stdin user$i >/dev/null 2>/pass.log done
步骤五:管道操作实践
借助于管道符“|”,可以将一条命令的标准输出交给另一条命令处理,在一条命令行内可依次使用多个管道。
1)统计/etc/目录下资料的数量。
[root@svr5 ~]# ls -l /etc | wc -l 254
2)列出Yum库里名称中含cluster的软件包。
[root@svr5 ~]# yum list | grep cluster cluster-cim.x86_64 0.12.1-7.el5 RHEL5-Cluster cluster-snmp.x86_64 0.12.1-7.el5 RHEL5-Cluster … …
本案例要求编写三个脚本程序,分别实现以下目标:
一个规范的Shell脚本构成包括:
实现此案例需要按照如下步骤进行。
步骤一:编写第一个Shell脚本,输出“Hello World”
1)根据手动任务操作编写脚本文件
[root@svr5 ~]# vim /root/first.sh #!/bin/bash echo 'Hello World' [root@svr5 ~]# chmod +x /root/first.sh //添加可执行权限
2)执行脚本,测试效果
[root@svr5 ~]# /root/first.sh Hello World
3)Shell脚本的执行方式:
方法一,作为“命令字”:指定脚本文件的路径,前提是有 x 权限
[root@svr5 ~]# ./first.sh //指定相对路径 [root@svr5 ~]# /root/first.sh //指定绝对路径
方法二,作为“参数”:使用bash、sh、source或者点号 . 来加载脚本文件
[root@svr5 ~]# bash first.sh //开启子进程 [root@svr5 ~]# sh first.sh //开启子进程 [root@svr5 ~]# source first.sh //不开启子进程 [root@svr5 ~]# . first.sh //不开启子进程
步骤二:编写为本机快速配Yum仓库的Shell脚本
1)Yum仓库配置文件的参考内容如下:
[root@svr5 ~]# vim /etc/yum.repos.d/rhel6.repo [rhel6] name=Red Hat Enterprise Linux 6 baseurl=file:///misc/cd enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
2)根据参考文件的内容,编写脚本内容如下:
[root@svr5 ~]# vim /root/el6repo.sh #!/bin/bash rm -rf /etc/yum.repos.d/*.repo echo '[rhel-packages] name=Red Hat Enterprise Linux 6 baseurl=file:///misc/cd gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release ' > /etc/yum.repos.d/rhel6.repo [root@svr5 ~]# chmod +x /root/el6repo.sh //添加可执行权限
3)执行脚本,测试效果
执行配置Yum仓库的脚本:
[root@svr5 ~]# /root/el6repo.sh
检查配置结果:
[root@svr5 ~]# ls /etc/yum.repos.d/* //仓库配置已建立 /etc/yum.repos.d/rhel6.repo [root@svr5 ~]# yum repolist //Yum仓库已可用 rhel-packages | 3.9 kB 00:00 ... rhel-packages/primary_db | 3.1 MB 00:00 ... repo id repo name status rhel-packages Red Hat Enterprise Linux 6 3,690 repolist: 3,690
步骤三:编写快速装配vsftpd服务的Shell脚本
1)编写参考脚本文件如下:
[root@svr5 ~]# vim /root/ftpon.sh #!/bin/bash yum -y install vsftpd &> /dev/null systemctl start vsftpd systemctl enable vsftpd [root@svr5 ~]# chmod +x /root/ftpon.sh //添加可执行权限
3)执行脚本,测试效果
执行快速装配vsftpd服务的脚本:
[root@svr5 ~]# /root/ftpon.sh
确认脚本执行结果:
[root@svr5 ~]# rpm -q vsftpd vsftpd-3.0.2-10.el7.x86_64 [root@svr5 ~]# systemctl status vsftpd
本案例要求熟悉Shell变量的使用,主要练习或验证下列内容:
除了学会建立和引用变量以外,还要认识环境变量PWD、USER、HOME、SHELL,还有预定义变量$0、$$、$?、$#、$*,以及位置变量$1、$2、$10、……的作用。
实现此案例需要按照如下步骤进行。
步骤一:变量的定义/赋值/查看
1)新建/赋值变量
新建变量SCHOOL,赋值“Tarena IT GROUP”,通过set命令可以检查变量设置:
[root@svr5 ~]# SCHOOL="Tarena IT" [root@svr5 ~]# set | grep SCHOOL SCHOOL='Tarena IT'
2)查看变量
通过echo $变量名 可输出变量值:
[root@svr5 ~]# echo $SCHOOL Tarena IT
查看变量时,若变量名称与后面要输出的字符串连在一起,则应该以{}将变量名括起来以便区分:
[root@svr5 ~]# echo $SCHOOLGroup //无法识别变量名SCHOOL [root@svr5 ~]# echo ${SCHOOL}Group //区分后可以识别 Tarena ITGroup
3)撤销自定义变量
若要撤销已有的变量,可使用unset命令:
[root@svr5 ~]# unset SCHOOL //撤销变量SCHOOL [root@svr5 ~]# echo $SCHOOL //查看时已无结果
步骤二:使用环境变量
1)查看环境变量相关文件
全局文件为/etc/profile,对所有用户有效;用户文件为~/.bash_profile,仅对指定的用户有效。
查看/etc/profile文件内容:
[root@svr5 ~]# cat /etc/profile .. .. if [ -x /usr/bin/id ]; then USER="`id -un`" LOGNAME=$USER MAIL="/var/spool/mail/$USER" fi HOSTNAME=`/bin/hostname` HISTSIZE=1000 .. .. export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC .. ..
2)使用环境变量
当前用户的环境变量USER记录了用户名、LOGNAME记录了登录名、HOME记录了宿主目录、SHELL记录了登录Shell、HOSTNAME记录主机名、TERM记录终端类型:
[root@svr5 ~]# echo $USER $LOGNAME $HOME $SHELL root root /root /bin/bash [root@svr5 ~]# echo $HOSTNAME svr5.tarena.com [root@svr5 ~]# echo $TERM xterm
环境变量PS1表示Shell环境的一级提示符,即命令行提示符(\u 用户名、\h 主机名、\W 工作目录、\$ 权限标识):
[root@svr5 src]# echo $PS1 //查看默认的一级提示 [\u@\h \W]\$ [root@svr5 src]#PS1='bash-3.2\$' //修改一级提示 bash-3.2# //更改结果 bash-3.2#PS1='[\u@\h \W]\$ ' //恢复原有设置 [root@svr5 src]#
环境变量PS2表示二级提示符,出现在强制换行、at任务编辑等场合:
[root@svr5 ~]# echo $PS2 //查看默认的二级提示 > [root@svr5 src]# cd \ //强制换行,观察提示符效果 > /root/ [root@svr5 ~]# PS2='=> ' //手动修改二级提示 [root@svr5 ~]# cd \ //再次验证提示符效果 => ~ [root@svr5 ~]# PS2='> ' //恢复原有设置
3)查看系统变量
使用env可查看所有环境变量:
[root@svr5 src]# env HOSTNAME=svr5.tarena.com TERM=xterm SHELL=/bin/bash HISTSIZE=1000 SSH_CLIENT=192.168.4.110 59026 22 OLDPWD=/root SSH_TTY=/dev/pts/0 USER=root .. ..
使用set可查看所有变量(包括env能看到的环境变量):
[root@svr5 src]# set BASH=/bin/bash BASH_ARGC=() BASH_ARGV=() BASH_LINENO=() .. ..
步骤三:使用位置变量与预定义变量
1)创建一个测试脚本,用来展示。
[root@svr5 ~]# vim location.sh #!/bin/bash echo $0 //脚本的名称 echo $1 //第一个参数 echo $2 //第二个参数 echo $* //所有参数 echo $# //所有的综合 echo $$ //当前进程的进程号 echo $? //上一个程序的返回状态码 [root@svr5 ~]# chmod +x location.sh //添加可执行权限
2)执行脚本location.sh,测试结果。
[root@svr5 ~]# ./location.sh one 1 2 abc qq 8 7
步骤四:创建账户与修改密码的脚本
1)编写脚本。
[root@svr5 ~]# vim /root/user.sh #!/bin/bash useradd $1 echo "$2" |passwd --stdin $1
执行脚本测试:
[root@svr5 ~]# ./user.sh jerry 123456 更改用户 jerry 的密码 。 passwd: 所有的身份验证令牌已经成功更新。
本案例要求进一步熟悉Shell变量的赋值控制,主要练习或验证下列内容:
实现此案例需要按照如下步骤进行。
步骤一:三种引号对变量赋值的影响
1)双引号的应用
使用双引号可以界定一个完整字符串。
[root@svr5 ~]# SCHOOL=Tarena IT Group -bash: IT: command not found //未界定时赋值失败 [root@svr5 ~]# SCHOOL="Tarena IT Group" //界定后成功 [root@svr5 ~]# touch aa bb //创建了两个文件 [root@svr5 ~]# touch "aa bb" //创建了一个文件 [root@svr5 ~]# ll //查看结果
2)单引号的应用
界定一个完整的字符串,并且可以实现屏蔽特殊符号的功能。
[root@svr5 ~]# NOTE='当前的用户是:$USER' [root@svr5 ~]# echo $NOTE 当前的用户是:$USER //单引号内的 $ 被视为普通字符
3)反撇号或$()的应用
使用反撇号或$()时,可以将命令执行的标准输出作为字符串存储,因此称为命令替换。
[root@svr5 ~]# tar -czf log-`date +%Y%m%d`.tar.gz /var/log
步骤二:使用read命令从键盘读取变量值
1)read基本用法
执行后从会等待并接受用户输入(无任何提示的情况),并赋值给变量str:
[root@svr5 ~]# read str What's happen ? //随便输入一些文字,按Enter键提交 [root@svr5 ~]# echo $str //查看赋值结果 What's happen ?
为了不至于使用户不知所措、莫名其妙,推荐的做法是结合-p选项给出友好提示:
[root@svr5 ~]# read -p "请输入一个整数:" i 请输入一个整数:240 [root@svr5 ~]# echo $i 240
2)stty终端显示控制
将回显功能关闭(stty -echo),
将回显功能恢复(stty echo)。
可参考下列操作创建一个测试脚本:
[root@svr5 ~]# vim sttyecho.sh //创建一个测试脚本 #!/bin/bash read -p "localhost login: " USERNAME //读取用户名 stty -echo //关闭回显 read -p "Password: " PASSWORD //读取密码 stty echo //恢复回显 echo "" //恢复回显后补一个空行 echo "Your login name is: $USERNAME" //确认赋值结果 echo "Your password is: $PASSWORD" //确认赋值结果 [root@svr5 ~]# chmod +x sttyecho.sh //添加执行权限
执行测试脚本sttyecho.sh,验证效果:
[root@svr5 ~]# ./sttyecho.sh localhost login: root //输入root,回车 Password: //输入1234567(不会显示),回车 Your login name is: root //脚本反馈结果 Your password is: 1234567
步骤三:使用export发布全局变量
默认情况下,自定义的变量为局部变量,只在当前Shell环境中有效,而在子Shell环境中无法直接使用。比如已定义的SCHOOL变量,当进入到sh或bash子Shell后,变量SCHOOL将处于未定义的状态:
[root@svr5 ~]# echo $SCHOOL Tarena IT Group [root@svr5 ~]# sh //开启一个sh子进程 sh-3.2# echo $SCHOOL //查看SCHOOL变量值无结果 sh-3.2# exit //返回原有Shell环境 exit [root@svr5 ~]# bash //开启bash子进程 [root@svr5 ~]# echo $SCHOOL //查看SCHOOL变量值无结果 [root@svr5 ~]# exit //返回原有Shell环境 exit [root@svr5 ~]#
若希望定义的变量能被子进程使用,可以使用export命令将其发布为全局变量。使用export发布时,只需指定变量名(可以有多个)即可,也可以通过export命令直接设置新的全局变量:
[root@svr5 ~]# export SCHOOL //发布已定义的变量 [root@svr5 ~]# export XX="1234" //发布新变量 [root@svr5 ~]# NSD="Network&System Direction" [root@svr5 ~]# export NSD YY="5678" //混合式发布
验证刚刚发布的全局变量:
[root@svr5 ~]# sh //进入sh子Shell环境 sh-3.2# echo $SCHOOL //查看全局变量的值 .. .. Tarena IT Group sh-3.2# echo $NSD Network&System Direction sh-3.2# echo $XX $YY 1234 5678 sh-3.2# exit //返回原有Shell环境 exit [root@svr5 ~]#
若要取消全局变量的全局属性,可结合export命令的 -n 选项;若要取消变量,则应使用unset命令。比如,以下操作可将前面发布的SCHOOL、XX恢复成局部变量:
[root@svr5 ~]# export -n SCHOOL XX //取消全局变量属性 [root@svr5 ~]# echo $SCHOOL $XX //局部变量SCHOOL、XX仍可用 Tarena IT Group 1234 [root@svr5 ~]# sh sh-3.2# echo $SCHOOL $XX //全局变量SCHOOL、XX已不可用 sh-3.2# exit //返回原有Shell环境 exit [root@svr5 ~]#