1. shell
的分类:
1>. Bourne Shell:标识为sh
,该Shell由Steve Bourne在贝尔实验室时编写。在许多Unix系统中,该Shell是root用户的默认的Shell。
2>. Bourne-Again Shell:标识为bash,该Shell由Brian Fox在1987年编写,是绝大多数localhost发行 版的默认的Shell。
3>. Korn Shell:标识为ksh,该Shell由贝尔实验室的David Korn在二十世纪八十年代早期编写。它完 全向上兼容 Bourne Shell 并包含了C Shell 的很多特性。
4>. C Shell:标识为csh,该Shell由Bill Joy在BSD系统上开发。由于其语法类似于C语言,因此称为C Shell。
查看当前系统支持的shell:[root@localhost ~] # cat /etc/shells/bin/sh/bin/bash/sbin/nologin/usr/bin/sh/usr/bin/bash/usr/sbin/nologin
查看当前系统默认 shell:[root@localhost ~] # echo $SHELL/bin/bash
2. shell
脚本的基本元素:
对于一个基本的Shell
程序来说,应该拥有以下基本元素:
1>. 声明:声明用哪个命令解释器来解释并执行当前脚本文件中的语句,一般写的解释器为 " #!/bin/bash "。
2>. 命令:可执行语句,实现程序的功能。
3>. 注释:说明某些代码的功能,通过在代码中增加注释可以提高程序的可读性。
(1). 单行注释: # 开头的一整行都是注释,例如:#comment1#comment2#comment3……
(2). 多行注释,使用冒号 “:” 配合 here document 可实现多行注释,例如::<<BLOCK…… 注释内容BLOCK
4>. 赋予rx
的权限。
3. shell
脚本编写规范:
(1
)脚本文件名应见名知意,例如backup_mysql.sh。
(2)文件开头指定脚本解释器 #!/bin/sh 或 #!/bin/bash。
(3)开头加版本特权等信息。
# Date: 创建日期# Author: 作者# Mail: 联系方式# Function: 功能# Version: 版本
(4)脚本中尽量不要用中文注释。
(5)多使用内部命令常用的内部命令有:echo、eval、exec、export、read、shift、exit。
· echo可在屏幕上输出信息
echo参数选项: |
说明
|
-n
|
不换行输出内容
|
-e
|
解析转义字符
|
转义字符
|
说明
|
\n
|
换行
|
\r
|
回车
|
\t
|
制表符
|
\b
|
退格
|
\v
|
纵向制表符
|
示例:[root@localhost ~] # echo -n i have a cati have a cat [root@localhost ~] #[root@localhost ~] # echo i\thave\ta\tcatithavetatcat[root@localhost ~] # echo -e i\thave\ta\tcatithavetatcat[root@localhost ~] # echo -e "i\thave\ta\tcat"i have a cat
· eval命令:
命令格式:eval args
功能:当shell程序执行到eval语句时,shell读入参数args,并将它们组合成一个新的命令,然后执行。
[root@localhost test] # a='shuju;head -1 /etc/passwd'[root@localhost test] # echo $ashuju;head -1 /etc/passwd[root@localhost test] # eval echo $ashujuroot:x:0:0:root:/root:/bin/bash
· exec命令能够在不创建新的子进程的前提下,转去执行指定的命令,当指定的命令执行完毕后,该进程就终止了。
· export设置或者显示环境变量。
· read命令可从标准输入读取字符串等信息,传给shell
程序内部定义的变量。
echo参数选项: | 说明 |
-p prompt | 设置提示信息 |
-t timeout | 设置输入等待时间,单位默认为秒 |
[root@localhost test] # read -t 10 -p "please input your name:" nameplease input your name:xiaoming[root@localhost test] # echo $namexiaoming[root@localhost test] # echo -n "please input your name:";read name1 name2# 读取两个输入(以空格隔开),分别赋值给 name1 和 name2变量please input your name:xiaoming xiaohong[root@localhost test] # echo $name1xiaoming[root@localhost test] # echo $name2xiaohong
· shift,在程序中每使用一次shift
语句,都会使所有的位置参数依次向左移动一个位置,并使位置参数$#减1,直到减到0为止。
· exit,退出shell程序。在exit之后可以有选择地指定一个数作为返回状态。
注意:快速如何快速生成脚本开头的版本版权注释信息:
[root@localhost ~] # vim ~/.vimrcautocmd BufNewFile *.py,*.cc,*.sh,*.java exec ":call SetTitle()"func SetTitle()if expand( "%:e" ) == 'sh'call setline(1, "#!/bin/bash" )call setline(2, "#########################" )call setline(3, "#File name:" .expand( "%" ))call setline(4, "#Version:v1.0" )call setline(5, "#Email:admin@test.com" )call setline(6, "#Created time:" .strftime( "%F %T" ))call setline(7, "#Description:" )call setline(8, "#########################" )call setline(9, "" )endifendfunc
4. shell
脚本的执行方式:
(1
)交互式执行:
[root@localhost ~] # for filename in `ls /etc`> do> if echo " $filename " | grep "passwd"> then> echo " $filename "> fi> done
(2
)作为程序文件执行:对于一组需要经常重复执行的Shell语句来说,将它们保存在一个文件中来执行。我们通常称这种包含多个Shell语句的文件为Shell脚本,或者Shell脚本文件。脚本文件是普通的文本文件,可使用任何的文本编辑器查看或修改Shell脚本。
[root@localhost ~] # mkdir /test[root@localhost ~] # cd /test[root@localhost test] # vim test1.sh#!/bin/bashfor filename in `ls /etc`doif echo " $filename " | grep "passwd"thenecho " $filename "fidone
5.
执行脚本的方法:
(1)bash ./filename.sh(产生子进程,再运行,使用当前指定的bash shell去运行)。
(2)./filename.sh(产生子进程,再运行,使用脚本里面指定的shell去运行。使用该种方式执行需要x 权限)。
(3)source ./filename.sh(source命令是一个shell内部命令,其功能是读取指定的shell程序文件,并且依次执行其中的所有的语句,并没有创建新的子shell进程,所以脚本里面所有创建的变量都会保存到当前的shell里面)。
(4). filename.sh(和source一样,也是使用当前进程执行)。
示例一:
[root@localhost test] # vim test2.sh#!/bin/bashcd /tmppwd[root@localhost test] # ls -l test2.sh-rw-r--r-- . 1 root root 24 Apr 30 20 :09 test2.sh(1)[root@localhost test] # bash test2.sh/tmp(2)[root@localhost test] # ./test2.sh-bash : ./test2.sh: Permission denied[root@localhost test] # chmod a+rx test2.sh[root@localhost test] # ./test2.sh/tmp(3)[root@localhost test] # source test2.sh/tmp[root@localhost tmp] #(4)[root@localhost test] # . test2.sh/tmp[root@localhost tmp] #注意:执行shell脚本时,如果使用1和2这种方式执行会在当前的进程下产生一个新的bash子进程,所以子进程切换到了/tmp目录,当脚本结束,子进程也就结束了,所以当前进程的目录不会发生变化;3和4方式执 行时,不会产生新的进程,所以脚本执行结束后当前的目录会变成/tmp。
示例二:
[root@localhost test] # echo 'userdir=`pwd`' > test3.sh[root@localhost test] # cat test3.shuserdir = `pwd`(1)[root@localhost test] # bash test3.sh[root@localhost test] # echo $userdir[root@localhost test] #(2)[root@localhost test] # chmod a+rx test3.sh[root@localhost test] # ./test3.sh[root@localhost test] # echo $userdir[root@localhost test] #(3)[root@localhost test] # source test3.sh[root@localhost test] # echo $userdir/test(4)[root@localhost test] # . test3.sh[root@localhost test] # echo $userdir/test
6. shell
脚本的退出状态:
在UNIX或者Linux
中,每个命令都会返回一个退出状态码。退出状态码是一个整数,其有效范围为0~255。通常情况下,成功的命令返回0,而不成功的命令返回非0值。非0值通常都被解释成一个错误 码。行为良好的UNIX命令,程序和工具都会返回0作为退出码来表示成功。 Shell脚本中的函数和脚本本身也会返回退出状态码。在脚本或者是脚本函数中执行的最后的命令会决定退出状态码。另外,用户也可以在脚本中使用exit语句将指定的退出状态码传递给Shell。