一文掌握shell脚本的基本语法

网友投稿 818 2022-05-29

欢迎大家star我的GitHub:https://github.com/SolerHo/geeks-shell

00. 使用环境和说明

centos8

Kernel 4.18.0-305.12.1.el8_4.x86_64

x86_64 GNU/Linux

bash 版本:4.4.20

本文不介绍和Linux 指令相关的内容

先修内容:Linux基本命令(推荐书籍:《鸟哥Linux私房菜:基础学习》)

只介绍本人在场景中使用后,结合参考书籍做的一个学习笔记,未使用过的暂时不更新

部分图片来源书籍《高级Bash脚本编程指南》

所有笔记的内容均可通过 cmd --help 查看具体的用法

01. shell概述

在shell中,每个脚本的开头都使用 #! ,就是告知系统文件的执行都需要指定一个解释器。指定一个文件类型的特殊标记。占用 2 字节 。

1.1 脚本解释器

shell极脚本都是以 #!开头,告知系统该文件的执行需要一个解释器。

常见的解释器类型如下:

#!/bin/sh #!/bin/bash #!/usr/bin/perl #!/usr/bin/tcl #!/bin/sed -f #!/usr/awk -f

解释说明

#!/bin/sh linux系统上默认是bash,多数UNIX商业OS中也默认shell。

1.2 调用脚本

执行脚本的三种方式:

#方式1 sh helloworld.sh #方式2 bash helloworld.sh bash +x helloworld.sh

第三种方式有一点特殊

./helloworld.sh #需给文件授予执行权限 #实授予权限的方式如下 chmod +x helloworld.sh #授予可执行权限 chmod +rx helloworld.sh #授予任何人可执行可读和可执行权限 chmod u+rx helloworld.sh #只给脚本的所有者可读和可执行权限

1.3 第一个脚本helloworld

#!/bin/bash echo "helloworld"

目前Linux/unix系统中,普遍的shell脚本的第一行是:#!/bin/sh 或者 #!/bin/bash。

1.4 Linux管道

在Linux中可以将两个或者多个命令连接到一起的符号(|),称为管道符。

思想:把上一个命令的输出作为下一个命令的输入(也就是因连接而形成管道(pipe)概念)。

语法格式:

command_1 | command_2 | ... | command_N # 最简单的管道 cat helloworld.sh | grep hello

⚠️注意:有输出才能输入,所以输出出现错误,则输入部分将无法处理。

管道的应用:在grep、tail、cat、sed、awk等Linux命令中较为常见。

02. shell中特殊字符

03. 转义符

转义符是一种引用单个字符的方法。添加转义符(\) 使得shell中的某个字符失去原有特殊含义。

注意:在echo 和 sed 中谨慎使用转义符,否则会有相反效果。

赋值给变量的字符串的元素也会被转义, 但是不能把一个单独的转义符赋值给变量。

04. shell中参数:

04. shell中参数:$0、$?、$!、$$、$*、$#、$@

、$?、$!、$$、$*、$#、$@

$* 和 $# 的区别:

不被双引号包含时,两者没有区别。

当被双引号包含时, $* 是将所有参数看作一整个数据。而 $# 则是将每个参数看作一个数据。

具体实例脚本:

#!/bin/bash # 已进行shellcheck检查 echo "This is $0 ---- :

#!/bin/bash # 已进行shellcheck检查 echo "This is \$0 ---- : $0" echo "This is \$1 ---- : $1" echo "This is \$2 ---- : $2" echo "This is \$? ---- : $?" echo "This is \$$ ---- : $$" echo "This is \$! ---- : $!" echo "This is \$_ ---- : $_" echo "This is \$* ---- : $*" echo "This is \$@ ---- : $*@" echo "This is \$# ---- : $#"

" echo "This is $1 ---- : " echo "This is $2 ---- : " echo "This is $? ---- : $?" echo "This is $$ ---- : $$" echo "This is $! ---- : $!" echo "This is $_ ---- : $_" echo "This is $* ---- : $*" echo "This is $@ ---- : $*@" echo "This is $# ---- : $#"

