欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

linux shell编程之单引号,双引号和反引号的区别的区别、printf命令、退出码等讲解

程序员文章站 2022-10-16 10:02:43
一.单引号,双引号和反引号的区别的区别: 1.单引号 ·由单引号括起来的字符都作为普通字符出现。特殊字符用单引号括起来以后,也会失去原有意义,而只作为普通字符解释。 &mi...

一.单引号,双引号和反引号的区别的区别:

1.单引号

·由单引号括起来的字符都作为普通字符出现。特殊字符用单引号括起来以后,也会失去原有意义,而只作为普通字符解释。

·单引号字串中不能出现单引号(对单引号使用转义符后也不行)。

2.双引号

·双引号里可以有变量

·双引号里可以出现转义字符

3.反引号

·``括起来的字符串被shell解释为命令行,在执行时,shell首先执行该命令行,并以它的标准输出结果取代整个反引号(包括两个反引号)部分。

linux shell编程之单引号,双引号和反引号的区别的区别、printf命令、退出码等讲解

·反引号还可以嵌套使用。但需注意,嵌套使用时内层的反引号必须用反斜杠(\)将其转义。

·反引号内部是一个独立的bash session,其声明的变量只有在内部有效.

linux shell编程之单引号,双引号和反引号的区别的区别、printf命令、退出码等讲解

·反引号是一个老的用法,$()才是新的用法,如例程中的$(seq 10)。无论是在学习中,还是在实际工作中,$()都是被推荐的用法。

linux shell编程之单引号,双引号和反引号的区别的区别、printf命令、退出码等讲解

二.printf命令

printf 命令模仿 C 程序库(library)里的 printf() 程序。printf 由 POSIX 标准所定义,因此使用 printf 的脚本比使用 echo 移植性好。

printf 命令的语法: printf format-string [arguments...]

linux shell编程之单引号,双引号和反引号的区别的区别、printf命令、退出码等讲解

三.退出码

shell中运行的每个命令都使用退出状态码(exit status)来告诉shell它完成了处理。退出状态码是一个0~255之间的整数值,在命令结束时由命令传回shell。

1 查看退出状态码

Linux提供了$专属变量保存上一个执行的命令的退出状态码。你可以在你运行一个命令之后查看(echo $)。

几个典型的退出状态码及其意义:

0----------------命令运行成功

1----------------通知未知错误

2----------------误用shell命令

126-------------命令不可执行

127-------------没有找到命令

128-------------无效退出参数

128+x-----------linux信号x的严重错误

130--------------命令通过Ctrl+C终止

255--------------退出状态码越界

2 exit命令

用于shell 脚本中指定退出状态码。

四.各种括号的作用()、(())、[]、[[]]、{}

1.单小括号()

(1)命令组。括号中的命令将会新开一个子shell顺序执行。

linux shell编程之单引号,双引号和反引号的区别的区别、printf命令、退出码等讲解

(2)与$配合使用,$(cmd)等价于`cmd`

(3)用于初始化数组。如:array=(a b c d)

2.双小括号(())

注意:只能用于整数运算或者比较,不能用于文件测试/字符串运算等场合。

(1)整数扩展。((exp))结构扩展并计算一个算术表达式的值,此计算是整数型的计算,不支持浮点型计算。如果表达式的结果为0,那么返回的退出状态码为1,或者是"false"。如果,表达式的结果为非0,那么返回的退出状态码将为0,或者是"true"。若是逻辑判断,表达式exp为真则为1,假则为0。

linux shell编程之单引号,双引号和反引号的区别的区别、printf命令、退出码等讲解

