学习了linux系统命令操作,为了提升运维效率,我们得学习shell脚本开发。
shell脚本的关键是在于处理多个命令,且处理每个命令的结果,或者将不同的命令结果进⾏传递,再次加⼯。
shell⽀持多个命令连接起来执⾏。
root@icloudy:~# date;whoami
Sun Oct 8 13:18:03 CST 2023
root
你已经会了第⼀个shell脚本。这个脚本简单到只有2个命令,这种形式,命令少还好说,如果命令较⻓,较多,那就很难在命令⾏敲打了。
我们可以把命令组合成⼀个⽂本⽂件,然后执⾏这个⽂件即可。
shell脚本⽂件,第⼀⾏必须指定想要⽤的shell
#!/bin/bash
shell脚本⾥, #号 是注释⾏,shell不会处理脚本中的注释⾏,然⽽第⼀⾏例外,该写法会通知shell⽤哪个解释器
来运⾏脚本。
shell脚本中可以书写你想要执⾏的命令,且可以添加注释⾏。
root@icloudy:~# cat test.sh
#!/bin/bash
# This is test script
date
whoami
echo "It's Over."
⽤解释器读取脚本
root@icloudy:~/shell_program# sh test.sh
Sun Oct 8 13:26:29 CST 2023
root
It's Over.
root@icloudy:~/shell_program# bash test.sh
Sun Oct 8 13:26:34 CST 2023
root
It's Over.
直接运⾏⽂件,需要赋予权限:
root@icloudy:~/shell_program# ./test.sh
-bash: ./test.sh: Permission denied
root@icloudy:~/shell_program# ll test.sh
-rw-r--r-- 1 root root 64 Oct 8 13:22 test.sh
root@icloudy:~/shell_program# chmod +x test.sh
root@icloudy:~/shell_program# ll test.sh
-rwxr-xr-x 1 root root 64 Oct 8 13:22 test.sh*
root@icloudy:~/shell_program# ./test.sh
Sun Oct 8 13:29:07 CST 2023
root
It's Over.
当以 ./test.sh 该形式执⾏脚本,则以⽂件第⼀⾏的 shebang 指定的解释器执⾏⽂件。
在shell脚本⾥,shell命令会有⾃⼰的输出,若是你想要⾃定义内容打印,以告知⽤户,当前脚本在做什么事。
可以通过echo命令来实现,注意 单引号 、 双引号 。
root@icloudy:~/shell_program# vim test.sh
root@icloudy:~/shell_program# cat test.sh
#!/bin/bash
# This script displays the date and who's logged on
echo "The time and date are:"
date
echo ''
echo "Let's see who's logged into the system:"
who
root@icloudy:~/shell_program# ./test.sh
The time and date are:
Sun Oct 8 13:35:07 CST 2023
Let's see who's logged into the system:
icloudy tty7 2023-10-04 12:05 (:0)
root@icloudy:~/shell_program#
脚本⾥,可以在环境变量名称前加上 $ 来使⽤环境变量。
root@icloudy:~/shell_program# vim test1.sh
root@icloudy:~/shell_program# cat test1.sh
#!/bin/bash
# display user information from the system
echo "User info for userid: $USER"
echo UID: $UID
echo HOME: $HOME
root@icloudy:~/shell_program# chmod +x test1.sh
root@icloudy:~/shell_program# ./test1.sh
User info for userid: root
UID: 0
HOME: /root
当⼀些情况,我们不希望shell解析⼀些符号,可以使⽤ 单引号 和 转义符 对符号不做解析。
echo识别变量的情况
root@icloudy:~/shell_program# echo "The cost of the item is $15"
The cost of the item is 5
这显然不是我们想要的,改成如下写法
root@icloudy:~/shell_program# echo ' The cost of the item is $15'
The cost of the item is $15
⽅法⼆:
root@icloudy:~/shell_program# echo "The cost of the item is \$15"
The cost of the item is $15
现在允许shell解读 $ 只是⼀个普通的美元符了。
root@icloudy:~/shell_program# vim test2.sh
root@icloudy:~/shell_program# cat test2.sh
t variables
days=10
guest="王"
echo "$guest checked in $days days ago"
root@icloudy:~/shell_program# chmod +x test2.sh
root@icloudy:~/shell_program# ./test2.sh
./test2.sh: line 1: t: command not found
王 checked in 10 days ago
变量被引⽤时会输出赋予给它的值,变量会在shell脚本退出后消失。
变量每次被引⽤的时候,都会输出赋予的值,需要加上 $ 符
root@icloudy:~/shell_program# vim test3.sh
root@icloudy:~/shell_program# cat test3.sh
#!/bin/bash
# assigning a variable value to another variable
value1=10
value2=$value1
echo "The resulting value is $value2"
root@icloudy:~/shell_program# ./test3.sh
The resulting value is 10
若是忘记⽤美元符,则结果就错误了,输出的是:The resulting value is value1
shell⼀⼤特性就是可以从命令中提取结果,再赋予给变量,这样处理脚本数据特别⽅便。
有两个⽅式将命令输出赋予给变量:
实践用法:
root@icloudy:~/shell_program# cat test.sh
#!/bin/bash
testing=$(date)
echo "The date and time are:" $testing
# 结果
root@icloudy:~/shell_program# ./test.sh
The date and time are: Sun Oct 8 19:19:06 CST 2023
再来看案例
root@icloudy:~/shell_program# cat test.sh
#!/bin/bash
# copy the /usr/bin directory listing to a log file
today=$(date +%y%m%d)
ls /usr/bin -al > log.$today
# today变量是取出命令的值,也就是提取了⽇期,然后在结合到⽂件名⾥使⽤
root@icloudy:~/shell_program# ./test.sh
root@icloudy:~/shell_program# cat log.200928 |wc -l
1240
反引号和$()的作⽤相同,⽤于命令替换(command substitution),即完成引⽤的命令的执⾏,将其结果替换出来,与变量
替换差不多。⽐如:
root@icloudy:~/shell_program# echo `date '--date=1 hour ago' +%Y-%m-%d-%H`
2023-10-08-18
# 等同于
root@icloudy:~/shell_program# echo $(date '--date=1 hour ago' +%Y-%m-%d-%H)
2023-10-08-18