摘自《Linux命令行与shell脚本》
shell编程学习
11 构建基本脚本
11.1 使用多个命令
用;
11.2 创建shell脚本文件
#!/bin/bash
# 注释
11.4 使用变量
- 引用一个变量值时需要使 用美元符,而引用变量来对其进行赋值时则不要使用美元符。
- 在赋值语句中使用value1变量的值时,仍然必须用美元符。
- 有两种方法可以将命令输出赋给变量:
- 反引符号
- $()格式
#!/bin/bash # 运行命令替换符号中的命令 testing = `date` testing = $(date)
11.5 重定向输入和输出
- 输出重定向 >
- 输入重定向 <
11.6 管道连接
由管道串起的两个命令会一次执行,LINUX内部会将它们连接起来,第一个命令输出的同时,输出会送到第二个命令。
command1 | command2
11.7 执行数学运算
- expr命令
- 使用方括号
bash shell数学运算符只支持整数运算。va1 = $[1+5] echo $va1 # 输出6 var1 = 100 var2 = 50 var3 = 45 var4 = $[$var1*($var2-$var3)] echo The final result is $var4 # 输出500
- 浮点解决方法
#!/bin/bash
var1=20
var2=3.14159
var3=$(echo "scale=4; $var1*var2" | bc)
echo The final result is var3
#!/bin/bash
var1=10.46
var2=43.67
var3=33.2
var4=71
var5=$(bc << EOF
scale=4
a1 = ( $var1 * $var2 )
b1 = ( $var3 * $var4 )
a1+b1
EOF
)
echo The final answer for this mess is $var5
# 输出var5的数值
11.8 退出脚本
# 退出状态码
exit status
12 使用结构化命令
12.1 if-then
bash shell的if语句会运行if后面的那个命令,如果该命令的退出状态码是0,位于then部分就会被执行,如果是其他值,then就不会被执行。
if command
then
commands
fi
举个例子:查看Christine是否在passwd文件中。
#!/bin/bash
# testing multiple commands in the then section
#
testuser = Christine
#
if grep $testuser /etc/passwd
then
echo "First Command"
echo "Second Command"
echo "I can even put in other commands besides echo: "
ls -a /home/$testuser/.b*
fi
12.2 if-then-else
if command
then
commands
else
commands
fi
12.3 嵌套if
if command1
then
commands
elif command2
then
more commands
elif command3
then
more commands
elif command4
then
more commands
fi
12.4 test命令
test命令可以判断三类条件:
- 数值比较
- 字符串比较
要大于号是要转移一下的! - 文件比较
if test condition
then
commands
fi
# 方括号定义了测试条件,注意,第一个方括号之后和第二个方括号之前必须加上一个空格,否则报错
if [ condition ]
then
commands
fi
12.5 复合条件测试
12.6 if-then的高级特性
- 双括号命令 (允许你再比较过程中使用高级的数学表达式)
“注意,不需要将双括号中表达式里的大于号转义。这是双括号命令提供的另一个高级特性。”
(( expression ))
if (( $val1 ** 2 > 90))
then
(( val2 = $val1 ** 2))
echo "The square of $val1 is $ val2"
fi
2. 双方括号命令 (允许你再比较过程中使用高级的字符串表达式)
相比较test,它还可以匹配字符串值。
12.7 case命令
如果使用if-then语句:
#!/bin/bash
if [ $USER = 'rich' ]
then
echo "Welcome $USER"
elif [ $USER = 'barbara' ]
then
echo "Welcome $USER"
elif [ $USER = 'testing' ]
then
echo "Special testing account"
elif [ $USER = 'jessiaca' ]
then
echo "Do not forget to logout when you're done"
else
echo "Sorry, you're not allowed here"
fi
可以换用这个命令:
case variable in
pattern1 | pattern2) commands1;;
pattern3) commands2;;
*) default commands;;
esac
13 更多的结构化命令
13.1 for命令
# for var in list; do
for var in list
do
commands
done
for命令用空格来划分列表中的每个值。如果在单独的数据值中有 空格,就必须用双引号将这些值圈起来。
#!/bin/bash
# reading values from a file
file="states"
for state in $(cate $file)
do
echo "Visit beautiful $state"
done
内部字段换行符,IFS环境便令定义了bash shell用作字段分隔符的一系列字符。默认情况下,bash shell会将下列字符当作字段分隔符:
- 空格
- 制表符
- 换行符
可以通过设置IFS来定义字段分隔符。
IFS=$'\n'
# 当遇到代码量较大的代码时
IFS.OLD=$IFS
IFS=$'\n'
# <在代码中使用新的IFS值>
IFS=$IFS.OLD
13.2 C语言风格的for命令
for (( variable assignment ; condition ; iteration process ))
# 变量赋值可以有空格
# 条件变量不以美元符开头
# 迭代过程的算式未用expr命令格式
13.3 while命令
while test command
do
other commands
done
13.4 until命令
当test commands满足条件时,才停下来。
until test commands
do
other commands
done
13.5 嵌套循环
讲述了该怎样嵌套几个for和while,注意缩进和语法,使用时小心。
13.6 循环处理
两个相关技术:使用嵌套循环;修改IFS环境变量
#!/bin/bash
# changing the IFS value
IFS.OLD=$IFS
IFS=$'\n'
for entry in $(cat /etc/passwd)
do
echo "Values in $enry '"
IFS=:
for value in $enry
do
echo " $value"
done
done
13.7 控制循环
有两个控制循环内部的情况
- break命令
break n
其中n指定了要跳出的循环层级。默认情况下,n为1,表明跳出的是当前的循环。如果你将 n设为2,break命令就会停止下一级的外部循环。
如果没有n的话就是跳出最内层循环。
2. continue命令
同上
13.8 处理循环输出
可以对循环的输出使用管道或者进行重定向。
#!/bin/bash
for (( a = 1; a < 10; a++ ))
do
echo "The number is $a"
done > test23.txt
14 处理用户输入
14.1 命令行参数
位置参数变量是标准的数字:$0是程序名,$1是第一个参数,$2是第二个参数,依次类推,直到第九个参数$9,如果不止9个的时候,可以在变量数字周围加上花括号。
当脚本认为参数变量会有数据而实际上并没有时,脚本很有可能产生错误,因此需要在参数前一定要检查其中是否存在数据。
#!/bin/bash
if [ -n "$1" ]
then
echo Hello $1, glad to meet you.
else
echo "Sorry, you did not identify yourself."
fi
14.2 特殊参数变量
- 参数统计
$# 含有脚本运行时携带的命令行参数的个数。
#!/bin/bash
echo There were $# parameters supplied.
如果想取最后一个就是${!#}
2. 抓取所有的数据
# testing $* and $@
s#
echo
count=1
#
for param in "$*"
do
echo "\$" Parameter #$count=$param"
count=$[ $count + 1 ]
done
echo
count=1
for param in "$@"
do
echo "\$@ Parameter #$count=$param"
count=$[ $count + 1]
done
14.3 移动变量
bash shell的shift命令能够用来操作命令行参数。
使用shift命令的时候要小心。如果某个参数被移出,它的值就被丢弃了,无法再恢复。
#!/bin/bash
echo
count=1
while [ -n "$1" ]
do
echo "Parameter #$count = $1"
count=$[ $count + 1 ]
shift
done
14.4 处理选项
- 查找选项
#!/bin/bash
# extracting command line options and values
echo
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option";;
-b) param = "$2"
echo "Found the -b option, with parameter value $param"
shift ;; # 移动了两个位置
-c) echo "Found the -c option";;
--) shift
break ;;
*) echo "$1 is not an option";;
esac
shift
done
#
count-1
for param in "$@"
do
echo "Paramater #$count: $param"
count=$[ $count + 1 ]
done
- 使用getopt命令