sh 脚本
变量
打印
1
2
3
4
5
|
# 打印
echo “hello world!”
# shell默认是不转义上面的字符的。需要加-e选项。带上双引号
echo -e "a is $a \n"
|
变量
1
2
3
4
5
6
7
8
9
10
|
# 定义变量
variable_name=1
readonly variable_name_2=2 # 不可变变量
# 打印变量
echo $variable_name
echo ${variable_name} # 建议加上花括号
# 删除变量
unset variable_name
|
| 变量 |
含义 |
$0 |
当前脚本的文件名 |
$n |
传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。 |
$# |
传递给脚本或函数的参数个数。 |
$* |
传递给脚本或函数的所有参数。 |
$@ |
传递给脚本或函数的所有参数。被双引号(" “)包含时,与 $* 稍有不同 |
$? |
上个命令的退出状态,或函数的返回值。一般情况下,大部分命令执行成功会返回 0,失败返回 1 |
$$ |
当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。 |
| 形式 |
说明 |
${var} |
变量本来的值 |
${var:-word} |
如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。 |
${var:=word} |
如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。 |
${var:?message} |
如果变量 var 为空或已被删除(unset),那么将消息 message 送到标准错误输出,可以用来检测变量 var 是否可以被正常赋值。若此替换出现在Shell脚本中,那么脚本将停止运行。 |
${var:+word} |
如果变量 var 被定义,那么返回 word,但不改变 var 的值。 |
shell示例
下面的脚本用于php安装过程中安装zip扩展。
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
|
php_zip_ins.sh
#!/bin/bash
#zip install
if [ -d php-5.4.25/ext/zip ];then
cd php-5.4.25/ext/zip
else
tar zxvf php-5.4.25.tar.gz
cd php-5.4.25/ext/zip
fi
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make
[ $? != 0 ] && exit
make install
echo
grep 'no-debug-zts-20100525' /usr/local/php/etc/php.ini
if [ $? != 0 ];then
echo '' >> /usr/local/php/etc/php.ini
echo 'extension_dir=/usr/local/php/lib/php/extensions/no-debug-zts-20100525' >> /usr/local/php/etc/php.ini
fi
grep 'zip.so' /usr/local/php/etc/php.ini
if [ $? != 0 ];then
echo 'extension=zip.so' >> /usr/local/php/etc/php.ini
fi
echo "zip install is OK"
/usr/local/apache2/bin/apachectl restart
cd -
rm -rf php-5.4.25
echo "all ok!"
ls /usr/local/php/lib/php/extensions/no-debug-zts-20100525/
|
运算
数学运算
1
2
3
4
5
6
7
8
9
10
11
|
# 命令行直接计算
expr 2 + 2 #4
expr 3 - 2 #1
expr 3 / 2 #1
expr 3 \* 2 #6
# 使用表达式
a=10
b=20
val=`expr $a + $b`
echo "a + b : $val"
|
关系运算
1
2
3
4
5
6
7
8
9
|
#!/bin/sh
a=10
b=20
if [ $a -eq $b ]
then
echo "$a -eq $b : a is equal to b"
else
echo "$a -eq $b: a is not equal to b"
fi
|
| 运算符 |
说明 |
|
| =-eq |
检测两个数是否相等,相等返回 true。同算数运算符== |
|
| =-ne |
检测两个数是否相等,不相等返回 true |
|
| =-gt |
检测左边的数是否大于右边的,如果是,则返回 true。 |
|
| =-lt |
检测左边的数是否小于右边的,如果是,则返回 true。 |
|
| =-ge |
检测左边的数是否大等于右边的,如果是,则返回 true。 |
|
| =-le |
检测左边的数是否小于等于右边的,如果是,则返回 true。 |
|
布尔运算
1
2
3
4
|
if [ 3 -eq 3 -a 3 -lt 5 ]
then
echo 'ok'
fi;
|
| 运算符 |
说明 |
|
| ! |
非运算,表达式为 true 则返回 false,否则返回 true。 |
|
| -o |
或运算(or),有一个表达式为 true 则返回 true。 |
|
| -a |
与运算(and),两个表达式都为 true 才返回 true。 |
|
字符串运算
| 运算符 |
说明 |
举例 |
| = |
检测两个字符串是否相等,相等返回 true。 |
[ $a = $b ] 返回 false。 |
| != |
检测两个字符串是否相等,不相等返回 true。 |
[ $a != $b ] 返回 true。 |
| -z |
检测字符串长度是否为0,为0返回 true。 |
[ -z $a ] 返回 false。 |
| -n |
检测字符串长度是否为0,不为0返回 true。 |
[ -n $a ] 返回 true。 |
| str |
检测字符串是否为空,不为空返回 true。 |
[ $a ] 返回 true。 |
文件运算
1
2
3
4
5
6
7
8
9
|
#!/bin/sh
file="/tmp/test.sh"
if [ -e $file ]
then
echo "File exists"
else
echo "File does not exist"
fi
|
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
|
操作符 说明 举例
-b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。
-c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ] 返回 false。
-d file 检测文件是否是目录,如果是,则返回 true。 [ -d $file ] 返回 false。
-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 [ -f $file ] 返回 true。
-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。 [ -g $file ] 返回 false。
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 [ -k $file ] 返回 false。
-p file 检测文件是否是具名管道,如果是,则返回 true。 [ -p $file ] 返回 false。
-u file 检测文件是否设置了 SUID 位,如果是,则返回 true。 [ -u $file ] 返回 false。
-r file 检测文件是否可读,如果是,则返回 true。 [ -r $file ] 返回 true。
-w file 检测文件是否可写,如果是,则返回 true。 [ -w $file ] 返回 true。
-x file 检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true。
-s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true。
-e file 检测文件(包括目录)是否存在,如果是,则返回 true。 [ -e $file ] 返回 true。
|
字符串和数组
字符串
1
2
3
4
|
str="hello"
${#str} # 读取字符串长度
echo ${str} # 读取字符串全部
echo ${str:1} # 截取字符串
|
数组
1
2
3
4
5
6
|
arr=(a1 a2 a3)
echo ${#arr[*]} # 读取数组长度
echo ${#arr[1]} # 读取数组某个元素长度
echo ${arr[*]} # 读取数组全部
echo ${arr[1]} # 读取数组某个元素
|
条件判断
if
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#!/bin/bash/
a=10
b=20
if [ $a == $b ]
then
echo "a is equal to b"
elif [ $a -gt $b ]
then
echo "a is greater to b"
# 注意 else 后面没有 then
else
echo "a is less to b"
fi
|
case
1
2
3
4
5
6
7
8
9
10
11
12
|
#!/bin/bash/
grade="B"
case $grade in
"A") echo "Very Good!";;
"B") echo "Good!";;
"C") echo "Come On!";;
*)
echo "You Must Try!"
echo "Sorry!";;
esac
|
经典例子(从命令行读取参数)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#!/bin/sh
usage()
{
echo "Usage: $0 -s [start|stop|reload|restart] -e [online|test]"
exit 1
}
if [ -z $1 ]; then
usage
fi
while getopts 's:e:h' OPT; do
case $OPT in
s) cmd="$OPTARG";;
e) env="$OPTARG";;
h) usage;;
?) usage;;
esac
done
echo $cmd
echo $env
|
循环语句
for
1
2
3
4
5
6
|
#!/bin/bash/
for value in 1 2 3 4 5
do
echo "The value is $value"
done
|
遍历当前目录的文件
1
2
3
4
5
|
#!/bin/bash
for FILE in *
do
echo $FILE
done
|
while
1
2
3
4
5
6
7
8
|
#!/bin/bash
c=0;
while [ $c -lt 3 ]
do
echo "Value c is $c"
c=`expr $c + 1`
done
|
until
1
2
3
4
5
6
7
8
|
#!/bin/bash
c=0;
until [ $c -eq 3 ]
do
echo "Value c is $c"
c=`expr $c + 1`
done
|
函数
1
2
3
4
5
6
7
8
|
# function 为可选
function function_name () {
list of commands
[ return value ]
}
# 获取函数返回值到变量
value=$(function_name)
|
输入输出重定向
输入重定向
1
2
3
4
5
6
|
# 内容被重定向到文件。
# 如果文件存在,会被覆盖
command > file
# >> 为追加,不会覆盖
command >> file
|
输出重定向
一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:
- 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
- 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
- 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。
1
2
3
4
5
|
# stderr 重定向到 file
command 2 > file
# stdout 和 stderr 合并后重定向到 file
command > file 2>&1
|
| 命令 |
说明 |
|
| command > |
file 将输出重定向到 file。 |
|
| command < |
file 将输入重定向到 file。 |
|
| command > |
> file 将输出以追加的方式重定向到 file。 |
|
| n > file |
将文件描述符为 n 的文件重定向到 file。 |
|
| n » file |
将文件描述符为 n 的文件以追加的方式重定向到file。 |
|
| n >& m |
将输出文件 m 和 n 合并。 |
|
| n <& m |
将输入文件 m 和 n 合并。 |
|
| « tag |
将开始标记 tag 和结束标记 tag 之间的内容作为输入。 |
|
特殊
1
2
3
4
5
6
7
8
9
10
11
|
# 将两个 delimiter 之间的内容(document) 作为输入传递给 command
command << delimiter
document
delimiter
# 示例:通过 wc -l 命令计算 document 的行数
wc -l << EOF
This is a simple lookup program
for good (and bad) restaurants
in Cape Town.
EOF
|
/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃
Shell文件包含
被包含文件:sub.sh
主文件:test.sh
1
2
|
. ./sub.sh
echo $name
|
运行主文件的结果:
注意
1
2
3
4
5
6
7
8
9
|
# 获取当前正在执行脚本的绝对路径
basepath=$(cd `dirname $0`; pwd)
# 按特定字符串截取字符串
str=/www/html/php/myapp/
b=($(echo $str|sed 's#/# #g'))
b_len=`expr ${#b[*]} - 1`
app_name=${b[$b_len]}
echo $app_name
|