转自http:blog。chinaunix。netuid16946891id5088144。html 在shell中常用的特殊符号罗列如下: ;;;。,string!{}?string?:command{}〔〕〔〔〕〕()(()){xx,yy,zz,。。。}。。。gt;! 井号(comments) 这几乎是个满场都有的符号,除了先前已经提过的第一行 !binbash 井号也常出现在一行的开头,或者位于完整指令之后,这类情况表示符号后面的是注解文字,不会被执行。 Thislineiscomments。 由于这个特性,当临时不想执行某行指令时,只需在该行开头加上就行了。这常用在撰写过程中。 如果被用在指令中,或者引号双引号括住的话,或者在倒斜线的后面,那他就变成一般符号,不具上述的特殊功能。〔rootRHEL6scripts〕echoaaa0a〔rootRHEL6scripts〕echoaaa0〔rootRHEL6scripts〕 帐户的home目录 算是个常见的符号,代表使用者的home目录:cd;也可以直接在符号后加上某帐户的名称:cduser或者当成是路径的一部份:bin 当前的工作目录,这个符号代表当前的工作目录,她和内建指令pwd的作用是相同的。 echovarlog 上次的工作目录,这个符号代表上次的工作目录。 echoetchttpdlogs ;分号(Commandseparator) 1、在shell中,担任连续指令功能的符号就是分号。 例子:cdbackup;mkdirstartup;cp。startup。 在命令与命令中间利用分号(;)来隔开,分号前的命令执行完成(无论成功与否)后就会立刻接着执行后面的命令 ;;连续分号(Terminator) 专用在case的选项,担任Terminator的角色。casefopinhelp)echoUsage:Commandhelpversionfilename;;version)echoversion0。1;;esac 。点号(dot,就是点) 1、在shell中,使用者应该都清楚,一个dot代表当前目录,两个dot代表上层目录。 CDPATH。::home:homeweb:var:usrlocal 在上行CDPATH的设定中,等号后的dot代表的就是当前目录的意思。 2、如果档案名称以dot开头,该档案就属特殊档案,用ls指令必须加上a选项才会显示。 3、在regularexpression中,一个dot代表一定有一个任意字符,空格字符也是一个字符。 string单引号(singlequote) 被单引号用括住的内容,将被视为单一字串。在引号内的代表变数的符号,没有作用,也就是说,他被视为一般符号处理,防止任何变量替换。 heyyouhomeechoheyyouWegetheyyou string双引号(doublequote) 被双引号用括住的内容,将被视为单一字串。它防止通配符扩展,但允许变量扩展。这点与单引数的处理方式不同。 heyyouhomeechoheyyouWegethome command倒引号反单引号(backticks) 在前面的单双引号,括住的是字串,但如果该字串是一列命令列,会怎样?答案是不会执行。要处理这种情况,我们得用倒单引号来做。〔rootawakescripts〕fdvdateF〔rootawakescripts〕echoTodayfdvToday20150619〔rootawakescripts〕 在倒引号内的dateF会被视为指令,执行的结果会带入fdv变量中。 fdvdateF还有另外一种写法就是fdv(dateF),两个命令是等价的,只是反单引号()容易被看穿()单引号而已。 ,逗点(comma,标点中的逗号) 这个符号常运用在运算当中当做区隔用途。如下例 !binbashlett1((a53,b71,c153))echot1t1,aa,bb 斜线(forwardslash) 在路径表示时,代表目录。 cdetcrc。d cd。。。。 cd 通常单一的代表root根目录的意思;在四则运算中,代表除法的符号。 letnum1((a102,b255)) 倒斜线 在交互模式下的escape字元,有几个作用;放在指令前,有取消aliases的作用;放在特殊符号前,则该特殊符号的作用消失;放在指令的最末端,表示指令连接下一行。 typermrmisaliasedtormirm。。log 上例,我在rm指令前加上escape字元,作用是暂时取消别名的功能,将rm指令还原。 bkdirhomeechoBackupdir,bkdirbkdirBackupdir,bkdirhome 上例echo内的bkdir,escape将变数的功能取消了,因此,会输出bkdir,而第二个bkdir则会输出变数的内容home。 管道(pipeline) pipeline是UNIX系统,基础且重要的观念。连结上个指令的标准输出,做为下个指令的标准输入。 whowcl 善用这个观念,对精简script有相当的帮助。 !惊叹号(negateorreverse)逻辑运算意义上的非(not)的意思 1、通常它代表反逻辑的作用,譬如条件侦测中,用!来代表不等于if〔?!0〕thenechoExecuteserrorexit1fi 2、在规则表达式中她担任反逻辑的角色lsa〔!09〕 上例,代表显示除了a0,a1。。。。a9这几个文件的其他文件。 3、在history命令中!号的用法〔rootRHEL6〕history。。。。。。1036echo1037ll1038llgrepd1039llgrepd1040history1041llgrepd1042history〔rootRHEL6〕!1038执行第1038条命令llgrepddrwxrxrx。2rootroot4096Jun1215:23bindrwxrxrx。2rootroot4096Jun1615:33scriptsdrwxrxrx。7rootroot4096Nov212014vmwaretoolsdistrib〔rootRHEL6〕!!执行上一个命令也就是刚刚的!1038llgrepddrwxrxrx。2rootroot4096Jun1215:23bindrwxrxrx。2rootroot4096Jun1615:33scriptsdrwxrxrx。7rootroot4096Nov212014vmwaretoolsdistrib〔rootRHEL6〕!echo执行最近一echo为开头的命令,也就是1036那条命令echo4316〔rootRHEL6〕 !的用法mkdirvarwwwhtmluploadchownRapache!这时的!表示上一条命令mkdirvarwwwhtmlupload,也就是chown将varwwwhtmlupload的所有者权限分配给apache这个用户 :冒号 在bash中,这是一个内建指令:什么事都不干,但返回状态值0。 : echo?回应为0 :f。 上面这一行,相当于catdevnullf。 。不仅写法简短了,而且执行效率也好上许多。 有时,也会出现以下这类的用法 :{HOSTNAME?}{USER?}{MAIL?} 这行的作用是,检查这些环境变数是否已设置,没有设置的将会以标准错误显示错误讯息。像这种检查如果使用类似test或if这类的做法,基本上也可以处理,但都比不上上例的简洁与效率。 除了上述之外,还有一个地方必须使用冒号 PATHPATH:HOMEfbin:HOMEfperl:usrlocalmozilla 在使用者自己的HOME目录下的。bashprofile或任何功能相似的档案中,设定关于路径的场合中,我们都使用冒号,来做区隔。 星号(wildcard) 相当常用的符号。 1、在文件名扩展(Filenameexpansion)上,她用来代表0到无穷多个任意字符。〔rootRHEL6〕lsaaaaanacondaks。cfg〔rootRHEL6〕 2、在正则表达式(RegularExpressions)中,代表重复零个到无穷多个的前一个字符,如:grepnessfile。txt,则可能会匹配es、ess、esss等等。正则表达式中的0到无穷多个字符使用的是。表示。 3、在运算时,它则代表乘法。 letfmult23 除了内建指令let,还有一个关于运算的指令expr,星号在这里也担任乘法的角色。不过在使用上得小心,他的前面必须加上escape字元。 次方运算 两个星号在运算时代表次方的意思。 letsus23echosussussus8 及钱号(dollarsign) 1、使用变量的前导符,即变量之前需要加的变量替代值 变量替换(VariableSubstitution)的代表符号。〔rootRHEL6〕vrs123〔rootRHEL6〕echovrsvrsvrs123〔rootRHEL6〕 2、在RegularExpressions里被定义为行的最末端(endofline)。这个常用在grep、sed、awk以及vim(vi)当中。〔rootRHEL6〕llgreptxt34;列出行末是txt结尾的行rwrr。1rootroot1700May2110:501。txtrwrr。1rootroot650May3118:11123。txtrwrr。1rootroot1700May2110:502。txtrwrr。1rootroot923May2709:20network。txtrwrr。1rootroot96Jun117:58printf。txtrwrr。1rootroot673Jun112:24regularexpress。txt 3、在bash中本身也是个变量。代表的是目前这个shell的进程代码,即所谓的PID(ProcessID)想要知道我们当前的shell的PID,可以这样〔rootRHEL6〕echo4316〔rootRHEL6〕 出现的数字就是你的PID号码 ! Shell最后运行的后台Process的PID ?问号 1、在文件名扩展(Filenameexpansion)上扮演的角色是匹配一个任意的字元,但不包含null字元。〔rootRHEL6〕lsm?nman。1man。test〔rootRHEL6〕 善用她的特点,可以做比较精确的档名匹配。 2、在bash中?问号也是一个特殊的变量。在bash里面这个变量很重要。这个变量是上一个执行的命令所回传的值。当我们执行某些命令时,这些命令都会回传一个执行后的代码,一般说,如果成功执行该命令,则会回传一个0值,如果执行过程发生错误,就会回传错误代码。一般以非0的数值来替代。 3、在RegularExpressions正则表达式中(扩展的正则表达式,需要grepE或者是egrep)?代表匹配无和?号前面单一字符,或者类型的实例如4(th)?等于4th或者4 ?状态值(statusvariable) 一般来说,UNIX(linux)系统的进程以执行系统调用exit()来结束的。这个回传值就是status值。回传给父进程,用来检查子进程的执行状态。 一般指令程序倘若执行成功,其回传值为0;失败为1。〔rootRHEL6〕tarcvzfbackup。tar。gzscriptsdevnull〔rootRHEL6〕echo?0〔rootRHEL6〕 由于进程的ID是唯一的,所以在同一个时间,不可能有重复性的PID。有时,script会需要产生临时文件,用来存放必要的资料。而此script亦有可能在同一时间被使用者们使用。在这种情况下,固定文件名在写法上就显的不可靠。唯有产生动态文件名,才能符合需要。符号或许可以符合这种需求。它代表当前shell的PID。〔rootRHEL6〕echoHOSTNAME,USER,MAILftmp。〔rootRHEL6〕llftmrwrr。1rootroot39Jun1709:50ftmp。4316〔rootRHEL6〕echo4316〔rootRHEL6〕 使用它来作为文件名的一部份,可以避免在同一时间,产生相同文件名的覆盖现象。 ps:基本上,系统会回收执行完毕的PID,然后再次依需要分配使用。所以script即使临时文件是使用动态档名的写法,如果script执行完毕后仍不加以清除,会产生其他问题。 {}变量的正规表达式 bash对{}定义了不少用法。以下是取自线上说明的表列 {parameter:word}{parameter:word}{parameter:?word}{parameter:word}{parameter:offset}{parameter:offset:length}{!prefix}{parameter}{parameterword}{parameterword}{parameterword}{parameterword}{parameterpatternstring}{parameterpatternstring} 引用script的执行引用变量,引用参数的算法与一般指令相同,指令本身为0,其后为1,然后依此类推。引用变量的代表方式如下: 0,1,2,3,4,5,6,7,8,9,{10},{11}。。。。。 个位数的,可直接使用数字,但两位数以上,则必须使用{}符号来括住。 则是代表所有引用变量的符号。使用时,得视情况加上双引号。 echo 还有一个与具有相同作用的符号,但效用与处理方式略为不同的符号。 与具有相同作用的符号,不过她们两者有一个不同点。 符号将所有的引用变量视为一个整体。但符号则仍旧保留每个引用变量的区段观念。 这也是与引用变量相关的符号,她的作用是告诉你,引用变量的总数量是多少。 echo (())与declarei declareitotalfirstnusecnu total((firstnusecnu)) 两个例子是一个意思,就是做整数乘法运算,也可以是加减乘除,号是求余数。 区别就是小方括号内可以加上空格符,也是合法的写法,而declarei不可以。 ()指令群组(commandgroup) 用括号将一串连续指令括起来,这种用法对shell来说,称为指令群组。如下面的例子:(cd;vcghpwd;echovcgh),指令群组有一个特性,shell会以产生subshell来执行这组指令。因此,在其中所定义的变数,仅作用于指令群组本身。我们来看个例子 catftmp01!binbashafsh(aincg;echoea)echoa。ftmp01incgfsh 除了上述的指令群组,括号也用在array变数的定义上;另外也应用在其他可能需要加上escape字元才能使用的场合,如运算式。 (()) 这组符号的作用与let指令相似,用在算数运算上,是bash的内建功能。所以,在执行效率上会比使用let指令要好许多。 !binbash((a10))echoeinitalvalue,aa((a))echoaftera,aa {}大括号(Blockofcode) 有时候script当中会出现,大括号中会夹着一段或几段以分号做结尾的指令或变数设定。 catftmp02!binbashafsh{ainbc;echoea}echoa。ftmp02inbcinbc 这种用法与上面介绍的指令群组非常相似,但有个不同点,它在当前的shell执行,不会产生subshell。 大括号也被运用在函数的功能上。广义地说,单纯只使用大括号时,作用就像是个没有指定名称的函数一般。因此,这样写script也是相当好的一件事。尤其对输出输入的重导向上,这个做法可精简script的复杂度。 此外,大括号还有另一种用法,如下 {xx,yy,zz,。。。} 这种大括号的组合,常用在字串的组合上,来看个例子 mkdir{userA,userB,userC}{home,bin,data} 我们得到userAhome,userAbin,userAdata,userBhome,userBbin,userBdata,userChome,userCbin,userCdata,这几个目录。这组符号在适用性上相当广泛。能加以善用的话,回报是精简与效率。像下面的例子 chownrootusr{ucb{ex,edit},lib{ex?。?,howex}} 如果不是因为支援这种用法,我们得写几行重复几次呀! 〔〕中括号 1、在通配符和正则表达式中〔〕代表一定有一个在中括号内的字符,例如〔abcd〕代表一定有一个字符,可能是a、b、c、d这四个任何一个; 2、流程控制中,扮演括住判断式的作用。 if〔?!0〕then echoExecuteserror exit1 fi 〔〕 在通配符和正则表达式中都表示范围如〔09〕、〔az〕、〔AZ〕,需要注意的是字母的范围与语系有关 〔〕 在通配符和正则表达式中都表示非之意如〔AZ〕,表示非大写字符。 〔〔〕〕 这组符号与先前的〔〕符号,基本上作用相同,但她允许在其中直接使用与逻辑等符号。 !binbashreadakif〔〔ak5ak9〕〕thenechoakfi 逻辑符号 这个会时常看到,在中括号中〔〕代表or逻辑的符号。 在命令的行中如下 cmd1cmd2 若cmd1执行完毕且正确执行(?0),则cmd2不执行 若cmd1执行完毕且为错误(?0),则开始执行cmd2 逻辑符号 这个也会常看到,在中括号中〔〕代表and逻辑的符号。 在命令行中如下 cmd1cmd2 若cmd1执行完毕且正确执行(?0),则开始执行cmd2 若cmd1执行完毕且为错误(?0),则cmd2不执行〔rootRHEL6〕lstmpabcmkdirtmpabctouchtmpabchehe如果tmpabc目录不存在则创建这个目录,成功后在目录下创建hehe文件ls:cannotaccesstmpabc:Nosuchfileordirectory这个就是lstmpabc标准错误输出〔rootRHEL6〕lltmpabcheherwrr。1rootroot0Jun1711:00tmpabchehe已经创建了文件〔rootRHEL6〕lstmpbcdechonotexistechoexist这个实例告诉我们与的使用是要注意顺序的。ls:cannotaccesstmpbcd:Nosuchfileordirectorynotexistexist〔rootRHEL6〕lstmpbcdechoexistechonotexist呈上,这个是正确的顺序ls:cannotaccesstmpbcd:Nosuchfileordirectorynotexist〔rootRHEL6〕一般来说,假设判断式有三个,也就是cmd1cmd2cmd3,而且顺序通常不会变,因为一般说cmd2与cmd3会放置肯定可以执行成功的命令。 后台工作 单一个符号,且放在完整指令列的最后端,即表示将该指令列放入后台中工作。 tarcvfzdata。tar。gzdatadevnull 。。。gt;单字边界 这组符号在规则表达式中,被定义为边界的意思。譬如,当我们想找寻the这个单字时,如果我们用 greptheFileA 你将会发现,像there这类的单字,也会被当成是匹配的单字。因为the正巧是there的一部份。如果我们要必免这种情况,就得加上边界的符号 grepFileA 加号(plus) 在运算式中,她用来表示加法。 expr123 此外在规则表达式中,用来表示很多个的前面字元的意思。 grep109fileB109100910000910000931010009这个符号在使用时,前面必须加上escape字元。 减号(dash) 在运算式中,她用来表示减法。 expr102 此外也是系统指令的选项符号。 lsexpr102 在GNU指令中,如果单独使用符号,不加任何该加的文件名称时,代表标准输入的意思。这是GNU指令的共通选项。譬如下例 tarxpvf 这里的符号,既代表从标准输入读取资料。 不过,在cd指令中则比较特别 cd 这代表变更工作目录到上一次工作目录。 除法(Modulo) 在运算式中,用来表示除法。 expr102 此外,也被运用在关于变量的规则表达式当中的下列 {parameterword}{parameterword} 一个表示最短的word匹配,两个表示最长的word匹配。 等号(Equals) 常在设定变数时看到的符号。 vara123echovaravara 或者像是PATH的设定,甚至应用在运算或判断式等此类用途上。 等号(Equals) 常在条件判断式中看到,代表等于的意思。 if〔varavarb〕 。。。下略 !不等于 常在条件判断式中看到,代表不等于的意思。 if〔vara!varb〕 。。。下略 1、这个符号在正则表达式中,代表行的开头位置〔rootRHEL6〕llgrepddrwxrxrx。2rootroot4096Jun1215:23bindrwxrxrx。2rootroot4096Jun1615:33scriptsdrwxrxrx。7rootroot4096Nov212014vmwaretoolsdistrib〔rootRHEL6〕 2、在〔〕中也与!(叹号)一样表示非 如〔AZ〕,表示非大写字符,〔abc〕表示非a、b、c这3个字符,〔〕的用法在通配符中和正则表达式中意思是一样的。 输出输入重导向 :222 文件描述符(FileDescriptor),用一个数字(通常为09)来表示一个文件。 常用的文件描述符如下: 文件描述符名称常用缩写默认值 0标准输入stdin键盘 1标准输出stdout屏幕 2标准错误输出stderr屏幕 我们在简单地用或时,相当于使用0或1(下面会详细介绍)。 cmdfile 把cmd命令的输出重定向到文件file中。如果file已经存在,则清空原有文件,使用bash的noclobber选项可以防止复盖原有文件。 cmdfile 把cmd命令的输出重定向到文件file中,如果file已经存在,则把信息加在原有文件後面。 cmdfile 使cmd命令从file读入 cmdtext 从命令行读取输入,直到一个与text相同的行结束。除非使用引号把输入括起来,此模式将对输入内容进行shell变量替换。如果使用,则会忽略接下来输入行首的tab,结束行也可以是一堆tab再加上一个与text相同的内容,可以参考後面的例子。 cmdword 把word(而不是文件word)和後面的换行作为输入提供给cmd。 cmdfile 以读写模式把文件file重定向到输入,文件file不会被破坏。仅当应用程序利用了这一特性时,它才是有意义的。 cmdfile 功能同,但即便在设置了noclobber时也会复盖file文件,注意用的是而非一些书中说的!,目前仅在csh中仍沿用!实现这一功能。 :filename把文件filename截断为0长度。如果文件不存在,那么就创建一个0长度的文件(与touch的效果相同)。 cmdn把输出送到文件描述符n cmdmn把输出到文件符m的信息重定向到文件描述符n cmd关闭标准输出 cmdn输入来自文件描述符n cmdmnm来自文件描述各个n cmd关闭标准输入 cmdn移动输入文件描述符n而非复制它。 cmdn移动输出文件描述符n而非复制它。 注意:实际上复制了文件描述符,这使得cmdfile21与cmd21file的效果不一样。