您的当前位置:首页正文

Linux-Shell语法入门

2021-03-28 来源:步旅网
Linux-Shell语法⼊门Shell语法⼊门

开头

Linux 的 Shell 种类众多,常见的有:Bourne Shell(/usr/bin/sh或/bin/sh)Bourne Again Shell(/bin/bash)C Shell(/usr/bin/csh)K Shell(/usr/bin/ksh)Shell for Root(/sbin/sh)……

⼤家通常所说的Shell其实是 Bourne Again Shell,它也是⼤多数Linux 系统默认的 Shell。在⼀般情况下,⼈们并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh,它同样也可以改为 #!/bin/bash。

#! 告诉系统其后路径所指定的程序即是解释此脚本⽂件的 Shell 程序。所以Shell脚本第⼀⾏通常是:

#!/bin/bash

注释

以 # 开头的⾏就是注释,会被解释器忽略。通过每⼀⾏加⼀个 # 号设置多⾏注释,像这样:

#--------------------------------------------# 第⼀⾏# 第⼆⾏# 第三⾏# 第四⾏

#--------------------------------------------多⾏注释

:<EOF 也可以使⽤其他符号:

:<<'

注释内容...注释内容...注释内容...'

:<注释内容...注释内容...注释内容...!

变量普通变量

变量名命名规则:

命名只能使⽤英⽂字母,数字和下划线,⾸个字符不能以数字开头。中间不能有空格,可以使⽤下划线(_)。不能使⽤标点符号。

不能使⽤bash⾥的关键字(可⽤help命令查看保留关键字)。变量赋值:

变量名=值 # 注意 赋值语句两边不能有空格

赋值语句(即 “=” 号)两边不能有空格。等号右边若有空格的话,需要加上引号(单引号或双引号都是可以的)。除了显式地直接赋值,还可以⽤语句给变量赋值,如:

for file in `ls /etc`或

for file in $(ls /etc)

以上语句将 /etc 下⽬录的⽂件名循环出来。只读变量

readonly variable_name

使⽤ readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。删除变量

unset variable_name

使⽤ unset 命令可以删除变量。变量被删除后不能再次使⽤。unset 命令不能删除只读变量。使⽤变量

使⽤⼀个定义过的变量,只要在变量名前⾯加 $ 符号即可,如:

pre_name=\"Helios\"

echo \"I am ${pre_name}_Fz\"

打印结果为:\"I am Helios_Fz\"。在这⾥,如果不加 {} ,打印结果将会是 \"I am $pre_name_Fz\"。推荐给所有变量加上花括号,这是个好的编程习惯。单引号与双引号:

单引号⾥的任何字符都会原样输出,单引号字符串中的变量是⽆效的;单引号字串中不能出现单独⼀个的单引号(对单引号使⽤转义符后也不⾏),但可成对出现,作为字符串拼接使⽤。

双引号⾥可以有变量。双引号⾥可以出现转义字符。获取字符串长度:

string=\"abcd\"

