By
anjia
更新日期:
Linux 下有很多不同的 shell,但我们通常使用 bash (bourne again shell) 进行 shell 编程,因为 bash 是免费的,且易用。下面用到的例子,都是用 bash。
程序的第一行必须是 #!/bin/sh
如果要执行脚本,就必须使其具有执行权限。
执行
1 2 3 4 5
| sh demo.sh ./demo.sh
|
准备
关于替换
关于替换(or扩展),举例说明,eg. echo *.jpg
不带引号,是命令;
带了引号,会当作字符串(可以使用转义字符-反斜杠,来防止通配符的扩展)
其中:
单引号:会防止任何变量扩展,即就是纯字符串
双引号:可以防止通配符扩展,但允许变量扩展。即里面可以携带变量
在双引号里,也可以使用{}来告诉我们要打印的是个变量
Unix 命令
常见命令
1 2 3 4
| ls find cd ../ cd directory
|
1 2 3 4 5
| echo 'hello word' cat file.txt head file tail file
|
1 2 3 4 5 6
| rm file cp sourcefile destfile mv oldname newname mkdir foldername rmdir foldername
|
1 2 3 4 5 6 7
| awk grep 'pattern' file sort file.txt uniq read var wc –l filewc -w filewc -c file
|
其他:
Here Documents
在 bash 中使用多行注释的方法 Here Documents
其中,InputComesFromHERE 是自定义字符串,运算符
<< 内部内容必须顶格
<<- 内部内容可以有缩进
1 2 3 4 5
| command <<InputComesFromHERE ... ... ... InputComesFromHERE
|
1 2 3 4 5
| command <<-InputComesFromHERE ... ... ... InputComesFromHERE
|
:是空命令,结合 here Documents,那么以下是多行注释
1 2 3
| :<<Multi-Comment 听说这里可以写成多行注释,试试喽 Multi-Comment
|
参考:
http://tldp.org/LDP/abs/html/here-docs.html
http://blog.csdn.net/delphiwcdj/article/details/8088407
控制语句
条件测试
[ ] 来表示条件测试,注意方括号和中间的内容之间必须有空格
1 2 3 4
| [ -n "$var" ] [ "$a" = "$b" ] [ -f "somefile" ] [ -x "/bin/ls" ]
|
更多条件测试,可参考 shell中条件判断if中的-a到-z的意思
if-else
1 2 3 4 5
| if [ xxx ]; then ... else ... fi
|
case-in
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ftype=`file "$1"` echo $ftype case "$ftype" in "$1: Zip archive"*) unzip "$1";; "$1: gzip compressed"*) gunzip "$1";; "$1: bzip2 compressed"*) bunzip2 "$1";; esac
|
循环
for-in
1 2 3
| for var in A B C; do echo "var is $var" done
|
while
1 2 3 4
| while true do sh /Users/anjia/GitHub/shell/crontab.sh sleep 5 done
|
选择
可与用户交互的 select
1 2 3 4 5
| #!/bin/sh select var in "Linux" "Gnu Hurd" "Free BSD" "Other"; do break done echo "You have select $var"
|
执行结果
demo
下面用实例来感受下 shell 脚本。在看 demo 之前,先了解下几个有特殊含义的参数:
- $* 所有输入的命令行参数值
- $1-$9 命令行的第1个参数、…、第9个参数
- $# 命令行参数的总个数
grep
grep:在文件内搜索字符串
wc:计算文件行数|文件单词个数
>>:文件追加
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #!/bin/sh echo 'welcome to shell!' grep 'anjia' filename1.txt grep 'anjia' filename1.txt | wc -l grep 'anjia' filename1.txt | wc -l >> filename2.txt if [ -f 'filename2.txt' ];then echo 'filename2.txt is a file.' else echo 'filename2.txt is not a file.' fi exit 1
|
运行结果:
sed
sed:基本的查找替换程序。从标准输入(eg命令管道)读入文本,并将结果输出到标准输出(屏幕)。此命令采用正则表达式进行搜索。
>:文件重写覆盖
文件重命名
本例子是对多个文件进行重命名的。其中:
第一个参数:oldname
第二个参数:newname
之后的参数:将要替换的文件列表
直接看源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| #!/bin/sh if [ $# -lt 3 ]; then cat <<-HELP ren -- renames a number of files using sed regular expressions USAGE: ren 'regexp' 'replacement' files... EXAMPLE: rename all *.HTM files in *.html: ren 'HTM$' 'html' *.HTM HELP exit 0 fi OLD="$1" NEW="$2" shift shift for file in $*; do if [ -f "$file" ]; then newfile=`echo "$file"|sed "s/${OLD}/${NEW}/g"` if [ -f "$newfile" ]; then echo "ERROR: $newfile exists already" else echo "renaming $file to $newfile ..." mv "$file" "$newfile" fi fi done exit 1
|
运行结果:
日志重命令
本实是给日志文件列表再插入一个最新的日志,从头插。比如:有如下文件
log.txt.1 log.txt.2 log.txt.3
现在又产生了一个最新的日志 log.txt,我们要将其变成 log.txt.1,原有的 log.txt.1变成 log.txt.2,log.txt.2 变成 log.txt.3,依次类推。
直接看源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| #!/bin/sh ver="0.1" help(){ cat <<-HELP rotatefile -- rotate the file name USAGE: rotatefile [-h] filename OPTIONS: -h help text EXAMPLE: rotatefile out This will e.g rename out.2 to out.3,out1 to out.2 and create an empty out-file The max number is 10 version $ver HELP exit 0 } error(){ echo "$1" exit 0 } if [ -z "$1" ]; then error "ERROR: you must specify a file, use -h for help" fi filen="$1" echo $filen for n in 5 4 3 2 1; do if [ -f "$filen.$n" ]; then p=`expr $n + 1` echo "mv $filen.$n $filen.$p" mv $filen.$n $filen.$p fi done if [ -f "$filen" ]; then echo "mv $filen $filen.1" mv $filen $filen.1 fi echo touch $filen touch $filen exit 1
|
运行结果:
小结
在编写 shell 脚本时,最好…:
- 写注释
- 校验参数
- 支持帮助说明,即选项 -h 或者 -help
包括:功能说明、USAGE、OPTIONS、EXAMPLE
学新语言时,一个一个字符敲代码的感觉,很好。
参考
http://blog.chinaunix.net/uid-20328094-id-95121.html
shell
bash