shell script 是利用shell 的功能缩写的一个程序,这个程序使用纯文本文档,将一些shell的指令(含外部指令)和语法写在里面,搭配正则表达式,管线命令,数据流重定向等功能,达到我们想要的目的 拥有比较不错的除错工具(debgu)
作用:
a) 自动化管理重要的数据
b) 追踪与管理系统的重要工作
c) 简单入侵检测功能
d) 简单的数据处理
e) 跨平台,在windows下边也有类似的仿真器
1. 当读取到一个回车符 ( CR ) 就开始执行 该行( 该串) 命令 , 如果一行内容太多可以使用 \ 来延伸到下一行, # 作为注释使用 ,. 编辑的时候
注意事项: a. 指令的执行是从上到下, 从左到右的分析与执行的.
b. 空白行也将被忽略掉, 并且 [tab] 按键所推开的空白同样视为空格键盘
c. 如果读取到一个 Enter 符号 ( CR ) , 就尝试开始执行该行( 或该串) 命令
d. 如果一行内容太多, 则可以使用[ \ [ Enter ] ] 来延伸到下一行
e. #可作为批注 ! 任何加在#后面的资料将全部被视为批注文字而被忽略.
2. 执行命令
a. 直接下达命令 : ( 档案必须具备 rx 权限 )
绝对路径 : /home/domtsai/shell.sh 下达命令
相对路径 : ./shell.sh
变量 : 将 shell.sh 放在 PATH 指定的目录内, ( 在任何目录下都可以执行 )
b. 以bash程序来执行 , 透过 bash shell.sh 或 sh shell.sh来执行 ( 这种必须在工作目录下, 或者已经将 shell.sh 添加到 PATH中 )
3. #!/bin/bash 宣告 script 使用的 shell 名称 : 因为我们使用的是 bash, 宣告之后, 能够加载bash相关环境配置
4. #备注的内容 script : 内容与功能, 版本信息, 作者与联系方式, 建档日期, 历史记录
5. 环境变量提前设定完成 ( 设定完成以后就可以直接使用, 不需要指定路径, 直接执行命令 ) ( 在程序中将需要用到的PATH,LANG设定好)
6. 主要程序部分
7. exit 定义回传信息 ( 类似 java 程序中的 printf )
程序例子 :
#!/bin/bash ( 宣告, 并非注释, 注意符号 ! , 没有这个符号就成了注释了 )
# program :
# This program for helloworld !
# History :
# 2012/04/06 moveofgod First release --> 注释
PATH=/bin;/sbin;usr/sbin;/usr/local/bin;usr/local/sbin;~/bin
export PATH
echo -e "Hello World ! \a \n " -->主程序部分
exit 0 --> 回传信息
8. 可以使用 vim进行编辑程序
如写程序一样,shell script 文档头文件也要有类似说明
简单范例
- 交互式脚本 : read -p "请输入内容" comment
- 随日期变化 : 利用date命令建立类似以日期为文件名称.
- 数值计算 : 必须先用 declare声明一下
执行脚本
如果是使用直接执行, 或者是 bash / sh 执行脚本时, 这种方式会创建一个子 bash 来执行脚本, 所以脚本中的变量并不会影响到父bash
如果使用 . 或者 source 执行, 在父bash中直接执行( 有可能会影响父 bash 的环境变量 )
测试指令 判断
test -e /dmtsai ( 查看 /dmtsai目录是否存在, 注意不会将内容显示出来, 所以要配合使用)
test -e /dmtsai && echo "exist" || echo "Not exist" ( -f 是否为档案 , -d 是否为目录, -e 是否存在 )
test
-e 该档名是否存在?
-f 该档名是否存在且为档案?
-d 该文件名是否存在且为目录?
-L 是否为连结档
测试档案权限
-r 测试是否可读
-w 是否可写
-x 是否可执行
-u 是否存在 SUID 属性
-g 是否存在 SGID 属性
-s 侦测档名是否存在且为 非空白档案
两个档案之间的比较 test file1 -nt file2
-nt 判断 file1 是否比 file2 新
-ot 判断 file1 是否比 file2 旧
-ef 判断是否为同一个档案,可用在判断 hard link 上
两个整数之间的判断
test n1 -eq n2
-eq 想等
-ne 不等
-gt n1 > n2
-lt n1 < n2
-ge n1 >= n2
-le n1 <= n2
判断字符串
test -z string 判断字符串是否为空,为空返回 true
test -n string 判断字符串是否为非0, 若为空串 false, ( n 可以省略 )
-test str1 = str2 ( 判断 str1 是否等于 str2 )
test str1 != str2 ( 不等,返回 true )
多重条件判断 test -r filename -a -x filename
-a ( and , 同时具有相同权限,返回 true )
-o ( or , 任何一个成立, 返回 true )
! ( 反相, 如 test ! -x file , 当 file 不具有 x 时, 回传 true )
[ ] 也是判断符号,
[ ] 中括号, 例如 [ -z"HOME" ] && echo $HOME || echo "NO" ( 在中括号内的每个组件都需要有空格键来分隔 ; 在中括号内的变数, 最好都以双引号括起来 ; 在中括号内的常数, 最好都以单或双引号括起来 ) , 中括号的使用方法与 test 几乎一模一样 . [ "$HOME" = "$MAILE" ]
[ "$yn" == "y" -o "yn" == "n" ] && echo "ok,continue" && exit 0
带参数 执行脚本
/path/to/scriptname opt1 opt2 opt3 opt4
$0 $1 $2 $3 $4
执行的脚本名为 $0这个变量,第一个参数是 $1,
$# : 代表后接的参数个数 ,以上为 4
$@ : 代表 “$1” “$2” “$3” “$4”
$* : 代表 ["$1c$2c$3c$4"] 其中,c为分隔符,默认为空格, 所以本例代表为 ["$1 $2 $3 $4"] ( 一般不需要记忆 )
shift 1 去掉第一个变量,shift 3 去掉前3个变量 ( 注意是前面3个,而不是第3个 )
条件判断
if [ 判断内容] ; then
//执行内容
fi
if [ "$yn" == "Y" ] || [ "$yn" == "t"] ; then
fi
if [ 条件1] ; then
elif [条件2] ; then
else
fi
case $as in
"one")
echo "The one"
;;
"two")
echo "The two"
;;
"three")
echo "The three"
;;
*) // 最后其他全部别的项目
echo "Nothing"
;;
esac
function
function fram(){
//程序段
}
function 内部也有内建变量, $0就是函数名, $1就是第一个参数 ......
循环
while [判断]
do
//代码
done
until [condition] //与while相反, 当condition不成立时,执行, 当 condition成立时就终止循环
do
//代码
done
fo varlue in st1 st2 st3 //根据变量内容
do
//程序
done
其中 第一次执行时, value=st1 , 第2次执行时, value=st2, 第3次执行时 value =st3
for username in $users
do
//代码
done
这样的话,每次 username 就是 $users 中的值,依次向下
for数值处理
for((初始值;限制值;进接值))
do
//程序段
done
例如 :
for ((i=1;i<=100;i=i+1))
do
echo $i
done
debug
方法1:
使用类似 print 的输出变量的命令, echo
debecho() {
if [ ! -z ""$DEBUG ]; then
echo "$1" > &2
fi
}
这样就可以通过设置变量 DEBUG 来判断是否将测试的print打印到屏幕, 类似C 语言中的DEBUGE
方法2:
sh [ -nvh ] scripts.sh
-n : 不要执行 script , 仅检查语法问题
-v : 再执行script 前, 先将 scirpt 内容输出到屏幕上
-x : 将使用到的 script 内容显示到屏幕上, 非常有用参数. ( 输出结果中, + 号后边的都是指令,指令执行过程显示出来,如此用户可以判断程序代码执行到哪一段时会出现相关的信息,这个功能非常棒,透过显示完整的指令串,你就能够依据输出的错误信息来修正你的脚本了。 )
/etc/init.d/ 目录下全部是script, 可以学习参考