echo ${#string} #输出 4

提取⼦字符串:以下实例从字符串第 2 个字符开始截取 4 个字符:

string=\"runoob is a great site\"

echo ${string:1:4} # 输出 unoo

注意:第⼀个字符的索引值为 0。

查找⼦字符串:查找字符 i 或 o 的位置(哪个字母先出现就计算哪个):

string=\"runoob is a great site\"

echo `expr index \"$string\" io` # 输出 4

Shell传递参数

创建 test.sh ⽂件,内容如下:

m=$1n=$2

echo $m-$n

执⾏命令:“sh test.sh aaa bbb”;输出 aaa-bbb位置参数变量:

参数$1、$2...$*

说明

脚本程序的参数,分别代表程序的第1个参数、第2个参数、... 程序第10个以上的参数需要⽤⼤括号包含,如 ${10}

代表命令⾏中的所有参数。在⼀个变量中将所有参数列出,各参数之间⽤环境变量 IFS 中的第⼀个字符分隔开。

和 $* ⼀样,也包含了命令⾏中的所有参数,但是不使⽤ IFS 环境变量,即使 IFS 为空,参数也是分开显⽰的。

如\"$@\"⽤ \"\" 括起来的情况、以\"$1\" \"$2\" … \"$n\" 的形式输出所有参数。后台运⾏的最后⼀个进程的ID号脚本运⾏的当前进程ID号

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

$@$!$$$?

$* 与 $@ 区别:

相同点:都是引⽤所有参数。

不同点:只有在双引号中体现出来。假设在脚本运⾏时写了三个参数 1、2、3,,则 \" * \" 等价于 \"1 2 3\"(传递了⼀个参数),⽽ \"@\" 等价于 \"1\" \"2\" \"3\"(传递了三个参数)。

echo \"-- \\$* 演⽰ ---\"for i in \"$*\"; do echo $idone

echo \"-- \\$@ 演⽰ ---\"for i in \"$@\"; do echo $idone

执⾏脚本,输出结果如下所⽰:

$ chmod +x test.sh $ ./test.sh 1 2 3-- $* 演⽰ ---1 2 3

-- $@ 演⽰ ---123

基本运算符算数运算符

原⽣bash不⽀持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr。其中expr 最常⽤。expr 是⼀款表达式计算⼯具,使⽤它能完成表达式的求值操作。例如,两个数相加(注意使⽤的是反引号 ` ⽽不是单引号 '):

#!/bin/bash

val=`expr 2 + 2`

echo \"两数之和为 : $val\"

输出:“两数之和为 : 4”。注意:

表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的⼤多数编程语⾔不⼀样。完整的表达式要被 ` ` 包含,注意这个字符不是常⽤的单引号,在 Esc 键下边。关系运算符

运算符+-*/%

加法减法乘法除法取余

说明举例

`expr $a + $b``expr $a - $b``expr $a \\* $b``expr $b / $a``expr $b % $a`

===!=

赋值

相等。⽤于⽐较两个数字,相同则返回 true。

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

不相等。⽤于⽐较两个数字,不相同则返回 true。[ $a != $b ]

注意:条件表达式要放在⽅括号之间,并且要有空格,例如: [$a==$b] 是错误的,必须写成 [ $a == $b ]。布尔运算符

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

运算符-eq-ne-gt-lt-ge-le运算符&&||运算符=!=-z-n$操作符

说明

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

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

举例[ $a -eq $b ] [ $a -ne $b ] [ $a -gt $b ] [ $a -lt $b ]

检测左边的数是否⼤于等于右边的,如果是,则返回 true。[ $a -ge $b ] 检测左边的数是否⼩于等于右边的,如果是,则返回 true。[ $a -le $b ]

说明逻辑的 AND逻辑的 OR

举例

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

只有左边的“命令”执⾏成功,右边的“命令”才会被执⾏。[[ $a -lt 100 || $b -gt 100 ]] 返回 true。

如果左边的“命令”未执⾏成功,就执⾏右边的“命令”。

说明

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

举例[ $a = $b ] [ $a != $b ] [ -z $a ]

逻辑运算符

字符串运算符

检测字符串长度是否不为 0,不为 0 返回 true。[ -n \"$a\" ] 检测字符串是否为空,不为空返回 true。

说明

[ $a ]

举例[ -b $file ] [ -c $file ] [ -d $file ]

⽂件测试运算符

-b file检测⽂件是否是块设备⽂件,如果是,则返回 true。-c file检测⽂件是否是字符设备⽂件,如果是,则返回 true。-d file检测⽂件是否是⽬录,如果是,则返回 true。-f file

检测⽂件是否是普通⽂件(既不是⽬录,也不是设备⽂件),如果是,则返回 true。[ -f $file ]

[ -g $file ] [ -k $file ] [ -p $file ] [ -u $file ] [ -r $file ] [ -w $file ] [ -x $file ] [ -s $file ] [ -e $file ]

-g file检测⽂件是否设置了 SGID 位,如果是,则返回 true。-k file检测⽂件是否设置了粘着位(Sticky Bit),如果是,则返回 true。-p file检测⽂件是否是有名管道,如果是,则返回 true。-u file检测⽂件是否设置了 SUID 位,如果是,则返回 true。-r file

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

-w file检测⽂件是否可写,如果是,则返回 true。-x file检测⽂件是否可执⾏,如果是,则返回 true。

-s file检测⽂件是否为空(⽂件⼤⼩是否⼤于0),不为空返回 true。-e file检测⽂件(包括⽬录)是否存在,如果是,则返回 true。

流程控制语句if-else

if condition1then

statements1elif condition2then

statements2else

statements3fi

for for 循环将会遍历整个对象列表,依次执⾏每⼀个独⽴对象的循环内容。对象可以是命令⾏参数、⽂件名或是任何可以以列表形式建⽴的东西。其语法如下:

for variable in values

do

statementsdone

case每个 case 分⽀⽤右圆括号开始,⽤两个分号 ;; 表⽰ break,即执⾏结束,跳出整个 case ... esac 语句,esac(就是 case 反过来)作为结束标记。

case variable in

pattern [ | pattern ] ... ) statements;; pattern [ | pattern ] ... ) statements;; ...esac

whilewhile conditiondo

commanddone

while循环可⽤于读取键盘信息。下⾯的例⼦中,输⼊信息被设置为变量FILM,按结束循环。

echo '按下 退出'echo -n '输⼊: 'while read FILMdo

echo \"输出: $FILM \"done

输出:

按下 退出输⼊: 1输出: 1

⽆限循环:

while :do

commanddone或

while truedo

commanddone

untiluntil 循环执⾏⼀系列命令直⾄条件为 true 时停⽌。until 循环与 while 循环在处理⽅式上刚好相反。

⼀般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有⽤。until 语法格式:

until conditiondo

commanddone

跳出循环break命令

break命令允许跳出所有循环(终⽌执⾏后⾯的所有循环)。continue

continue命令与break命令类似,只有⼀点差别,它不会跳出所有循环,仅仅跳出当前循环。函数

shell中函数的定义格式如下:

[ function ] funname [()]{

action; [return int;]}

不带返回例⼦:

#!/bin/bash

demoFun(){

echo \"这是⼀个 shell 函数!\"}

echo \"-----函数开始执⾏-----\"demoFun

echo \"-----函数执⾏完毕-----\"

结果:

-----函数开始执⾏-----这是⼀个 shell 函数!-----函数执⾏完毕-----

带返回例⼦:

#!/bin/bash

funWithReturn(){

echo \"输⼊第⼀个数字: \" read aNum

echo \"输⼊第⼆个数字: \" read bNum

echo \"两个数字分别为 $aNum 和 $bNum !\" return $(($aNum+$bNum))}

funWithReturn

echo \"输⼊的两个数字之和为 $? !\"

结果:

输⼊第⼀个数字: 1

输⼊第⼆个数字: 2

两个数字分别为 1 和 2 !输⼊的两个数字之和为 3 !

函数返回值在调⽤该函数后通过 $? 来获得。

注意:所有函数在使⽤前必须定义。这意味着必须将函数放在脚本开始部分,直⾄shell解释器⾸次发现它时,才可以使⽤。调⽤函数仅使⽤其函数名即可。输⼊/输出重定向

⼤多数 UNIX 系统命令从终端接受输⼊并将所产⽣的输出发送回到终端。⼀个命令通常从⼀个叫标准输⼊的地⽅读取输⼊,将其输出写⼊到标准输出,默认情况下,标准输⼊和标准输出都是终端。⽂件描述符:

0 通常是标准输⼊ STDIN1 是标准输出 STDOUT

2 是标准错误输出 STDERR 重定向命令列表:

命令command > filecommand < file

将输出重定向到 file。将输⼊重定向到 file。

说明

command >> file将输出以追加的⽅式重定向到 file。n > filen >> filen >& mn <& m<< tag

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

将⽂件描述符为 n 的⽂件以追加的⽅式重定向到 file。将输出⽂件 m 和 n 合并。将输⼊⽂件 m 和 n 合并。

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

/dev/null

/dev/null 称做空设备,是⼀个特殊的设备⽂件,它丢弃⼀切写⼊其中的数据,读取它则会⽴即得到⼀个EOF。空设备通常被⽤于丢弃不需要的输出流,

command > /dev/null

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

$ command > /dev/null 2>&1

这⾥的 2 和 > 之间不可以有空格,2> 是⼀体的时候才表⽰错误输出。⽂件引⽤

Shell ⽂件引⽤的语法格式如下:

. filename # 注意点号(.)和⽂件名中间有⼀空格或

source filename

例⼦:test1.sh

#!/bin/bashstr=\"测试输出\"

test2.sh

#!/bin/bash. ./test1.sh

# source ./test1.shecho \"$str\"

执⾏test2.sh输出:

测试输出

注意:被包含的⽂件 test1.sh 不需要可执⾏权限。

因篇幅问题不能全部显示,请点此查看更多更全内容