文章目录
1. chatper13 更多结构化命令
1.1 for
格式:
风格1:
for var in list
do
commands
done
风格2:
for (( VAR = 0; VAR < 10; ++VAR )); do
echo $VAR
done
1.2 while
格式:
while testcommand
do
other commands
done
示例:
var=10
while [ $var -gt 0 ]; do
echo $var
#var=$[ $var-1 ] # 变量减一方式1
(( var = $var-1 )) # 变量减一方式2
done
结果:
10
9
8
7
6
5
4
3
2
1
1.3 until
直到某某条件,否则do。格式:
until test commands
do
other commands
done
1.4 break与continue
与普通语言一致。
1.5 处理循环的输出
可以使用重定向,如:
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
2. chapter14处理用户输入
2.1 读取参数
$0,$1
$0 : 文件名
$1: 第一个参数
...
$9: 第9个参数
${10}:第10个参数
示例:
echo $0
echo $1
运行1:
[hadoop@hadoop1 input]$ sh param.sh 1
param.sh
1
运行2:
[hadoop@hadoop1 input]$ sh ../input/param.sh 1
../input/param.sh
1
$0是运行脚本时,传进来的值,可能会不同。如果运行时,带了路径,则会显示路径,比较麻烦。
basename
幸好有个方便的小命令可以帮到我们。basename命令会返回不包含路径的脚本名。
[hadoop@hadoop1 input]$ basename
basename: missing operand
Try `basename --help' for more information.
[hadoop@hadoop1 input]$ basename /home/hadoop/test/input/param.sh
param.sh
在脚本中:
#!/usr/bin/env bash
name=$(basename $0)
echo $0
echo $name
结果:
didi@bogon:~/CodeFile/proTest/shell-pro/input$ sh ../input/input.sh
../input/input.sh
input.sh
2.2 测试参数
if [ -n “$1” ]
在shell脚本中使用命令行参数时要小心些。如果脚本不加参数运行,可能会出问题。
当脚本认为参数变量中会有数据而实际上并没有时,脚本很有可能会产生错误消息。这种写 脚本的方法并不可取。在使用参数前一定要检查其中是否存在数据。
在本例中,使用了-n
测试来检查命令行参数$1中是否有数据。在下一节中,你会看到还有
另一种检查命令行参数的方法。
#!/usr/bin/env bash
if [ -n "$1" ];then #注意$1要加引号,-n判断的是字符串
echo "hi,see you,$1"
else
echo "my self"
fi
结果:
didi@bogon:~/CodeFile/proTest/shell-pro/input$ sh param.sh pp
hi,see you,pp
didi@bogon:~/CodeFile/proTest/shell-pro/input$ sh param.sh
my self
2.3 特殊变量
$# 参数个数
返回的是数值类型,例如:if [ $# -ne 2 ]
特殊变量$#含有脚本运行时携带的命令行参数的个数。可以在脚本中任何地方使用这个特殊 变量,就跟普通变量一样。
如果你仔细考虑过,可能会觉得既然$#
变量含有参数的总数,那么变量${$#}
就代表了最后
一个命令行参数变量,但是出了点问题。它表明你 不能在花括号内使用美元符
。必须将美元符换成感叹号。
${!#} 最后一个参数
重要的是要注意,当命令行上没有任何参数时,$#
的值为0, params变量的值也一样,但${!#}
变量会返回命令行用到的脚本名。
$* 和 $@ 抓取所有参数
$*
和$@
变量可以用来轻松访问所有的参数。这两个变量都能够在单个变量中存储所有的命 令行参数。
$*
变量会将命令行上提供的所有参数当作一个单词保存。这个单词包含了命令行中出现的每 一个参数值。基本上$*
变量会将这些参数视为一个整体,而不是多个个体。- 另一方面,
$@
变量会将命令行上提供的所有参数当作同一字符串中的多个独立的单词。这样 你就能够遍历所有的参数值,得到每个参数。这通常通过for
命令完成。
移动参数shift
在使用shift命令时,默认情况下它会将每个参数变量向左移动一个位置。所以,变量$3 的值会移到$2中,变量$2的值会移到$1中,而变量$1的值则会被删除(注意,变量$0的值,也就是程序名,不会改变)。
这是遍历命令行参数的另一个好方法,尤其是在你不知道到底有多少参数时。你可以只操作 第一个参数,移动参数,然后继续操作第一个参数。
2.4 处理选项
略
2.5 输入
基本读取
read
read -p 带提示
如:
read -p "Please enter your age: " age
days=$[ $age * 365 ]
从文件中读取
最后,也可以用read命令来读取Linux系统上文件里保存的数据。每次调用read命令,它都 4 会从文件中读取一行文本。当文件中再没有内容时,read命令会退出并返回非零退出状态码。
其中最难的部分是将文件中的数据传给read命令。最常见的方法是对文件使用cat命令,将 结果通过管道直接传给含有read命令的while命令。
#!/usr/bin/env bash
# 从文件中读数据
count=1
cat test.txt | while read line; do
echo "第 $count 行,内容是:$line"
count=$[ $count+1 ]
done
读取最后一行可能会遇到问题。见:https://www.cnblogs.com/Braveliu/p/10573389.html
改进:
while read line || [[ -n ${line} ]]