脚本都以#!/bin/bash
开头,"#" 称为 sharp,"!" 在 unix 行话中称为 bang,合起来简称 shabang。"/bin/bash"表示在执行脚本时内部使用该路径的 bash 去执行。
脚本被被执行由两种方式:
sh
命令的参数作为 sh 命令的参数时,脚本中的"#!/bin/bash"存在与否变得不重要。
[root@docker tmp]# sh bash_script.sh
作为独立的可执行文件执行时脚本文件需要有执行权限
[root@docker tmp]# chmod +x bash_script.sh
[root@docker tmp]# ./bash_script.sh 或 /tmp/bash_script.sh
关于 echo 的用法,主要就是注意区分单引号和双引号的特殊情况。
在 bash 环境中,感叹号只能通过单引号包围来输出,因为默认情况下开启了使用感叹号引用内存中的历史命令的设置,可以使用 set +H 关闭该设置,此时就可以使用双引号包围输出。
set +H #关闭使用感叹号引用命令历史
echo "Hello World!"
或者使用多对引号分别包围 echo 的参数,其中感叹号使用单引号包围:
echo "Don't use rm -rf command"'!'
Don't use rm -rf command!
如果 echo 不加任何引号,不能输出分号";",因为分号会被 shell 解析为命令链接符号。
echo Hello,world;
Hello,world #分号作为断行符被忽略了
目前这种情况下,使用单引号,可以输出分号,但是无法扩展变量,使用双引号又无法输出感叹号,所以 echo 命令克服各种疑难杂症的方法是:对特殊符号分开引用!
str=hello
echo "$str"'!' "world"
hello! world
echo 使用 -e 选项,识别参数中的特殊意义符号。
echo 'Hello world!\n';echo "Hello world"!
Hello world!\n
Hello world!
echo -e 'Hello world!\n';echo "Hello world"!
Hello world!
Hello world!
echo默认情况下会在每行加上换行符号,使用 echo -n
取消分行输出。
echo 'hello world!' > abc.sh
echo 'hello world' >> abc.sh
cat abc.sh
hello world!
hello world
echo -n 'Hello World!'>abc.sh #取消了分行符号
echo 'Hello World!'>>abc.sh
cat abc.sh
Hello World!Hello World!
echo可以控制字体颜色和背景颜色输出。
常见的字体颜色:
重置=0,黑色=30,红色=31,绿色=32,黄色=33,蓝色=34,紫色=35,天蓝色=36,白色=37。
常见的背景颜色:
重置=0,黑色=40,红色=41,绿色=42,黄色=43,蓝色=44,紫色=45,天蓝色=46,白色=47。
字体控制选项:
1表示高亮,4表示下划线,5表示闪烁等。
因为需要使用特殊符号,所以需要配合-e选项来识别特殊符号。
下面是 echo 颜色控制的方法:
颜色控制和字体控制选项的定义顺序无所谓,只要被定义出来,shell都能识别。建议定义了颜色后同时定义关闭颜色,否则颜色会继续影响bash环境的颜色。定义转义序列的"\e"可以使用"\033"替换。
多条命令可以使用";"、"&&"、"||"连接。
命令之间没有逻辑关系,分号连接的命令会按照顺序从前向后依次执行,即使分号前面的命令执行失败也不影响后面的命令执行。
➜ ~ ls nas;echo 'Hello!'
ls: 无法访问nas: 没有那个文件或目录
Hello!
"&&" 连接的命令会按照顺序从前向后执行,但只有当 command1正确执行才执行 command2,如果 command1 不能正确执行,则 command2 不会执行。
在 bash 中,使用预定义变量 $?
判断命令是否成功执行,如果"$?"的值为0则表示前一条命令正确执行,其他任意退出值均表示不能正确执行。
➜ ~ echo hello && ls nas
hello <------------
ls: 无法访问nas: 没有那个文件或目录
➜ ~ ls nas && echo hello
ls: 无法访问nas: 没有那个文件或目录
"||" 连接的命令会按照顺序从前向后执行,但只有当 command1不正确执行才执行 command2,如果 command1正确执行则不会执行 command2。
"&&" 和 "||" 都是短路符号,符号左右的命令具有逻辑关系。
➜ ~ ls nas || echo 'yes'
ls: 无法访问nas: 没有那个文件或目录
yes
➜ ~ echo yes || ls nas
yes
一般要联合使用 "&&" 和 "||" 的情况,基本上都会先逻辑与再逻辑或。
command1 && command2 || command3
在上面的示例中,command2和 command3应该都是想要执行的命令。
如果 command1执行正确,$?
的值为0,执行 command2,然后根据 command2的情况执行 command3。
如果 command1执行出错,$?
的值不为0,"||"右边的命令command3应该被执行。
通俗的根据语义理解:“如果...就...否则...”,而!command1 && command2 || command3
表示“如果不...就...否则...”。
例如:
如果 user1存在,就显示用户名已存在,否则就添加用户:
id user1 && echo "user1 exists" || useradd user1
如果user2不存在,就添加用户,否则显示用户已存在
!id user2 && useradd user2 || echo "user2 exists"
如果user3不存在,则添加此用户,并设定其密码为用户名本身,否则显示用户不存在
!id user3 && useradd user3 && echo "user3" | passwd --stdin user3 || echo "user3 exists"
"&"表示将其前面的命令放入后台执行,放入后台后会立即返回到bash环境让用户可以继续和bash交互。如果&符号连接了两个命令,则其前面的命令被放入后台,立即执行后面的命令,所以可以简单地认为这两个命令是并行执行的,两端的命令之间也没有任何逻辑关系。
注意:在终端 bash 环境下,子 shell 中的后台进程不受终端控制,在终端关闭时,它会挂靠在 init/systemd 进程下,因此退出终端或脚本 shell 环境,无法中断这些后台进程。
[root@localhost ~]# (sleep 50 &) #终端1上执行,立即关闭该终端
[root@localhost ~]# ps aux | grep slee[p] #终端2捕捉 sleep 进程,?表示非终端进程,即脱离了终端
root 5401 0.0 0.0 107952 620 ? S 09:05 0:00 sleep 50
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。