Shell中的特殊符号(specialcharacters)和含义
之前写过两篇关于Bash语法的blog,分别是:
个⼈感觉,想要通畅地读懂bash脚本,还差⼀个部分,那就是符号。
个⼈⽹上的讲bash符号的⽂章有点乱,要么有错,要么不全,要么太深,看了也感觉⽤不上。很多英⽂的⽂章写的好,写的深,但是查阅起
来不⽅便。于是,⼲脆我⾃⼰写⼀篇吧,不说我这篇写的有多好,起码名称中英⽂有个对应,有⼀些⾃⼰动⼿运⾏验证过了的⼩例⼦,很多
技术细节我也注明了出处。将来如果有对细节进⼀步的查阅的需要,可以从这⾥开始。
#井号(crosshatch/sharp/hash)
1.井号开头的语句被视为代码的注释,不会被执⾏。
2.在#!/bin/bash中,脚本⽂件开头⾸⾏的#!会告诉系统这个⽂件是⼀系列命令的集合,应该被发送给#!后⾯指定的解释器来执⾏。⼤概
都有哪些解释器呢?如下:
#!/bin/sh:ExecutesthescriptusingtheBourneshelloracompatibleshell,withpath/bin/sh
#!/bin/bash:ExecutesthescriptusingtheBashshell.
#!/bin/csh-f:ExecutesthescriptusingCshelloracompatibleshell.
#!/usr/bin/perl-T:Executesthescriptusingperlwiththeoptionoftaintchecks
#!/usr/bin/envpython:Executesthescriptusingpythonbylookingupthepathtothepythoninterpreterautomaticallyfromthe
environmentvariables
~波浪号(tilde)
Bash提供了⼀些⽤~开头的变量,这些变量的展开叫做TildeExpansions,也就是将这些缩写转换成它们代表的⽬录名称的过程。
1.与$HOME⼀样,代表当前⽤户的homedirectory.
2.~urname,代表其他某⽤户的homedirectory.
3.~+,代表当前的⼯作⽬录,与$PWD⼀样。
4.~-,代表上⼀个⼯作⽬录,与$OLDPWD⼀样。
5.~1,~2,~-1,~-0分别代表⽬录栈中的编号为1的,编号为2的,编号为倒数第2的,倒数第⼀的⽬录。相当于‘dirs+1’,‘dirs+2’,‘dirs-
1’,‘dirs–0’.
下⾯展⽰了⼀个例⼦。关于操作⽬录栈的具体内容,请看。
;分号(micolon)
分号⽤来分隔两个命令,⽐如命令echoa;echob就是告诉bash,echoa和echob是两个不同的命令,需要⼀个接⼀个地分开运⾏。参
考。
;;双分号(doublemicolon)
双分号;;仅⽤在ca结构中,标志⼀个选项的结束,类似于C语⾔中的break。
1
2
3
4
ca$answerin
yes)echo'yay!';;
no)echo'boo!';;
esac
.点号(dot)
⼀个dot代表当前⽬录,两个dot代表上层⽬录。如果档案名称以dot开头,该档案就属特殊档案,⽤ls指令必须加上-a选项才会显⽰。除
此之外,在regularexpression中,⼀个dot代表匹配⼀个字元。
‘string'单引号(singlequote)
被单引号⽤括住的内容,将被视为单⼀字串。在引号内的代表变量的$符号,没有作⽤,也就是说,$符号被视为⼀般符号处理,防⽌任何变
量替换。
“string”双引号(doublequote)
被双引号⽤括住的内容,将被视为单⼀字串。它防⽌通配符扩展,但允许变量扩展。这点与单引数的处理⽅式不同。
`command`反引号(backtick)
反引号不是⼀种引号,它有特殊的意义。任何被反引号括起来的东西都会在主命令执⾏之前先被shell求值(或执⾏),并且反引号括起来的
东西的求值(或执⾏)的输出会被主命令使⽤到。
在前⾯的单双引号,括住的是字串,但如果该字串是⼀列命令列,会怎样?命令会执⾏么?
答案是不会执⾏。要处理这种情况,我们得⽤反引号。
在反引号内的date+%F会被视为指令,执⾏的结果会带⼊$fdv变量中。
下⾯的例⼦⾥,先创建⼀个名为lucky的ur,可以看到他的uid为1001.
查看当前⽤户的信息,名为yunlong的⽤户的uid为1000.可以看到/home/lucky是lucky⽤户的homedirectory,owner是lucky。
然后,我们利⽤命令chown`id-u`/home/lucky,把/home/lucky的owner换成了yunlong。注意这⾥对于反引号的使⽤。
关于反引号的更多信息,看。
,逗号(comma)
逗号可以有下⾯这些⽤途:
1.括号扩展(braceexpansion)
tee命令的作⽤是从标准输⼊读取(standardinput)之后,将读取来的信息同时写⼊标准输出(standardoutput)和⼀个或多个⽂件中。详情
见。
2.在let语句中,或者在与其作⽤等价的(())构造中分隔算数操作。
3.可以在for语句中,分隔不同的index变量,避免在for循环体中进⾏操作。
4.逗号还可以⽤在Bash4中,把字符串变成⼩写。
关于逗号在bash中的⽤途,原⽂看。
/斜杠(forwardslash)
在路径表⽰时,斜杠代表⽬录。通常单⼀的斜杠/代表root根⽬录的意思;在四则运算中,斜杠代表除法的符号。
反斜杠(backslash/escape)
在交互模式下的escape符号,有⼏个作⽤:
1.放在指令前,有取消alias的作⽤;
#typerm
rmisaliadto`rm-i'
#rm.*.log
上例,作者在rm指令前加上escape字符,作⽤是暂时取消别名的功能,将rm指令还原。
2.转义字符,放在特殊符号前,则该特殊符号的作⽤消失;
3.放在指令的最末端,表⽰指令连接下⼀⾏。
|竖线bar/pipe/verticalbar
pipeline是UNIX系统,基础且重要的观念。连结上个指令的标准输出,做为下个指令的标准输⼊。
善⽤这个观念,对精简script有相当的帮助。
!叹号exclamationmark/bang
通常它代表反逻辑的作⽤,譬如条件侦测中,⽤!=来代表”不等于”
#if["$?"!=0];thenecho“Executerror”;elifthenecho"Executessuccessfully";fi;
这个例⼦⾥,除了展⽰了叹号的⽤法,还包含了如何把if语句写在⼀⾏⾥的⽅法,还有⼀个利⽤上⾯讲过的反斜杠把⼀个⼀⾏的if语句写成多
⾏的⽅法。
在正则表达式⾥,可以使⽤!字符在正则表达式之前对其求反。也就是说,仅当字符串与表达式的其余部分不匹配时,才认为字符串已匹配。
注意,⽹上的很多名为《shell脚本中⼀些特殊符号》的⽂章⾥,在讲叹号是给出的例⼦⾥使⽤叹号是不正确的。
应该使⽤^符号,来对字符范围取反。如下:
:冒号colon
在bash中,这是⼀个内建指令,这个指令”什么事都不⼲(no-op)”,但返回状态值0(Bash⾥返回值为0表⽰正常执⾏结束,⾮0表⽰出了问
题)。
⽐如,if语句利⽤上冒号可以写成这样:
#if["$?"!=0];then:;elecho"Executesuccessfully";fi
关于冒号在Bash中的应⽤,具体可以看。
问号(questionmark)
在⽂件名的匹配中,⽤作单字符的通配符。注意,问号代表的是只有⼀个字符的通配符,数字和字母都可以匹配。
*星号(asterisk/star)
星号是bash中的任意字符序列通配符,包括没有字符的情况都可以匹配。
**双星号(double-asterisk)
双星号(**)在多个段中尝试匹配零个或多个字符,它⽤于对嵌套⽬录中的⽂件进⾏通配。
举例:
Tests/**/*.js
这⾥,匹配的⽂件被限制在Test⽬录中。会被匹配的⽂件包括Tests/,Tests/UI/,Tests/UI/Feature1/
更多信息,看。
另⼀个就是幂运算。
$美元符号(dollarsign)
变量替换(VariableSubstitution)的代表符号。⼀个变量名字前⾯带上美元符号,表明这是个变量。可以⽤美元符带上这个变量的名字对其进
⾏引⽤。
另外,在RegularExpressions⾥被定义为匹配⾏尾(end-of-line)。
还有很多其他特殊变量是⽤美元符号开头的,参考。
${}变量扩展(variablesubstitution)
${}⽤于变量替换。⼀般情况下,$var与${var}并没有啥不⼀样。但是⽤${}会⽐较精确的界定变量名称的范围。
$AB=string0
$A=string1
$echo$AB
string0
#原本是打算先将$A的结果替换出来,然后再补⼀个B字母于其后.
#但在命令⾏上,真正的结果却是只会提换变量名称为AB的值出来…
#若使⽤${}就没问题了:
$echo${A}B
string1B
详情看和。
$()命令替换(commandsubstitution,与⼀对反引号相同)
在bashshell中,$()与``(反引号)都是⽤来做命令替换⽤(commandsubstitution)的。
例如version=$(uname-r)和version=`uname-r`都可以是version得到内核的版本号。
1.反引号的命令替换基本上可在全部的unixshell中使⽤,若写成shellscript,其移植性⽐较⾼。但是,反引号容易打错或看错。
2.$()并不是所有shell都⽀持。
$(())和$[]算数扩展(arithmeticexpansion)
它们是⼀样的,都是进⾏数学运算的。⽀持+-*/%:分别为“加、减、乘、除、取模”。但是注意,bash只能作整数运算,对于浮点数是当
作字符串处理的。
⼆者的区别是$[]已经是淘汰的,弃⽤的语法了,现在已经完全被$(())替代了。
()⼩括号(parenthes)指令群组(commandgroup)
⼩括号之内的⼀系列命令,会在⼀个新创建的subshell中执⾏。由于⼩括号内的命令是在subshell中执⾏的,所以其内部的变量赋值在执⾏
之后不会持续。
Placingalistofcommandsbetweenparenthescausasubshellenvironmenttobecreated(e),andeachofthe
helistixecutedinasubshell,variableassignmentsdonotremain
ineffectafterthesubshellcompletes.
{}花括号(braces)指令群组(commandgroup)
花括号之内的⼀系列指令会在当前的shell的上下⽂中执⾏。不会创建subshell。列表之后的分号(或者换⾏)是必须要有的。
Placingalistofcommandsbetwhellis
icolon(ornewline)followinglistisrequired.
具体解释参考。
(())双括号(Double-Parenthes)
跟let命令⼀样,双括号允许在其中进⾏算数扩展和求值。最简单的⼀个例⼦,a=$((5+3)),会将5+3的结果赋值给a。双括号还是⼀个在
bash中使⽤的C语⾔风格的操作变量的⽅法,举个例⼦((var++)).
详情看。
[]单⽅括号(SingleSquareBrackets)
单⽅括号是内置命令test的另⼀种形式,⽅括号括住的命令会被验证其是否为真。注意,空字符串为fal,⾮空字符串为true。
既然是test命令的另⼀种形式,那么test命令的各种选项就也是可以应⽤的。
具体看。
[[]]双⽅括号(DoubleSquareBrackets)
[[是新的,提⾼版的[,双⽅括号是个关键字,不是⼀个程序。双⽅框更好⽤,⽐较见下表。
英⽂原⽂如下:
[:testimplementstheold,stallshells(theoldestBourneshellsaretheexception),[
isasynonymfortest(butrequiresafinalargumentof]).
[[:isanew,improvedversionofit,kesiteasiertou
具体看和。
&&逻辑与,||逻辑或(LogicalOperators)
双&&符号在Bash中意思是逻辑与(AND),并且可以⽤来分隔⼏个顺序执⾏的命令。
举例:
#cd/root/&&echo"I'vegotroot"
具体看。
&后台⼯作(SingleAmpersand)
在Bash中,&是控制字符,放在命令的末尾,其作⽤是让命令在后台运⾏,也就是说在另外的⼀个subshell⾥,以异步的⽅式,如同⼀个
job⼀样的执⾏。当前的Shell会⽴即回到等待⽤户输⼊的状态,并且返回值为0.
举例:
#shell会给出后台运⾏命令的processID(PID),这个ID会存储在$!变量中。
$./&
[1]1337
#后⾯可以通过$!变量对该进程进⾏引⽤。
$echo$!
1337
#⼀旦⽣成了新的后台进程,这个进程会出现在job列表中。
$jobs
[1]+Running./&
#foregroud命令可以把这个进程拿回前台。
fg
具体看。
+加号,-减号,*乘号,/除号
⽐较简单,不说了。
=等号(赋值),==双等号(判断相等),!=不等于号
简单,也不说了。
^折⾳号(circumflex/caret)
这个符号在正则表达式中,代表⾏的开头位置,在[]中也与!(叹号)⼀样表⽰⾮,即求反。
>,>>,<,<<,>&,<&,<
这⾥符号⽐较多,⼀个⼀个简介吧。
d>file---将输出重定向到file
d
d>>file---将输出以追加的⽅式重定向到file
4.n>&m---将输出⽂件m和n合并
5.n<&m---将输⼊⽂件m和n合并
6.<
输⼊重定向举例:
⼀般情况下,每个Unix/Linux命令运⾏时都会打开三个⽂件:
标准输⼊⽂件(stdin):stdin的⽂件描述符为0,Unix程序默认从stdin读取数据。
标准输出⽂件(stdout):stdout的⽂件描述符为1,Unix程序默认向stdout输出数据。
标准错误⽂件(stderr):stderr的⽂件描述符为2,Unix程序会向stderr流中写⼊错误信息。
默认情况下,command>file将stdout重定向到file,command
如果希望stderr重定向到file,可以这样写:
$command2>file
如果希望stderr追加到file⽂件末尾,可以这样写:
$command2>>file
2表⽰标准错误⽂件(stderr)。如果希望将stdout和stderr合并后重定向到file,可以这样写:
$command>file2>&1
$#或者
$command>>file2>&1
更多信息,看。
参考资料
=============
Shell中的特殊符号和含义简明总结
shell脚本中⼀些特殊符号
(#!/bin/bash)Whatexactlyisthis?
⽬录堆栈
HowtoCreateUrsinLinux(uraddCommand)
TheMagic~:BashTildeExpansionwith5Examples
本文发布于:2022-11-25 02:30:25,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/90/15775.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |