前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Shell 编程(1)

Shell 编程(1)

原创
作者头像
懒人的小脑
修改2019-01-25 09:58:06
1K0
修改2019-01-25 09:58:06
举报
文章被收录于专栏:懒人的运维备忘录

Shell 脚本简介

脚本都以#!/bin/bash开头,"#" 称为 sharp,"!" 在 unix 行话中称为 bang,合起来简称 shabang。"/bin/bash"表示在执行脚本时内部使用该路径的 bash 去执行。

脚本被被执行由两种方式:

  • 将脚本作为sh命令的参数
  • 作为独立的可执行文件执行

作为 sh 命令的参数时,脚本中的"#!/bin/bash"存在与否变得不重要。

代码语言:txt
复制
[root@docker tmp]# sh bash_script.sh 

作为独立的可执行文件执行时脚本文件需要有执行权限

代码语言:txt
复制
[root@docker tmp]# chmod +x bash_script.sh
[root@docker tmp]# ./bash_script.sh 或 /tmp/bash_script.sh

引号和转义

关于 echo 的用法,主要就是注意区分单引号和双引号的特殊情况。

  • 单引号:原文输出
  • 双引号:解析命令引用

在 bash 环境中,感叹号只能通过单引号包围来输出,因为默认情况下开启了使用感叹号引用内存中的历史命令的设置,可以使用 set +H 关闭该设置,此时就可以使用双引号包围输出。

代码语言:txt
复制
set +H #关闭使用感叹号引用命令历史
echo "Hello World!"

或者使用多对引号分别包围 echo 的参数,其中感叹号使用单引号包围:

代码语言:txt
复制
echo "Don't use rm -rf command"'!'
Don't use rm -rf command!

如果 echo 不加任何引号,不能输出分号";",因为分号会被 shell 解析为命令链接符号。

代码语言:txt
复制
echo Hello,world;
Hello,world #分号作为断行符被忽略了

目前这种情况下,使用单引号,可以输出分号,但是无法扩展变量,使用双引号又无法输出感叹号,所以 echo 命令克服各种疑难杂症的方法是:对特殊符号分开引用!

代码语言:txt
复制
str=hello
echo "$str"'!' "world"
hello! world

转义

echo 使用 -e 选项,识别参数中的特殊意义符号。

代码语言:txt
复制
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 取消分行输出。

代码语言:txt
复制
echo 'hello world!' > abc.sh

echo 'hello world' >> abc.sh

cat abc.sh

hello world!
hello world
代码语言:txt
复制
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颜色输出
echo颜色输出

下面是 echo 颜色控制的方法:

颜色输出的设置方法
颜色输出的设置方法

颜色控制和字体控制选项的定义顺序无所谓,只要被定义出来,shell都能识别。建议定义了颜色后同时定义关闭颜色,否则颜色会继续影响bash环境的颜色。定义转义序列的"\e"可以使用"\033"替换。

echo 颜色输出演示
echo 颜色输出演示

多命令逻辑执行顺序

多条命令可以使用";"、"&&"、"||"连接。

;

命令之间没有逻辑关系,分号连接的命令会按照顺序从前向后依次执行,即使分号前面的命令执行失败也不影响后面的命令执行。

代码语言:txt
复制
➜  ~ ls nas;echo 'Hello!'
ls: 无法访问nas: 没有那个文件或目录
Hello!

&&-逻辑与

"&&" 连接的命令会按照顺序从前向后执行,但只有当 command1正确执行才执行 command2,如果 command1 不能正确执行,则 command2 不会执行。

在 bash 中,使用预定义变量 $? 判断命令是否成功执行,如果"$?"的值为0则表示前一条命令正确执行,其他任意退出值均表示不能正确执行。

代码语言:txt
复制
➜  ~ echo hello && ls nas
hello   <------------
ls: 无法访问nas: 没有那个文件或目录

➜  ~ ls nas && echo hello
ls: 无法访问nas: 没有那个文件或目录

||-逻辑或

"||" 连接的命令会按照顺序从前向后执行,但只有当 command1不正确执行才执行 command2,如果 command1正确执行则不会执行 command2。

"&&" 和 "||" 都是短路符号,符号左右的命令具有逻辑关系。

代码语言:txt
复制
➜  ~ 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存在,就显示用户名已存在,否则就添加用户:

代码语言:shell
复制
id user1 && echo "user1 exists" || useradd user1

如果user2不存在,就添加用户,否则显示用户已存在

代码语言:shell
复制
!id user2 && useradd user2 || echo "user2 exists"

如果user3不存在,则添加此用户,并设定其密码为用户名本身,否则显示用户不存在

代码语言:shell
复制
!id user3 && useradd user3 && echo "user3" | passwd --stdin user3 || echo "user3 exists"

&

"&"表示将其前面的命令放入后台执行,放入后台后会立即返回到bash环境让用户可以继续和bash交互。如果&符号连接了两个命令,则其前面的命令被放入后台,立即执行后面的命令,所以可以简单地认为这两个命令是并行执行的,两端的命令之间也没有任何逻辑关系。

注意:在终端 bash 环境下,子 shell 中的后台进程不受终端控制,在终端关闭时,它会挂靠在 init/systemd 进程下,因此退出终端或脚本 shell 环境,无法中断这些后台进程。

代码语言:javascript
复制
[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 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Shell 脚本简介
  • 引号和转义
    • 转义
      • 分行
        • 颜色输出
        • 多命令逻辑执行顺序
          • ;
            • &&-逻辑与
              • ||-逻辑或
                • &
                相关产品与服务
                容器服务
                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档