直接执行且打印信息如下:

bash +x paramshell.sh 7 77 #打印信息 This is

bash +x paramshell.sh 7 77 #打印信息 This is $0 ---- : paramshell.sh # 显示文件名 This is $1 ---- : 7 # 第1个参数 This is $2 ---- : 77 # 第2个参数 This is $? ---- : 0 # 执行完毕后的返回值 0 --- True,1 --- False This is $$ ---- : 1549879 # 该程序执行时的本身进程ID This is $! ---- : # shell后台运行的进程ID This is $_ ---- : This is $! ---- : # 变量保存之前执行命令的最后一个参数的值 This is $* ---- : 7 77 # 参数值列表 This is $@ ---- : 7 77 # 参数值列表 This is $# ---- : 2 # 参数的个数

---- : paramshell.sh # 显示文件名 This is ---- : 7 # 第1个参数 This is ---- : 77 # 第2个参数 This is $? ---- : 0 # 执行完毕后的返回值 0 --- True,1 --- False This is $$ ---- : 1549879 # 该程序执行时的本身进程ID This is $! ---- : # shell后台运行的进程ID This is $_ ---- : This is $! ---- : # 变量保存之前执行命令的最后一个参数的值 This is $* ---- : 7 77 # 参数值列表 This is $@ ---- : 7 77 # 参数值列表 This is $# ---- : 2 # 参数的个数

5. 变量问题

变量表示数据的方法。是计算机为了保存数据项而在内存中分配的一个位置或一组位置的标识或名字。

变量名就是保存值的地方。

5.1 shell变量概述

shell变量有系统变量和自定义变量两种。

对于变量名的声明规则类似于其他编程语言。由字母、数字、下划线组成,但不能以数字开头。

hello_123 # 合法 123_hello # 不合法

5.2 内部变量(系统变量)

主要记录实际工作中使用的,也不要记住。用到了再查即可。

5.3 自定义变量基本语法

定义变量:变量名=变量值,等号两侧不能有空格(与其它语言可设空格的区别之处)。变量名一般习惯使用大写。

设置变量:set 变量名=变量值。

删除变量:unset 变量名=变量值。

声明静态变量:readonly 变量名,静态变量不能用unset

使用变量:$变量名

变量赋值

简单赋值:a=123 && echo $a

命令行赋值给变量

#使用反引号 str=`cat helloworld.sh` #直接使用 $(..)格式 os=$(cat /etc/os-release)

局部变量:只在代码块或函数中可见可用。外部不可用。

Bash变量:不区分类型,都是字符串,不允许进行数值计算,除非变量中包含数字。

如果变量的值中间有空格,则使用引号(单引号或双引号均可)扩起来。

5.4 环境变量

会影响用户接口和shell的行为。环境变量是一个全局变量。

通过 export 命令将变量声明为环境变量即可。

export 变量名=变量值 # 方式 1 :直接export导入,命令行窗口重启后失效 export LD_LIBRARY_PATH=/usr/local/cuda/lib # 方式 2 # 加入到 root目录下的 .bashrc 中 # 使用 source ./bashrc 使修改后的配置信息生效,命令行窗口重启或者机器重启均不会失效 # 查看环境变量是否生效 echo $变量名 echo $LD_LIBRARY_PATH

对于环境变量的查看

# 方式 1 :查看所有变量(包括环境变量和自定义变量) set # 方式 2 :只能查看环境变量 env

5.5 引用变量

引用:将字符串使用双引号扩起来。作用:保护字符串的特殊字符(通配符)不被shell重新解释或者扩展。

[root@centos8 data]# var01=3 [root@centos8 data]# echo $var01 3

在引用变量时,需要使用$来进行引用变量的值。

变量在使用过程中,如果没有$作为前缀,需要思考如下情况:

被声明或被赋值。

是否被unset

被使用export方式导入

是否作为信号量。

赋值的两种方式:

使用 = 方式。

直接使用read命令。

6. 运算符

