Shell编程

Shell接受用户或应用层命令,并将命令解释给底层的系统内核,由内核完成相应的工作,并将结果返回给用户或者应用层。
Shell命令的基本格式为command -options [argument]:
$ ls -l /home    #查看当前目录下的文件

1、程序必须以下面的行开始,而且必须放在第一行:
#!/bin/sh
此行称为shebang,就是sharp(#)+bang(!)的意思,#!告诉系统它后面的参数是用来执行该文件的程序,例如用/bin/bash来执行文件。如果使用#!/bin/sh,这表示用任何支持 POSIX shell 语言的sh执行程序。

2、一般会用export关键字去处理过环境变量,这仅仅在登录期间有效,会影响常用命令例如:echo、ls、cd、pwd、cp、mv、rm、grep、read、sort、find、sed等。

3、shell编程中所有的变量都由字符串组成,不需要事先声明,但是要注意等号左右不能存在空格,取用变量的值在变量名前加$即可:
a=”hello world” #对变量赋值
echo $a  #hello world
有时候需要使用花括号,但是要注意两端不可留空格
num=2
echo “this is the ${num}nd” #this is the 2nd
此时如果不用花括号的话shell将会去搜索一个叫numnd的变量。
Shell的变量默认的都是字符串类型。
var=1
var=$var+1
echo $var #1+1
为了避免这个问题有很多方法,常用的是C风格表达式,在bash里面用 (( )) 执行C风格的算术表达式:
var=0
(( var += 1 )) # 这是一种,现在var=1
(( var++ ))    # 这也是自增,var=2
(( var = var * var )) # 乘法了,var=4
$(( ))会展开成为这个C表达式所求的值的结果:
echo $((var += 2))    # var=3。
var=$((var-1))        # var=2

4、几个符号
管道(|) 将一个命令的输出作为另外一个命令的输入:
$ grep “hello” file.txt | wc -l
重定向将命令的结果输出到文件,而不是标准输出(屏幕):
>写入文件并覆盖旧文件,>>加到文件的尾部,保留旧文件内容。
反短斜线(backtick=`)可以将一个命令的输出作为另外一个命令的一个命令行参数:
例如用来查找过去24小时内修改过的文件是这样:
$ find . -mtime -1 -type f -print
那么下面就可以把所有查找到的文件打成一个包:
tar -zcvf lastmodified.tar.gz `find . -mtime -1 -type f -print`
引号(单引号和双引号)可以防止通配符扩展在向程序传递任何参数之前扩展通配符和变量:
所谓扩展的意思是程序会把通配符比如*替换成合适的文件名,为了防止程序作这种替换,可以使引号
echo “*.jpg”
echo ‘*.jpg’
都将打印”*.jpg”
单引号更严格一些。它可以防止任何变量扩展。双引号可以防止通配符扩展但允许变量扩展。

5、流程控制
if …; then …
elif …; then …
else …
fi
注意是elif而不是elseif。
通常用[ ]表示条件的测试,注意要确保内中两边的空格很重要,基本的比较关系有:
-eq —比较两个参数是否相等(例如,if [ 2 –eq 5 ])
-ne —比较两个参数是否不相等
-lt —参数1是否小于参数2
-le —参数1是否小于等于参数2
-gt —参数1是否大于参数2
-ge —参数1是否大于等于参数2
-f — 检查某文件是否存在(例如,if [ -f “filename” ])
-d — 检查目录是否存在
[ -f “somefile” ] :判断是否是一个文件
[ -x “/bin/ls” ] :判断/bin/ls是否存在并有可执行权限
[ -n “$var” ] :判断$var变量是否有值
[ “$a” = “$b” ] :判断$a和$b是否相等
快捷操作符也是一种判断:
[ -f “/etc/shadow” ] && echo “This computer uses shadow passwors”
这里&&就是一个快捷操作符,如果左边的表达式为真则执行右边的语句,也可以认为是逻辑运算中的与操作。同样或操作(||)在shell编程中也是可用的。

6、case表达式可以用来匹配一个给定的字符串,而不是数字。
case … in
…) do something here ;
esac
经典例子是这点写一个smartzip脚本,可以自动解压bzip2, gzip和zip 类型的压缩文件:
#!/bin/sh
ftype=`file “$1″`
case “$ftype” in
“$1: Zip archive”*)
unzip “$1”;;
“$1: gzip compressed”*)
gunzip “$1” ;;
“$1: bzip2 compressed”*)
bunzip2 “$1” ;;
*) echo “File $1 can not be uncompressed with smartzip”;;
esac

7、上面使用了一个特殊的变量$1,该变量包含了传递给该程序的第一个参数值,对于:
$ smartzip articles.zip
$1 就是字符串articles.zip
还有一个特殊的变量$*包含了所有输入的命令行参数值,对于:
$ yoursh pmopenssh.rpm w3m.rpm webgrep.rpm
此时$* 包含了3 个字符串,即openssh.rpm, w3m.rpm and webgrep.rpm.
这些特殊变量包含了用户从命令行输入的参数,但是更复杂的程序可能需要更多的自定义的选项,通常的惯例是在所有可选的参数之前都加一个减号,在这后面再给出参数值比如文件名。有好多方法可以实现对输入参数的分析,但是下面的使用case表达式的例子是个不错的方法。
#!/bin/sh
help()
{
cat <
This is a generic command line parser demo.
USAGE EXAMPLE: cmdparser -l hello -f — -somefile1 somefile2
HELP
exit 0
}

while [ -n “$1” ]; do
case $1 in
-h) help;shift 1;; # function help is called
-f) opt_f=1;shift 1;; # variable opt_f is set
-l) opt_l=$2;shift 2;; # -l takes an argument -> shift by 2
–) shift;break;; # end of options
-*) echo “error: no such option $1. -h for help”;exit 1;;
*) break;;
esac
done

echo “opt_f is $opt_f”
echo “opt_l is $opt_l”
echo “first arg is $1”
echo “2nd arg is $2”

8、select 表达式是一种bash的扩展应用,尤其擅长于交互式使用。用户可以从一组不同的值中进行选择。
selectvar in …  do
break
done
例如:
#!/bin/sh
echo “What is your favourite OS?”
select var in “Linux” “Gnu Hurd” “Free BSD” “Other”; do
break
done
echo “You have selected $var”
运行的结果:
What is your favourite OS?
1) Linux
2) Gnu Hurd
3) Free BSD
4) Other
#? 1
You have selected Linux

0 回复

发表评论

Want to join the discussion?
Feel free to contribute!

发表评论