- shell程序介绍
1.查看我们的Linux(centos6.5为例)有多少我们可以使用的shell:
[root@localhost bin]# cat /etc/shells /bin/sh /bin/bash /sbin/nologin /bin/dash /bin/tcsh /bin/csh
系统某些服务在运作过程中,会去检查使用者能够使用的shells,而这些shell的查询就是由/etc/shells这个档案。
2.当我们登入Linux系统的时候,系统就会给我一个shell来工作,而这个登录取得的shell就记录在/etc/passwd这个档案里:
[root@localhost bin]# cat /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin ...
3.shell的内部指令type,查看指令来自外部指令还是内建在bash当中。
[root@localhost bin]# man cd [root@localhost bin]# type cd cd is a shell builtin [root@localhost bin]# type -t cd builtin #表示该指令为bash内建的指令功能 [root@localhost bin]# type -a cd cd is a shell builtin [root@localhost bin]# type type type is a shell builtin
[root@localhost bin]# type it ls
alias #表示该指令为命名别名所设定的名称
[root@localhost bin]# type uname
uname is hashed (/bin/uname)
[root@localhost bin]# type -t uname
file #表示为外部指令
4.变量的取用 echo
[root@localhost bin]# echo $PATH /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin [root@localhost bin]# echo ${PATH} /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
变量的设定 = ,如果一个变量未设定,内容为空
[root@localhost bin]# echo $myname [root@localhost bin]# myname=tian [root@localhost bin]# echo $myname tian
子程序,就是在目前这个shell的情况下,去启用另一个新的shell,新的shell就是子程序。在一般状态下,父程序的自定义变量无法在子程序内使用,但是通过export将变量变成环境变量,就能在子程序下应用了。
[root@localhost bin]# echo $name yes [root@localhost bin]# bash #进入所谓的子程序 [root@localhost bin]# echo $name [root@localhost bin]# exit #离开子程序 exit [root@localhost bin]# export name [root@localhost bin]# bash [root@localhost bin]# echo $name yes [root@localhost bin]# exit
5.变量的设定规则:
6.环境变量
env,environment的简写,列出所有的环境变量
[root@localhost /]# env HOSTNAME=localhost.localdomain SHELL=/bin/bash TERM=xterm HISTSIZE=1000 USER=root ...
set,观察所有变量(包含环境变量和自定义变量)
[root@localhost /]# set BASH=/bin/bash BASH_VERSINFO=([0]="4" [1]="1" [2]="2" [3]="1" [4]="release" [5]="i386-redhat-linux-gnu") BASH_VERSION='4.1.2(1)-release' HISTFILE=/root/.bash_history HISTFILESIZE=1000 HISTSIZE=1000 HOSTTYPE=i386 OLDPWD=/ OSTYPE=linux-gnu PPID=5200 PS1='[u@h W]$ ' ...
PS1:提示字符的设定
[root@localhost php]# PS1='[u@h w]$' [root@localhost /usr/local/php]#ls
$变量,代表的是目前这个shell的线程代号,即PID(Process ID)
[root@localhost /]#echo $$ 2840
?变量:上一个执行的指令所回传的值,如果执行成功,则回传一个0值,否则,就会回传错误代码(一般为非0值)
[root@localhost scripts]# ls sh01.sh sh02-1.sh sh02.sh sh03.sh sh04.sh [root@localhost scripts]# echo $? 0
7.数据流重导向
数据流重导向可以将standard output与standard error output分别传送到其他档案或装置去,而分别传送所用的特殊字符则如下所示:
[tianxintian22@localhost ~]$ find /home -name .bashrc find: `/home/w002': Permission denied <==Standard error /home/tianxintian22/.bashrc <==Standard output find: `/home/w001': Permission denied <==Standard error
#将stdout与stderr分别存到不同的档案 [tianxintian22@localhost ~]$ find /home -name .bashrc > list_right 2> list_error [tianxintian22@localhost ~]$ ls Desktop Documents Downloads list_error list_right Music Pictures Public Templates Videos
#将错误数据丢弃,屏幕显示正确的数据
#/dev/null 垃圾桶黑暗装置,可以吃掉任何导向这个装置的信息 [tianxintian22@localhost ~]$ find /home -name .bashrc 2> /dev/null /home/tianxintian22/.bashrc
#将指令的数据全部写入list档案中 [tianxintian22@localhost ~]$ find /home -name .bashrc > list 2>&1 #[tianxintian22@localhost ~]$ find /home -name .bashrc &> list 这句等同于上一句
[tianxintian22@localhost ~]$ ls Desktop Documents Downloads list list_error list_right Music Pictures Public Templates Videos [tianxintian22@localhost ~]$ cat list find: `/home/w002': Permission denied /home/tianxintian22/.bashrc find: `/home/w001': Permission denied
- shell script
1.路径与指令搜寻顺序
2.script指令下达
以上方式下达脚本时,script都会使用一个新的bash环境来执行脚本内的指令,也就是说,script是在子程序的bash内执行的。
3.指令依序执行关系
#不清楚/tmp/abc是否存在,但是要建立/tmp/abc/hehe档案
[root@localhost ~]ls /tmp/abc || mkdir /tmp/abc && touch /tmp/abc/hehe
4.test指令的测试功能
[root@localhost scripts]# ls sh01.sh sh02-1.sh sh02.sh sh03.sh sh04.sh [root@localhost scripts]# test -e sh01.sh #该档名是否存在 [root@localhost scripts]# echo $? 0 [root@localhost scripts]# test -f sh01.sh #该档名是否存在且为档案(file) [root@localhost scripts]# echo $? 0 [root@localhost scripts]# test -d sh01.sh #该文件名是否存在且为目录 [root@localhost scripts]# echo $? 1 [root@localhost scripts]# test -d ~/scripts [root@localhost scripts]# echo $? 0
5.判断符号[ ]
编写脚本:sh01.sh
[root@localhost scripts]# vim sh01.sh #!/bin/bash #Program # This program shows the user's choice #History #2016/07/11 tianxintian22 first release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH read -p "Please input (Y/N)" choice [ "$choice" == 'Y' -o "$choice" == 'y' ] && echo "OK,continue" && exit 0 # -o 等价于或者(or) [ "$choice" == 'n' -o "$choice" == 'N' ] && echo "Oh,interrupt" && exit 0 echo "I don't know what your choice is" && exit 0
执行脚本:
[root@localhost scripts]# sh sh01.sh Please input (Y/N)Y OK,continue
6.shell script 默认变数($1,$2...)
[root@localhost scripts]# vim sh02.sh #!/bin/bash #program # program shows the script name, parameters... PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH echo "The script name is ==> $0" echo "Total parameter number is ==> $#" [ "$#" -lt 2 ] && echo "The number of parameter is less than 2.Stop here." && exit 0 echo "Your whole parameter is ==>'$@'" echo "The first parameter is ==>$1" echo "The second parameter is ==>$2" exit 0
执行脚本:
[root@localhost scripts]# ./sh02.sh The script name is ==> ./sh02.sh Total parameter number is ==> 0 The number of parameter is less than 2.Stop here. [root@localhost scripts]# ./sh07.sh one two The script name is ==> ./sh02.sh Total parameter number is ==> 2 Your whole parameter is ==>'one two' The first parameter is ==>one The second parameter is ==>two
7.条件判断式 if...then
[root@localhost scripts]# vim sh01-1.sh #!/bin/bash #Program # This program shows the user's choice PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH read -p "Please input (Y/N):" choice if [ "$choice" == 'Y' ] || [ "$choice" == 'y' ];then echo "OK,continue" elif [ "$choice" == 'n' ] || [ "$choice" == 'N' ];then echo "Oh,interrupt" else echo "I don't know what your choice is" fi
执行脚本:
[root@localhost scripts]# ./sh01-1.sh Please input (Y/N):n Oh,interrupt
8.case...esac 判断
[root@localhost scripts]# vim sh02.sh #!/bin/bash #program # Show "hello" from $1 by using case...esac #history PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH case $1 in
"hello") echo "Hello,how are you?" ;; "") echo "You must input parameter, ex> {$0 someword}" ;; *) echo "Usage $0 {hello}" ;; esac
执行脚本:
[root@localhost scripts]# ./sh02.sh hello Hello,how are you? [root@localhost scripts]# ./sh02.sh test Usage ./sh02.sh {hello} [root@localhost scripts]# ./sh02.sh You must input parameter, ex> {./sh02.sh someword}
9.function功能
[root@localhost scripts]# vim sh02-1.sh #!/bin/bash #program # use function to repeat information #history PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH function printit(){ echo -n "Your choice is " } echo "This program will print your selection!" case $1 in "one") printit;echo $1 | tr 'a-z' 'A-Z' ;; "two") printit;echo $1 | tr 'a-z' 'A-Z' ;; "three") printit;echo $1 | tr 'a-z' 'A-Z' ;; *) echo "Usage $0 {one|two|three}" ;; esac
执行脚本:
[root@localhost scripts]# ./sh02-1.sh This program will print your selection! Usage ./sh02-1.sh {one|two|three} [root@localhost scripts]# ./sh02-1.sh one This program will print your selection! Your choice is ONE
shell script 的执行方式是由上而下,由左而右,因此在shell script当中的设定一定要写在程序的最前面!
[root@localhost scripts]# vim sh02-2.sh #!/bin/bash #program # use function to repeat information #history PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH function printit(){ echo "Your choice is $1" } echo "This program will print your selection!" case $1 in "one") printit 1 ;; "two") printit 2 ;; "three") printit 3 ;; *) echo "Usage $0 {one|two|three}" ;; esac
执行脚本:
[root@localhost scripts]# ./sh02-2.sh This program will print your selection! Usage ./sh02-2.sh {one|two|three} [root@localhost scripts]# ./sh02-2.sh one This program will print your selection! Your choice is 1
10.while do done;until do done
#当condition条件满足时,就进行循环
while [ condition ] do 程序语句 done
#当condition条件成立时,终止循环 until [ condition ] do 程序语句 done
计算1+2+3+4+...+100:
#!/bin/bash #program calculate '1+2+3+4+...+100' #history ... sum=0 i=0 while [ "$i" != '100' ] do i=$(($i+1)) sum=$(($sum+$i)) done echo "1+2+3+...+100="$sum
#!/bin/bash #program calculate '1+2+3+4+...+100' #history sum=0 i=0 until [ "$i" == '100' ] do i=$(($i+1)) sum=$(($sum+$i)) done echo "1+2+3+...+100="$sum
11.for do done(固定循环)
for var in con1 con2 con3 ... do 程序段 done
$var 的变量内容在循环时:第一次循环时,$var的内容为con1;第二次循环时,$var的内容为con2;第三次循环时,$var内容为con3;...
eg1:
#!/bin/bash #program # using for ... loop to print 3 animals #history PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH for animal in dog cat elephant do echo "There are ${animal}s..." done
执行脚本:
[root@localhost scripts]# sh sh04.sh There are dogs... There are cats... There are elephants...
eg2:
#!/bin/bash users=$(cut -d ':' -f 1 /etc/passwd) for user in $users do id $user done
执行脚本:
[root@localhost scripts]# sh sh05.sh uid=0(root) gid=0(root) groups=0(root) uid=1(bin) gid=1(bin) groups=1(bin),2(daemon),3(sys) uid=2(daemon) gid=2(daemon) groups=2(daemon),1(bin),4(adm),7(lp) uid=3(adm) gid=4(adm) groups=4(adm)
...
12.for...do...done
for((初始值;限制值;执行步阶)) do 程序段 done
[root@localhost scripts]# cat sh06.sh #!/bin/bash #program # try do calculate 1+2+3+...+${your_input} #history read -p "input a number:" number sum=0 for((i=1;i<=number;i++)) do sum=$(($sum+$i)) done echo "1+2+3+...+$number="$sum
执行脚本:
[root@localhost scripts]# sh sh06.sh input a number:100 1+2+3+...+100=5050
13.debug
[root@localhost scripts]# sh -n sh06.sh #如果语法没有问题,则不会显示任何信息 [root@localhost scripts]# sh -v sh06.sh #执行脚本前,现将脚本内容输出到屏幕上 #!/bin/bash #program # try do calculate 1+2+3+...+${your_input} #history read -p "input a number:" number input a number:5 sum=0 for((i=1;i<=number;i++)) do sum=$(($sum+$i)) done echo "1+2+3+...+$number="$sum 1+2+3+...+5=15 [root@localhost scripts]# sh -x sh06.sh #将使用到的script内容显示到屏幕上 + read -p 'input a number:' number input a number:5 + sum=0 + (( i=1 )) + (( i<=number )) + sum=1 + (( i++ )) + (( i<=number )) + sum=3 + (( i++ )) + (( i<=number )) + sum=6 + (( i++ )) + (( i<=number )) + sum=10 + (( i++ )) + (( i<=number )) + sum=15 + (( i++ )) + (( i<=number )) + echo 1+2+3+...+5=15 1+2+3+...+5=15