6.1 赋值运算符符

=: 通用赋值操作符,可用于算术和字符串的赋值。

6.2 算术运算符

⚠️注意:运算符(+|-|*|/|%)= 表示:将变量的值(+|-|*|/|%)另一个常量值,然后再将结果赋值给变量。

具体实例:

#!/bin/bash # 未进行shellcheck检查 a=5 let a+=2 echo "plus : $a " # a = 7 和 let a-=2 echo "minus : $a" # a = 5 差 let a*=2 echo "multi : $a" # a = 10 积 let a/=2 echo "div : $a" # a = 5 商 let a%=2 echo "Modulo : $a" # a = 1 余数

6.3 位运算符

使用较少,暂时不做更新学习。

6.4 比较运算符

6.5 逻辑运算符

7. 操作字符串

字符串是由单引号('') 或者 双引号("") 或者也可不用引号。

单引号

原样输出(变量依然原样输出)

单引号内不能再使用单引号。

双引号

如果其中使用了变量,则变量内容也会被替换。

如果再次使用引号,则使用转义符。

不用引号

性质和双引号一致,但是字符串不能有空格。

7.1 字符串的长度

直接使用 ${#string} 来计算字符串的长度

# 3 个语法格式 ${#string} # 方式 1 expr length $string # 方式 2 expr "$string" : '.*' # 方式 3 # 具体实例 str="hello world" echo "After using #str : ${#str}" echo "Use expr length : $(expr length "$str")" # 该方式不建议使用,因为shellcheck也建议使用第一种方式 echo "Use expr : $(expr "$str" : '.*')"

7.2 索引子串第一次出现的位置

# 语法格式 : expr index "$string" '$substring' # 详细实例 ---- 未进行shellcheck检查 str="SolerHO123456" echo $(expr index "$str" H) # 结果为 6

7.3 提取子串

目的:提取一些特殊需求的字符。

7.4 子串截除

7.5 子串替换

8. 数组

bash支持只支持一维数组。数组元素可使用符号 var[number] 来初始化。

脚本使用 declare -a var 语句来指定一个数组。

数组访问:通过下标的方式访问 — ${var[number]}。数组元素的下标由0开始,和C语言类似。下标可以是整数或算术表达式,其值应大于或等于0。

在数组中,${#array[*]} 和 ${#array[@]} 表示数组中元素的个数。

8.1 初始化方式

shell中使用括号来表示数组,元素之间则使用 空格符号 分隔。

# 等号两边不能空格 array_name=(element_1 element_2 ... element_N) # 声明偶数 arr_odd=(1 3 5 7 9)

8.2 获取数组中的元素

# 数组名[索引] 方式 $(array_name[index]) # 示例 echo ${arr_odd[2]}

打印数组中所有元素

${arr_odd[*]} # 建议使用该方式 ${arr_odd[@]} # 该方式在shellcheck中会无法认可,对

在数组声明时添加一个额外的 declare -a语句,可加速后续的数组操作速度。

declare -a arr_name=(...)

8.3 删除数组元素

在shell中,使用unset命令来删除数组元素。语法格式:

# 删除特定的元素 unset array_name[index] # 删除整个数组 unset array_name # 使用数组名,不写下标

8.4 二维数组

二维数组本质也是一维数组。通过 行 和 列 的寻址方式来对数组进行引用和操作。

在一维数组中由单行组成,而二维数组由连续的多行组成。

9. 分支与循环控制

双中括号[[ ... ]] 结构

在bash中,引入 [[ ... ]] 扩展测试命令。这种方式一般直接使用数学符号判断时使用。例如

if [[ "" > "" ]];then

双圆括号((...)) 结构

允许进行算术扩展和赋值。例如:a=$(( 5 + 3 ))。该风格类似于C语言风格中的变量操作处理方式。

9.1 if和if嵌套

if/then结构用来判断命令列表的退出状态码是否为0。

if单分支

语法格式:

if [ condition ];then command1 command2 ... fi # 注意不能少了fi结尾 #例如 if [ "" -gt 18 ];then echo "you are an adult" fi

if多分支

语法格式:

if [ condition ];then command1 command2 ... else command3 fi #例如 if [ "" -gt 18 ];then echo "you are an adult" else echo "You are a minor and you should study hard" fi

if嵌套

语法格式:

if [ condition1 ];then if [ condition2 ];then command1 ... fi fi

9.2 for循环

语法格式:

# [list] 是一个列表,类似list1 list2 list3 ... listN for arg in [list];do #如果do和for在同一行,则注意中间加个分号 command1 command2 ... done

具体实例:

# 方式 1 for i in {1..4};do # 类似python中使用in的方式判断 echo "This is No $i" done # 方式 2 for((i=1;i<=5;i++));do # 类似C语言风格来实现 echo "This is No $i" done

9.3 while循环语句

在循环的开头判断条件是否满足,如果条件为True,则一直循环。

while适合循环次数未知的情况。

语法格式:

while [ condition ];do command1 command2 ... done

具体实例:计算两个数字之间的和(程序很简单,是本人Test所以加了一些说明)

echo "-------This program calculates the sum of all the numbers between two numbers-------" echo "please inpput first number (need Must be less than the second number): " read a echo "Please input second number (Must be greater than the first number): " read b sum=0 while ((a <= b));do ((sum+=a)) ((a++)) done echo "the plus is : $sum"

9.4 until循环语句

在循环的顶部判断条件,如果condition为False,就进入循环,和while语句相反。

语法格式:

until condition;do # 如果condition为True,直接结束循环 command1 command2 ... done

实例:计算1~50的乘积

#程序使用C语言风格,如果使用shellcheck是会直接报错 set i=1 sum=0 until ((i>50));do ((sum+=i)) ((i++)) done echo "The puls is : $sum"

9.5 break和continue语句

直接影响循环行为的命令:break 和 continue。

和C语言的方式一致,不做过多说明。

break 直接跳出循环

continue 只跳过本次循环,忽略本次循环剩余代码,直接进入下一次循环。

9.6 case结构语句

case结构语句类似C语言中的switch语句。个人使用场景:写多个dockerfile(如ubuntu16.04、ubuntu18.04、centos7.2等)则使用一个变量控制,保证会执行的命令。

语法格式:

case arg/expression in condition_1) command_1 ;; condition_2) command_2 ;; ...... condition_N) command_N ;; *) command esac

⚠️注意:

每句测试行,都以右小括号)结尾.

每个判断语句块都以一对分号;; 结尾。

case块以 esac(case的反向拼写) 结尾。

具体实例:打印成绩评级

#已进行shellcheck检查 echo "Please input your Score : " read -r score case $score in #固定格式,判断数字,然后直接类似C语言中的goto语句 [9][0-9]|100) # 十位 和个位的组合 echo "The Level is A" ;; # 固定格式 [8][0-9]|90) echo "The Level is B" ;; [67][0-9]|80) echo "The Level is C" ;; [0-5][0-9]|[0-9]) echo "The Level is D, please pay attention it" ;; *) #固定格式 echo "The input is False" esac # 注意结尾不能少

9.7 select结构语句

select结构语句和case结构语句类似,是建立menu的一种工具。

select是从ksh中引入。

语法格式:

select arg in [list];do command_1 command_2 ...... break # 一定要使用break,否则会直接一直提示你选择内容,无法退出(只能通过ctrl+c方式进行) done

提示用户输入选择的内容(比如放在变量列表中). 注意: select命令使用PS3提示符, 默认为

(#?), 可修改。

具体实例:

#已进行shellcheck检查 PS3="Please choose the OS you are using : " #直接将提示字符串赋值给PS3变量,即可替代符号 #? select os_type in "ubuntu1604" "Ubuntu1804" "Centos8" "OpenEuler";do echo "The OS you are using : $os_type" break done exit 0

10. 函数

函数:实现一系列操作的代码块(完成特定task)。一个函数就是一个子程序。

目的:提高代码的重用性。

10.1 自定义函数

语法格式:

# 方式 1 function func_name(){ # function在shell中专门定义函数 command1 command2 ... [return value] } # 方式 2 : 简化写法 function_name(){ command1 command2 ... [return value] }

⚠️注意:

关键字function可有可无。

函数定义必须在第一次调用函数之前完成。

一个函数可以嵌套另一个函数。

不用在函数中指明参数,只需在调用时传递参数即可。

10.2 函数的调用

在shell中,调用函数时可直接使用名字即可。如果有参数,设置即可。

func_name [param_1] [param_2] ... [param_N]

具体实例:

# 最简单的例子 function print_infor(){ echo "My Name is : " echo "My Age is : " } print_infor solerho 26

10.5 系统函数

暂时未使用到,所以不做更新。

11. 字符串的显示颜色

ANSI定义了屏幕属性相关颜色输出的转义码来表示。

一般会看到打印信息中显示特殊的颜色。通过echo带颜色属性,以及参数 -e。语法格式如下:

# 方式 1 ---- 容易出现数字混乱 echo -e "3[字背景颜色;文字颜色m 字符串3[0m" # 方式 2 ---- 看起来简洁 echo -e "\e[字背景颜色;文字颜色m 字符串\e[0m"

说明:echo中 -e 是启用转义序列。其中字体或者背景等编号都会以 m 结尾。

具体实例:

# 已进行shellcheck检查 echo -e "3[30m This is Black Font 3[1m" echo -e "3[31m This is Red Font 3[1m" echo -e "3[32m This is green Font 3[1m" echo -e "3[33m This is yellow Font 3[1m" echo -e "3[34m This is Blue Font 3[1m" echo -e "3[35m This is Purple Font 3[1m" echo -e "3[36m This is Cyan Font 3[1m" echo -e "3[37m This is White Font 3[1m" echo -e "3[40m This is Black background 3[1m" echo -e "3[41m This is Red background 3[1m" echo -e "3[42m This is green background 3[1m" echo -e "3[43m This is yellow background 3[1m" echo -e "3[44m This is Blue background 3[1m" echo -e "3[45m This is Purple background 3[1m" echo -e "3[46m This is Cyan background 3[1m" echo -e "3[47m This is White background 3[1m"

打印信息如下:

更多详细情况请移步 https://misc.flogisoft.com/bash/tip_colors_and_formatting

12. I/O重定向

该部分不谈基本原理和具体实现,具体可查看 csapp 和 Linux内核中fd内容分析

shell脚本(Linux中保存log等操作也是如此)中,常用的I/O重定向相关的文件描述符(file description,简写fd)有3个:

stdin ----- 标准输入 ----- 0 ----- 键盘

stdout ----- 标准输出 ----- 1 ----- 屏幕

stderr ----- 标准错误 ----- 2 ----- 错误消息输出到屏幕上

12.1 重定向符号及功能说明

12.2 关闭文件描述符

该使用场景本人暂未遇到,但是看到一些code在使用。

12.3 代码块重定向

代码块:就是 {} 括起来的命令。例如:for循环、while循环、until循环、case语句等。

具体用法:将重定向命令符号写在代码块的结尾。具体实例:

echo "This is Code block redirect Example" echo { echo "SolerHO"; echo "shell"; echo "55" } > infor.log # 将代码块重定向输出到infor.log 文件中 { read -r name; read -r dev_lang; read -r age } < infor.log # 将infor.log重定向输入到代码块 echo "My Name is $name, The programming language being used is $dev_lang, age is $age"

13. 正则表达式

正则表达式(Regular Expression,简称regex或RE):由一系列的特殊字符组成的字符串,每个特殊字符都称为 元字符(一般解释为特定的含义)。

主要目的:用于搜索文本和字符串的操作。

一般情况下,可以通过 https://tool.oschina.net/regex/ 来验证自己写的是否可以匹配预期想要的结果。

13.1 正则表达式组成

正则表达式由普通字符和元字符(也称为通配符)组成的集合,用来查找匹配特定规则的字符文本。

一个正则表达式中,会包含以下一种或者三种:

一个字符集:只包含表示字面意义的普通字符。

锚:指定所要匹配的文本在文件中所处的位置。如 ^ 和 $ 。

修饰符:扩大或缩小匹配范围

常见的修饰符:星号(*)、括号和反斜杠(\)。

13.2 POSIX字符类 [:class:]

POSIX字符类通常都要用引号或双中括号([[ ]])引起来。

13.2 扩展RE字符

13.1 应用场景

- Linux文本处理:sed、grep、awk、cat、tail、head、tee、uniq、sort - Linux工具:vim - 其他的编程语言

详细关于正则表达式内容阅读:https://www.runoob.com/regexp/regexp-tutorial.html

14. Linux / shell中一些命令说明

更多关于Linux相关的命令,请移步目录 Linux 关注知识点笔记。

关于里面的参数选项则不做出过多解读,只增加目前使用到的,后续有使用过其他的,也会再次更新。

14.1 set/ unset命令 – 设置/取消赋值

内容只介绍在实际生产中的情况,更多的细节请阅读:https://www.computerhope.com/unix/uset.htm

在命令中直接输入 set,则显示系统中已经存在的一些shell变量。

设置新变量值

set var[n]=value set -ex var

参数选项

-e(errexit):如果命令的返回值不是0,则直接退出shll的执行。

-x():执行命令后,优先显示该命令及对应的参数。

14.2 read命令 – 从控制台读取输入

参考:https://www.computerhope.com/unix/bash/read.htm

从屏幕标准输入中读取一行。默认情况下,read将换行符作视为行的结尾。

read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...] [name2 ...]

在while循环中使用的 -r 则是直接使用原始的输入。例如

read -r name # 读取控制台输入的name值 read -r age # 读取控制前台输入的age值

14.3 declare命令 – 声明shell变量

参考链接:https://www.computerhope.com/unix/bash/declare.htm

几个功能

声明shell变量和函数

设置属性

显示值

语法:

declare [-a] [-A] [-f] [-F] [-g] [-i] [-l] [-n] [-r] [-t] [-u] [-x] [-p] [name[=value]] [name[=value]] ...

具体使用的例子:

# 数组声明中使用,可加速数组的操作速度 # shellcheck中也会无异常 declare -a arr[]=(...)

14.4 let命令 – 计算算术表达式

直接参考:https://www.computerhope.com/unix/bash/let.htm

功能:主要用于计算算术表达式。

let是Linux内置命令。而 ((...))是复合命令。

let arg [arg ...] # 和 ((...)) 直接计算算术表达式的思想类似 # 示例 let "var = 5";echo $var # 直接返回 5

14.5 expr命令 – 表达式

通用求值表达式:通过给定的操作(参数之间必须空格隔开)连接参数,并对参数求值。可使用算术、比较、字符串或逻辑操作。

expr 3 + 5 # 返回8 expr 3 \* 5 # 乘法符号需要转义,返回15

字符串操作的请查看字符串部分。

14.6 test命令 – 判断检查

直接参考:https://www.computerhope.com/unix/test.htm

检查文件类型并比较值。

# 语法 test expression # 应用 1:比较两个字符串(一般是判断字符串是否相等),比较运算符移步前面介绍部分 ---------> 比较运算符 # 应用 2:数字大小比较

15. Linux三剑客 — grep

grep ---- global regular expression print,通过正则表达式来进行多用途文本搜索,属于一个过滤器。

语法格式:

grep [OPTION]... PATTERN [FILE]... # pattern 可以是要搜索的字符串,也可以正则表达式 # 扩展命令 egrep 等价于 grep -E # 扩展命令 fgrep 等价于 grep -F

15.1 常用查找option说明

15.2 输出控制option说明

15.3 其他两个常用RE进行的grep操作

显示文件中以 “xxxx” 开头的内容,使用符号 ^

cat xxxx.sh | grep "^xxxx" # 以字符xxxx开头的内容行

示例:

显示以 “xxxx” 结尾的文件名或者文件内容行,使用符号 $

cat xxxx.sh | grep "xxxx$" # 显示以 xxxx 内容结尾的内容行

示例:

16. Linux三剑客 — sed

sed ----- stream editor,是文本处理工具。主要是查找并替换文本字符串等。

