Shell--脚本

Bash Shell–脚本

date命令:显示当前日期和时间
who命令:显示当前是谁登录到了系统上。

这种技术对于小型脚本尚可,但它有一个很大的缺陷:
每次运行之前,你都必须在命令提示符下输入整个命令。
可以将这些命令组合成一个简单的文本文件,这样就不需要在命令行中手动输入了。
在需要运行这些命令时,只用运行这个文本文件就行了。

创建shell脚本文件

在创建shell脚本文件时,必须在文件的第一行指定要使用的shell。其格式为:
#!/bin/bash
在通常的shell脚本中,井号( #)用作注释行。
shell并不会处理shell脚本中的注释行。
然而,shell脚本文件的第一行是个例外, #后面的惊叹号会告诉shell用哪个shell来运行脚本。

让bash shell能找到你的脚本文件
要让shell找到test1脚本,只需采取以下两种作法之一:
 将shell脚本文件所处的目录添加到PATH环境变量中;
 在提示符中用绝对或相对文件路径来引用shell脚本文件。
$chmod u+x test1(文件名)
$./test1

显示消息:在echo命令后面加上一个字符串,该命令就能显示出这个文本字符串。

在这里插入图片描述

echo命令可用单引号或双引号来划定文本字符串。
可以将echo语句添加到shell脚本中任何需要显示额外信息的地方。

在这里插入图片描述
在这里插入图片描述

如果想把文本字符串和命令输出显示在同一行中:可以用echo语句的-n参数

在这里插入图片描述
在这里插入图片描述

在环境变量名称之前加上美元符( $)来使用这些环境变量。
$USER、 UID和HOME环境变量用来显示已登录用户的有关信息。
只要脚本在引号中出现美元符,它就会以为你在引用一个变量。

在这里插入图片描述

脚本会尝试显示变量$1(但并未定义),再显示数字5。要显示美元符,你必须在它前面放置一个反斜线。

在这里插入图片描述

用户变量可以是任何由字母、数字或下划线组成的文本字符串,长度不超过20个。
用户变量区分大小写,所以变量Var1和变量var1是不同的。
使用等号将值赋给用户变量。在变量、等号和值之间不能出现空格
引用一个变量值时需要使用美元符,而引用变量来对其进行赋值时则不要使用美元符。

在这里插入图片描述
在这里插入图片描述

没有美元符, shell会将变量名解释成普通的文本字符串。

命令替换

从命令输出中提取信息,并将其赋给变量。
有两种方法可以将命令输出赋给变量:

在这里插入图片描述

 反引号字符( `) 很少用到
 $()格式

在这里插入图片描述

shell会运行命令替换符号中的命令,并将其输出赋给变量testing。
注意,赋值等号和命令替换字符之间没有空格。

在这里插入图片描述
在这里插入图片描述

在脚本中通过命令替换获得当前日期并用它来生成唯一文件名。
+%y%m%d格式告诉date命令将日期显示为两位数的年月日的组合。

重定向输入和输出

想要保存某个命令的输出,可以将命令的输出重定向到另一个位置,
同时也可以将文件重定向到命令输入。

输出重定向:>

在这里插入图片描述

重定向操作符创建了一个文件test6(通过默认的umask设置),
并将date命令的输出重定向到该文件中。
如果输出文件已经存在了,重定向操作符会用新的文件数据覆盖已有文件。

不想覆盖文件原有内容,而是想要将命令的输出追加到已有文件中,可以用双大于号( >>)来追加数据。

输入重定向

输入重定向将文件的内容重定向到命令:<
在命令行上,命令总是在左侧,而重定向符号“指向”数据流动的方向。

在这里插入图片描述

wc命令可以对数据中的文本进行计数。默认情况下输出文本的行数、词数、字节数。

内联输入重定向:<<

无需使用文件进行重定向,只需要在命令行中指定用于输入重定向的数据就可以了。
除了这个符号,
你必须指定一个文本标记来划分输入数据的开始和结尾。
任何字符串都可作为文本标记,但在数据的开始和结尾文本标记必须一致。
提示符会持续提示,以获取更多的输入数据,直到你输入了作为文本标记的那个字符串。

在这里插入图片描述

管道:

在这里插入图片描述

$rpm -qa
rpm命令对系统上安装的软件包进行管理。配合-qa使用,生成已安装包的列表。
rpm命令的输出重定向到了文件rpm.list。再将内容发送给sort命令,该命令按字母顺序对软件包进行排序。
我们用不着将命令输出重定向到文件中,可以将其直接重定向到另一个命令。这个过程叫作管道连接( piping)。 很少用到

在这里插入图片描述

Linux系统同时运行这两个命令,
在系统内部将它们连接起来。
在第一个命令产生输出的同时,输出会被立即送给第二个命令。
数据传输不会用到任何中间文件或缓冲区。
$ rpm -qa | sort 代替上面的命令
$ rpm -qa | sort | more 强行将输出按屏显示。
ls -l命令产生了目录中所有文件的长列表。
$ls -l | more 通过将输出管道连接到more命令,可以强制输出在一屏数据显示后停下来。

表达式

$ expr 5 * 2
使用方括号将数字表达式围起来。
bash shell数学运算符只支持整数运算。

在这里插入图片描述

$bc 进入bc计算机。可以在命令行中输入浮点表达式,并计算后返回结果。
scale变量的默认值是0。
在scale值被设置前, bash计算器的计算结果不包含小数位。在将其值设置成4后, bash计算器显示的结果包含四位小数。
-q命令行选项可以不显示bash计算器冗长的欢迎信息。
bash计算器还支持变量,可以用print语句打印变量和数字。

在这里插入图片描述

在脚本中使用bc:

在这里插入图片描述
在这里插入图片描述

bc命令能识别输入重定向,使用内联输入重定向,直接在命令行中重定向数据。

退出脚本

Linux提供了一个专门的变量$?来保存上个已执行命令的退出状态码。
对于需要进行检查的命令,必须在其运行完毕后立刻查看或使用该变量。
它的值会变成由shell所执行的最后一条命令的退出状态码。
按照惯例,一个成功结束的命令的退出状态码是0。
无效命令会返回一个退出状态码127。
退出状态码126表明用户没有执行命令的正确权限。 一般性的退出状态码1,表明在命令中发生了未知错误/给某个命令提供了无效参数。

在这里插入图片描述

总结

在变量前使用美元符来引用环境变量。
通过反引号或$()捕获的某个命令的输出。
通过大于号将命令输出从显示器屏幕重定向到一个文件中。
也可以通过双大于号将输出数据追加到已有文件。
小于号用来将输入重定向到命令。
Linux管道命令(断条符号)允许你将命令的输出直接重定向到另一个命令的输入。
为了执行浮点运算,你需要利用bc计算器命令,将内联数据重定向到输入,然后将输出存储到用户变量中。
shell中运行的每个命令都会产生一个退出状态码。

结构化命令

if-then和case语句。

在这里插入图片描述

在这里插入图片描述

If-then-else语句

在这里插入图片描述

当if语句中的命令返回非零退出状态码时,
 bash shell会执行else部分中的命令。
嵌套if-then语句的问题在于代码不易阅读,很难理清逻辑流程。
可以使用else部分的另一种形式:elif。
这样就不用再书写多个if-then语句了。 
elif使用另一个if-then语句延续else部分。

在这里插入图片描述

elif语句行提供了另一个要测试的命令,这类似于原始的if语句行。
如果elif后命令的退出状态码是0,则bash会执行第二个then语句部分的命令。
使用这种嵌套方法,代码更清晰,逻辑更易懂。

在这里插入图片描述

elif语句返回的是非零值的退出状态。这使得elif块中的else代码块得以执行。
可以继续将多个elif语句串起来,形成一个大的if-then-elif嵌套组合。

在这里插入图片描述

每块命令都会根据命令是否会返回退出状态码0来执行。
记住, bash shell会依次执行if语句,只有第一个返回退出状态码0的语句中的then部分会被执行。
可以使用test命令确定变量中是否有内容。这只需要一个简单的条件表达式。

在这里插入图片描述

当test命令测试条件时,返回的退出状态为0。这使得then语句块中的语句得以执行。

在这里插入图片描述

方括号定义了测试条件。
无需在if-then语句中声明test命令。
注意,第一个方括号之后和第二个方括号之前必须加上一个空格,否则就会报错。

在这里插入图片描述
在这里插入图片描述

这个脚本中只用了大于号,没有出现错误,但结果是错的。脚本把大于号解释成了输出重定向。
因此,它创建了一个名为hockey的文件。
由于重定向的顺利完成, test命令返回了退出状态码0, if语句便以为所有命令都成功结束了。
要解决这个问题,就需要正确转义大于号。

在这里插入图片描述

比较测试中,大写字母被认为是小于小写字母的。
sory命令相反,使用的是系统的本地化语言设置中定义的排序顺序。小写字母出现在大写字母前。

在这里插入图片描述

在这里插入图片描述

复合条件测试

if-then语句允许你使用布尔逻辑来组合测试。有两种布尔运算符可用:
 [ condition1 ] && [ condition2 ] AND布尔运算符,要让then部分命令执行,两个条件都必须满足。
 [ condition1 ] || [ condition2 ] OR布尔运算符,任意条件为TRUE,then部分的命令就会执行。

双括号

在这里插入图片描述

expression可以是任意的数学赋值或比较表达式。
除了test命令使用的标准数学运算符,表12-4列出了双括号命令中会用到的其他运算符。

在这里插入图片描述

可以在if语句中用双括号命令,也可以在脚本中的普通命令里使用来赋值。
注意,不需要将双括号中表达式里的大于号转义。这是双括号命令提供的另一个高级特性。

双方括号:

提供了针对字符串比较的高级特性。

在这里插入图片描述

双方括号里的expression使用了test命令中采用的标准字符串比较。
但它提供了test命令未提供的另一个特性——模式匹配( pattern matching)。

if [[ $USER == r* ]]
双等号将右边的字符串( r*)视为一个模式,并应用模式匹配规则。
双方括号命令USER环境变量进行匹配,看它是否以字母r开头。如果是的话,比较通过, shell会执行then部分的命令。

case命令

就不需要再写出所有的elif语句来不停地检查同一个变量的值了。
 case命令会采用列表格式来检查单个变量的多个值。

在这里插入图片描述

for命令

在这里插入图片描述

for命令,允许你创建一个遍历一系列值的循环。
每次迭代都使用其中一个值来执行已定义好的一组命令。
只要你愿意,也可以将do语句和for语句放在同一行,但必须用分号将其同列表中的值分开: for var in list; do
使用转义字符(反斜线)来将单引号转义;

在这里插入图片描述

在第一个有问题的地方添加了反斜线字符来转义don’t中的单引号。
在第二个有问题的地方将this’ll用双引号圈起来。两种方法都能正常辨别出这个值。
for循环假定每个值都是用空格分割的。
如果在单独的数据值中有空格,就必须用双引号将这些值圈起来。

在这里插入图片描述

$list变量包含了用于迭代的标准文本值列表。
注意,代码还使用了另一个赋值语句向该变量包含的已有列表中添加(或者说是拼接)了一个值。
这是向变量中存储的已有文本字符串尾部添加文本的一个常用方法。

在这里插入图片描述
在这里插入图片描述

IFS=:
如果要指定多个IFS字符,只要将它们在赋值行串起来就行。
IFS=美元符号’\n’:;"
这个赋值会将换行符、冒号、分号和双引号作为字段分隔符。如何使用IFS字符解析数据没有任何限制。

C语言风格的for循环

在这里插入图片描述

注意,有些部分并没有遵循bash shell标准的for命令:
 变量赋值可以有空格;
 条件中的变量不以美元符开头;
 迭代过程的算式未用expr命令格式。

while命令

在这里插入图片描述

while循环会在测试条件不再成立时停止。
while echo $var1 显示了var1变量的当前值。
[ $var1 -ge 0 ] 判断var1变量的值。(是否大于等于0)

while循环会在var1变量等于0时执行echo语句,
然后将var1变量的值减一。
接下来再次执行测试命令,用于下一次迭代。
echo测试命令被执行并显示了var变量的值(现在小于0了)。直到shell执行test测试命令, whle循环才会停止。

until命令

注意,在使用嵌套循环时,你是在迭代中使用迭代,与命令运行的次数是乘积关系。

在这里插入图片描述

这个脚本使用了两个不同的IFS值来解析数据。
第一个IFS值解出/etc/passwd文件中的单独的行。
内部for循环接着将IFS的值修改为冒号,允许你从/etc/passwd的行中解析出单独的值。
内部循环会解析出/etc/passwd每行中的各个值。
这种方法在处理外部导入电子表格所采用的逗号分隔的数据时也很方便。

控制循环

break命令&continue命令

for循环通常都会遍历列表中指定的所有值。
但当满足if-then的条件时, shell会执行break命令,停止for循环。
while循环会在if-then的条件满足时执行break命令,终止。

跳出外部循环:break n
其中m制定了要跳出的循环层级。默认n为1,表明跳出的是当前的循环。如果n为2则停止下一级的外部循环。

continue命令可以提前中止某次循环中的命令,但并不会完全终止整个循环。可以在循环内部设置shell不执行命令的条件。

和break命令一样, continue命令也允许通过命令行参数指定要继续执行哪一级循环:
continue n
其中n定义了要继续的循环层级。

处理循环的输出

在shell脚本中,你可以对循环的输出使用管道或进行重定向。
这可以通过在done命令之后添加一个处理命令来实现。
done > output.txt
shell会将for命令的结果重定向到文件output.txt中,而不是显示在屏幕上。

在这里插入图片描述

shell创建了文件test23.txt并将for命令的输出重定向到这个文件。 
shell在for命令之后正常显示了echo语句。

查找可执行文件,创建多个用户账户

userid,user name
第一个条目是你为新用户账户所选用的用户ID。
第二个条目是用户的全名。
两个值之间使用逗号分隔,这样就形成了一种名为逗号分隔值的文件格式(或者是.csv)。
读取文件中的数据,将IFS分隔符设置成逗号,并将其放入while语句的条件测试部分。
然后使用read命令读取文件中的各行。
while IFS=’,’ read –r userid name
read命令会自动读取.csv文本文件的下一行内容,所以不需要专门再写一个循环来处理。
当read命令返回FALSE时(也就是读取完整个文件时), while命令就会退出。
把数据从文件中送入while命令,只需在while命令尾部使用一个重定向符就可以了。

#!/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”

总结

for命令允许你遍历一系列的值,不管是在命令行里提供好的、包含在变量中的还是通过文件扩展匹配获得的文件名和目录名。
while命令使用普通命令或测试命令提供了基于命令条件的循环。
只有在命令(或条件)产生退出状态码0时, while循环才会继续迭代指定的一组命令。
until命令也提供了迭代命令的一种方法,但它的迭代是建立在命令(或条件)产生非零退出状态码的基础上。
这个特性允许你设置一个迭代结束前都必须满足的条件。
可以在shell脚本中对循环进行组合,生成多层循环。
 bash shell提供了continue和break命令,允许你根据循环内的不同值改变循环的正常流程。

bash shell还允许使用标准的命令重定向和管道来改变循环的输出。
你可以使用重定向来将循环的输出重定向到一个文件或是另一个命令。
这就为控制shell脚本执行提供了丰富的功能。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

raindayinrain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值