《Linux 命令行与 Shell 脚本编程大全》笔记
第六章 使用 Linux 环境变量
第十一章 构建基本脚本
内联输入重定向(inline input redirection)
$ wc << EOF
> test string 1
> test string 2
> test string 3
> EOF
执行数学运算
- 使用方括号($[ operation ])
$ var1=$[1 + 5]
$ echo $var1
6
$ var2=$[$var1 * 2]
$ echo $var2
12
- 在脚本中使用 bc
variable=$(echo "options; expression" | bc)
#!/bin/bash
var1=100
var2=45
var3=$(echo "scale=4; $var1 / $var2" | bc)
echo The answer for this is $var3
if-then-else 语句
if command1
then
commands
elif command2
then
more commands
fi
test 命令
if test condition
then
commands
fi
-----------------
if [ condition ]
then
commands
fi
$ cat test9.sh
#!/bin/bash
# mis-using string comparisons
#
val1=baseball
val2=hockey
#
if [ $val1 \> $val2 ]
then
echo "$val1 is greater than $val2"
else
echo "$val1 is less than $val2"
fi
$
$ ./test9.sh
baseball is less than hockey
复合条件测试
if-then语句允许你使用布尔逻辑来组合测试。有两种布尔运算符可用:
-
[ condition1 ] && [ condition2 ]
-
[ condition1 ] || [ condition2 ]
if-then 的高级特性
bash shell提供了两项可在if-then语句中使用的高级特性:
-
用于数学表达式的双括号
(( expression ))
-
用于高级字符串处理功能的双方括号
[[ expression ]]
$ cat test23.sh
#!/bin/bash
# using double parenthesis
#
val1=10
#
if (( $val1 ** 2 > 90 ))
then
(( val2 = $val1 ** 2 ))
echo "The square of $val1 is $val2"
fi
$
$ ./test23.sh
The square of 10 is 100
# 注意,不需要将双括号中表达式里的大于号转义。这是双括号命令提供的另一个高级特性
双方括号里的expression使用了test命令中采用的标准字符串比较。但它提供了test命令未提供的另一个特性——模式匹配(pattern matching)。
$ cat test24.sh
#!/bin/bash
# using pattern matching
#
if [[ $USER == r* ]]
then
echo "Hello $USER"
else
echo "Sorry, I do not know you"
fi
$
$ ./test24.sh
Hello rich
case 命令
case variable in
pattern1 | pattern2) commands1;;
pattern3) commands2;;
*) default commands;;
esac
for 命令
for var in list
do
commands
done
$ cat test5b
#!/bin/bash
# reading values from a file
file="states"
IFS=$'\n'
for state in $(cat $file)
do
echo "Visit beautiful $state"
done
$ ./test5b
for file in /home/rich/test/*
do
if [ -d "$file" ]
then
echo "$file is a directory"
elif [ -f "$file" ]
then
echo "$file is a file"
fi
done
# 在Linux中,目录名和文件名中包含空格当然是合法的。要适应这种情况,应该将$file变量用双引号圈起来。
# 如果不这么做,遇到含有空格的目录名或文件名时就会有错误产生
C 语言风格的 for 命令
for (( a = 1; a < 10; a++ ))
for (( a=1, b=10; a <= 10; a++, b-- ))
do
echo "$a - $b"
done
while 命令 until 命令
while [ $var1 -gt 0 ]
do
echo $var1
var1=$[ $var1 - 1 ]
done
until [ $var1 -eq 0 ]
do
echo $var1
var1=$[ $var1 - 25 ]
done
循环处理文件数据
#!/bin/bash
# changing the IFS value
IFS.OLD=$IFS
IFS=$'\n'
for entry in $(cat /etc/passwd)
do
echo "Values in $entry –"
IFS=:
for value in $entry
do
echo " $value"
done
done
处理循环的输出
最后,在shell脚本中,你可以对循环的输出使用管道或进行重定向。这可以通过在done命令之后添加一个处理命令来实现。
for file in /home/rich/*
do
if [ -d "$file" ]
then
echo "$file is a directory"
elif
echo "$file is a file"
fi
done > output.txt
实例
查找可执行文件
#!/bin/bash
# finding files in the PATH
IFS=:
for folder in $PATH
do
echo "$folder:"
for file in $folder/*
do
if [ -x $file ]
then
echo " $file"
fi
done
done
创建多个用户账户
#!/bin/bash
# process new user accounts
input="users.csv"
while IFS=',' read -r userid name
do
echo "adding $userid"
useradd -c "$name" -m $userid
done < "$input"
$ cat users.csv
rich,Richard Blum
christine,Christine Bresnahan
barbara,Barbara Blum
tim,Timothy Bresnahan