(2)只要括号中的运算符、表达式符合C语言运算规则,都可用在$((exp))中,甚至是三目运算符。作不同进位(如二进制、八进制、十六进制)运算时,输出结果全都自动转化成了十进制。如:echo $((16#5f)) 结果为95 (16进位转十进制)

(3)常用于算术运算比较,双括号中的变量可以不使用$符号前缀。括号内支持多个表达式用逗号分开。 只要括号中的表达式符合C语言运算规则,比如可以直接使用for((i=0;i<5;i++)), 如果不使用双括号, 则为for i in `seq 0 4`或者for i in {0..4}。再如可以直接使用if (($i<5)), 如果不使用双括号, 则为if [ $i -lt 5 ]。

linux shell编程之单引号,双引号和反引号的区别的区别、printf命令、退出码等讲解

(4)如果要 把双小括号的运算结果返回给shell中的变量则需要在双小括号前面加入$

linux shell编程之单引号,双引号和反引号的区别的区别、printf命令、退出码等讲解

(5) 只有在双小括号中才可直接使用变量,其他括号符中都需要使用$来引用变量。

3.单中括号[ ]

(1)shell的运算符都可以用单中括号[]来表示。

(2)bash 的内部命令,[和test是等同的。

(3)条件表达式要放在方括号之间,并且变量与括号之间,及变量与运算符之间都要有空格,例如:[$a==$b]是错误的,必须写成

[ $a == $b ]。

(4)[ ]中不可以使用&& || > < 等操作符号,需要使用[[ ]]来表示。

(5)在一个array 结构的上下文中,中括号用来引用数组中每个元素的编号。

4.双中括号[[ ]]

注意:不能用于数字运算或数字比较。

(1)支持字符串的模式匹配,使用=~操作符时甚至支持shell的正则表达式。字符串比较时可以把右边的作为一个模式,而不仅仅是一个字符串,比如[[ hello == hell ]],结果为真。[[ ]] 中匹配字符串或通配符,不需要引号。

(2)使用[[ ... ]]条件判断结构,而不是[ ... ],能够防止脚本中的许多逻辑错误。比如,&&、||、<和> 操作符能够正常存在于[[ ]]条件判断结构中,但是如果出现在[ ]结构中的话,会报错。比如可以直接使用if [[ $a != 1 && $a != 2 ]], 如果不适用双括号, 则为if [ $a -ne 1] && [ $a != 2 ]或者if [ $a -ne 1 -a $a != 2 ]。

(3)bash把双中括号中的表达式看作一个单独的元素,并返回一个退出状态码。

(4)双中括号中可以使用&& || > < 等操作符号,但是在[ ]中是不允许的,所有的操作符号和变量或者常量间必须要有空格否则会报错。

五.花括号{ }

1.大括号拓展.对大括号内的文件名做扩展。在大括号中,不允许有空白,除非这个空白被引用或转义。

第一种:对大括号中的以逗号分割的文件列表进行拓展。如 touch {a,b}.txt 结果为a.txt b.txt。第二种:对大括号中以点点(..)分割的顺序文件列表起拓展作用,如:touch {a..d}.txt 结果为a.txt b.txt c.txt d.txt

2.几种特殊的替换结构

${var:-string},${var:+string},${var:=string},${var:string}

(1)${var:-string}和${var:=string}:若变量var为空,则用在命令行中用string来替换${var:-string},否则变量var不为空时,则用变量var的值来替换${var:-string};对于${var:=string}的替换规则和${var:-string}是一样的,所不同之处是${var:=string}若var为空时,用string替换${var:=string}的同时,把string赋给变量var: ${var:=string}很常用的一种用法是,判断某个变量是否赋值,没有的话则给它赋上一个默认值。

(2) ${var:+string}的替换规则和上面的相反,即只有当var不是空的时候才替换成string,若var为空时则不替换或者说是替换成变量 var的值,即空值。(因为变量var此时为空,所以这两种说法是等价的)

(3) ${var:string}替换规则为:若变量var不为空,则用变量var的值来替换${var:string};若变量var为空,则把string输出到标准错误中,并从脚本中退出。我们可利用此特性来检查是否设置了变量的值。

补充扩展:在上面这五种替换结构中string不一定是常值的,可用另外一个变量的值或是一种命令的输出。

六.字符串提取

${var:num},${var:num1:num2},${var/pattern/pattern},${var//pattern/pattern}

第一种模式:${var:num},这种模式时,shell在var中提取第num个字符到末尾的所有字符。若num为正数,从左边0处开始;若num为负数,从右边开始提取字串,但必须使用在冒号后面加空格或一个数字或整个num加上括号,如${var: -2}、${var:1-3}或${var:(-2)}。

第二种模式:${var:num1:num2},num1是位置,num2是长度。表示从$var字符串的第$num1个位置开始提取长度为$num2的子串。不能为负数。

第三种模式:${var/pattern/pattern}表示将var字符串的第一个匹配的pattern替换为另一个pattern。

第四种模式:${var//pattern/pattern}表示将var字符串中的所有能匹配的pattern替换为另一个pattern。

七.shell数组

1. 数组元素定义用空格分隔,而不是逗号。如:array_string=(123 124 2345)。

2. 输出数组元素,采用 ${数组名[下标]} 格式,下标默认从0开始。如果直接输出数组名则默认于 ${数组名[0]}等价。如果要输出所有的元素,则采用“@”或“*”替代下标,即 ${数组名[@]}

八.运算符

l算数运算符

l关系运算符

l布尔运算符

l字符串运算符

l文件测试运算符

1.算术运算符

注意:

(1)条件表达式要放在方括号之间,并且要有空格,例如:[$a==$b]是错误的,必须写成

[ $a == $b ]。

(2)乘号(*)前边必须加反斜杠(\)才能实现乘法运算。

2.关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

运算符

说明

举例

+

加法

`expr $a + $b` 结果为30。

-

减法

`expr $a - $b` 结果为 -10。

*

乘法

`expr $a \* $b` 结果为 200。

/

除法

`expr $b / $a` 结果为2。

%

取余

`expr $b % $a` 结果为0。

=

赋值

a=$b 将把变量 b 的值赋给 a。

==

相等。用于比较两个数字,相同则返回 true。

[ $a == $b ] 返回false。

!=

不相等。用于比较两个数字,不相同则返回 true。

[ $a != $b ] 返回 true。

3.布尔运算符

运算符

说明

举例

-eq

检测两个数是否相等,相等返回 true。

[ $a -eq $b ] 返回false。

-ne

检测两个数是否相等,不相等返回 true。

[ $a -ne $b ] 返回 true。

-gt

检测左边的数是否大于右边的,如果是,则返回 true。

[ $a -gt $b ] 返回 false。

-lt

检测左边的数是否小于右边的,如果是,则返回 true。

[ $a -lt $b ] 返回 true。

-ge

检测左边的数是否大于等于右边的,如果是,则返回 true。

[ $a -ge $b ] 返回 false。

-le

检测左边的数是否小于等于右边的,如果是,则返回 true。

[ $a -le $b ] 返回 true。

4.逻辑运算符

运算符

说明

举例

!

非运算,表达式为 true 则返回 false,否则返回 true。

[ ! false ] 返回 true。

-o

或运算,有一个表达式为 true 则返回 true。

[ $a -lt 20 -o $b -gt 100 ] 返回true。

-a

与运算,两个表达式都为 true 才返回 true。

[ $a -lt 20 -a $b -gt 100 ] 返回false。

5.字符串运算符

下表列出了常用的字符串运算符,假定变量 a 为 "abc",变量 b 为 "efg":

运算符

说明

举例

&&

逻辑的 AND

[[ $a -lt 100 && $b -gt 100 ]] 返回 false

||

逻辑的 OR

[[ $a -lt 100 || $b -gt 100 ]] 返回 true

6.文件测试运算符

文件测试运算符用于检测 Unix 文件的各种属性。

属性检测描述如下:

运算符

说明

举例

=

检测两个字符串是否相等,相等返回 true。

[ $a = $b ] 返回 false。

!=

检测两个字符串是否相等,不相等返回 true。

[ $a != $b ] 返回true。

-z

检测字符串长度是否为0,为0返回 true。

[ -z $a ] 返回 false。

-n

检测字符串长度是否为0,不为0返回 true。

[ -n $a ] 返回 true。

str

检测字符串是否为空,不为空返回 true。

[ $a ] 返回true。

九.test命令

Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。

1.数值测试

操作符

说明

举例

-b file

检测文件是否是块设备文件,如果是,则返回 true。

[ -b $file ] 返回 false。

-c file

检测文件是否是字符设备文件,如果是,则返回 true。

[ -c $file ] 返回false。

-d file

检测文件是否是目录,如果是,则返回 true。

[ -d $file ] 返回 false。

-f file

检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。

[ -f $file ] 返回true。

-g file

检测文件是否设置了 SGID 位,如果是,则返回 true。

[ -g $file ] 返回false。

-k file

检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。

[ -k $file ] 返回false。

-p file

检测文件是否是有名管道,如果是,则返回 true。

[ -p $file ] 返回false。

-u file

检测文件是否设置了 SUID 位,如果是,则返回 true。

[ -u $file ] 返回false。

-r file

检测文件是否可读,如果是,则返回 true。

[ -r $file ] 返回true。

-w file

检测文件是否可写,如果是,则返回 true。

[ -w $file ] 返回true。

-x file

检测文件是否可执行,如果是,则返回 true。

[ -x $file ] 返回true。

-s file

检测文件是否为空(文件大小是否大于0),不为空返回 true。

[ -s $file ] 返回true。

-e file

检测文件(包括目录)是否存在,如果是,则返回 true。

[ -e $file ] 返回true。

num1=100

num2=100

iftest $[num1]-eq $[num2]

then

echo '两个数相等!'else

echo '两个数不相等!'

fi

2.字符串测试

参数

说明

-eq

等于则为真

-ne

不等于则为真

-gt

大于则为真

-ge

大于等于则为真

-lt

小于则为真

-le

小于等于则为真

3.文件测试

参数

说明

=

等于则为真

!=

不相等则为真

-z 字符串

字符串的长度为零则为真

-n 字符串

字符串的长度不为零则为真

iftest -e ./bash

then

echo '文件已存在!'

else

echo '文件不存在!'

fi

4.与或非

Shell还提供了与( -a )、或( -o )、非( ! )三个逻辑操作符用于将测试条件连接起来,其优先级为:"!"最高,"-a"次之,"-o"最低。

iftest -e ./notFile -o -e ./bash

then

echo '至少有一个文件存在!'

else

echo '两个文件都不存在'

fi

十.函数

[ function ] funname [()]

{

action;

[return int;]

}

1. 可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。

2. 参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)

3. 函数返回值在调用该函数后通过 $ 来获得。

4.所有函数在使用前必须定义。

5.函数参数:

在Shell中,定义函数无需定义形参,在调用函数时,直接传入实参即可。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数...当n>=10时,需要使用${n}来获取参数,不能直接写$10。

参数

说明

-e 文件名

如果文件存在则为真

-r 文件名

如果文件存在且可读则为真

-w 文件名

如果文件存在且可写则为真

-x 文件名

如果文件存在且可执行则为真

-s 文件名

如果文件存在且至少有一个字符则为真

-d 文件名

如果文件存在且为目录则为真

-f 文件名

如果文件存在且为普通文件则为真

-c 文件名

如果文件存在且为字符型特殊文件则为真

-b 文件名

如果文件存在且为块特殊文件则为真

linux shell编程之单引号,双引号和反引号的区别的区别、printf命令、退出码等讲解

十一.输入/输出重定向

参数处理

说明

$#

传递到脚本的参数个数

$*

以一个单字符串显示所有向脚本传递的参数

$$

脚本运行的当前进程ID号

$!

后台运行的最后一个进程的ID号

$@

与$*相同,但是使用时加引号,并在引号中返回每个参数。

$-

显示Shell使用的当前选项,与set命令功能相同。

$

显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

1.同时使用输入/输出重定向。

command1 < infile > outfile

同时替换输入和输出,执行command1,从文件infile读取内容,然后将输出写入到outfile中。

2.重定向深入讲解

一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:

标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。

标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。

标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。

默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。

实例1:如果希望 stderr 重定向到 file,可以这样写:

$ command 2 > file

实例2:如果希望 stderr 追加到 file 文件末尾,可以这样写:

$ command 2 >> file

实例3:如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:

$ command > file 2>&1

或者

$ command >> file 2>&1

3. Here Document

(1)语法

command << delimiter

document

delimiter

它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。

注意:

结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。

开始的delimiter前后的空格会被忽略掉。

delimiter是一个自定义标识符,只要保证前后一致即可。

linux shell编程之单引号,双引号和反引号的区别的区别、printf命令、退出码等讲解

4./dev/null 文件

/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。

如果希望屏蔽 stdout 和 stderr,可以这样写:

$ command > /dev/null 2>&1

十二.shell文件包含

1.语法

. filename # 注意点号(.)和文件名中间有一空格

source filename

2.实例

test2.sh代码:

#!/bin/bash

#使用 . 号来引用test1.sh 文件. 或者使用以下包含文件代码source ./test1.sh

./test1.sh

echo "菜鸟教程官网地址:$url"

注:被包含的文件 test1.sh 不需要可执行权限。

命令

说明

command > file

将输出重定向到 file。

command < file

将输入重定向到 file。

command >> file

将输出以追加的方式重定向到 file。

n > file

将文件描述符为 n 的文件重定向到 file。

n >> file

将文件描述符为 n 的文件以追加的方式重定向到 file。

n >& m

将输出文件 m 和 n 合并。

n <& m

将输入文件 m 和 n 合并。

<< tag

将开始标记 tag 和结束标记 tag 之间的内容作为输入。