语法:

sed [OPTION]... {script-only-if-no-other-script} [input-file]...

目前常用的格式为:

sed -i 's/查找的字符串(可包含RE)/替代内容/g' filename # 如果在s/... /g 中包含单引号,则外面直接使用 双引号(""),⚠️注意中间使用一些特殊字符 sed -i "s/查找的字符串(可包含RE)/替代内容/g" filename

参数说明

i 一般是默认,可设置为其他option,具体 sed --help 查看。

s 查找

///分隔符,也可以是其他的字符。例如在Jenkins的pipeline语法中使用时(sed -i "s#search_word#target_word#g" filename)

g 表示直接全局替换 ----- global replacement。如果是需要忽略大小写时,可使用gi

几个具体的使用场景:vim命令行模式中操作和直接操作文本是相同原理

16.1 替换/修改字符串

# 全局替换(vim亦可),且忽略大小写 sed -i "s/Hello/This is/g" helloworld.sh # 将文件helloworld.sh 中 Hello替换为 This is # 指定行替换(vim亦可),区分大小写 sed "10,20 s/42m/46m/g" color_print.sh # 将color_print.sh中10~20行之间的颜色42m替换成46m

16.2 换行、删除

sed -i "s/ /\n/g" helloworld.sh # 将文件中空格全部换行(\n) sed "/\//d" helloworld.sh # 将文件中的 /所在的行直接删除(也就是#!/bin/bash)

16.3 注释

# 全局删除 sed "/^#\|^$\| *#/d" checkpip_deps.sh # 将文件中注释直接全部删除

16.4 查看指定的行范围的内容

sed -n -e "5,7p" [-e ...] font_color.sh # 查看指定范围内的内容,可使用多个 -e来指定多个行区间 sed "5,7d" font_color.sh # 查看指定范围之外的内容,可重复使用

17. Linux三剑客 — awk

awk ---- ,是报告可视化工具,文本格式化输出工具。主要处理文本文件。

17.1 语法格式

awk [-F 分隔符] '{ACTION}' filenames awk [option] '{ACTION}'

17.2 awk的原理

从第1行到最后1行,逐行去扫描文件内容,然后找到匹配pattern的行,最后进行指定的ACTION。

未指定pattern,则所有行都会被处理。

未指定ACTION,则屏幕直接打印匹配到行的内容。

18. shell脚本静态检查 — shellcheck

详细内容直接阅读:https://github.com/koalaman/shellcheck,如下为使用方式:

一文掌握shell脚本的基本语法

安装方式

# 方式 1 : 直接命令行方式安装 apt-get install shellcheck # Ubuntu # centos暂时未使用 yum install ShellCheck,建议直接使用源码方式安装 # 方式 2 : 源代码方式 wget https://github.com/koalaman/shellcheck/releases/download/v0.8.0/shellcheck-v0.8.0.linux.x86_64.tar.xz && tar -xf shellcheck-v0.8.0.linux.x86_64.tar.xz && cp shellcheck-v0.8.0/shellcheck /usr/bin/ # 查看shellcheck 版本 shellcheck --version

使用方式

直接调用shellcheck加上自己的脚本,可检测一些语法或者格式问题等。

shellcheck testop.sh

显示信息:

19. 参考资源

《高级bash脚本编程指南》

https://juejin.cn/post/6844904045329514504

https://juejin.cn/post/6962032698697187364

https://myshell-note.readthedocs.io/en/latest/index.html

https://github.com/koalaman/shellcheck

Linux Shell

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:一个牛人给JAVA初学者的建议(上篇)
下一篇:Python 中的按位运算符2 |【生长吧!Python!】 【生长吧!Python】有奖征文火热进行中:https://bbs.huaweicloud.com/blogs/278897
相关文章