在shell下总是有一些符号让人感到困惑费解下面有我从网上搜索的shell符号以及解释。
gcc优化程序常用选项
选项格式 功能
-O
-O1 试图减少代码大小和执行时间,但并不执行需要花费大量编译时间的任何优化
-O2 在-O1级别的优化之上,还进行一些额外调整工作——除不做循环展开、函数内联、和寄存器重新命名外,几乎进行所有可选优化
-O3 除了完成所有-O2级别的优化之外,还进行包括循环展开和其他一些与处理器特性相关的优化工作
-O0 不执行优化
-Os 具有-O2级别的优化,同时并不特别增加代码大小
Shell符号 使用方法及说明
(1)# 注释符号(Hashmark[Comments])
1.在shell文件的行首,作为shebang标记,#!/bin/bash;
其他地方作为注释使用,在一行中,#后面的内容并不会被执行,除非;
但是用单/双引号包围时,#作为#号字符本身,不具有注释作用。
(2); 作为多语句的分隔符
多个语句要放在同一行的时候,可以使用分号分隔。注意,有时候分号需要转义。
(3);; 连续分号
在使用case选项的时候,作为每个选项的终结符。在Bash version 4+ 的时候,还可以使用[;;&], [;&]
(4) . 点号
1. 相当于bash内建命令source,如:
#!/bin/bash
. data-file
#包含data-file;
2. 作为文件名的一部分,在文件名的开头,表示该文件为隐藏文件,ls一般不显示出来(ls -a 可以显示);
3. 作为目录名,一个点代表当前目录,两个点号代表上层目录(当前目录的父目录)。注意,两个以上的点不出现,除非你用引号(单/双)包围作为点号字符本身;
4. 正则表达式中,点号表示任意一个字符。
(5) ” 双引号
部分引用。双引号包围的内容可以允许变量扩展,也允许转义字符的存在。如果字符串内出现双引号本身,需要转义,因此不一定双引号是成对的。
(6)’ 单引号
单引号括住的内容,被视为单一字符串,引号内的禁止变量扩展,所有字符均作为字符本身处理(除单引号本身之外),单引号必须成对出现。
(7), 逗号
用在连接一连串的数学表达式中,这串数学表达式均被求值,但只有最后一个求值结果被返回。如:
#!/bin/bash
let t1=((a=5+1, b=7+2))
echo t1=$t1, a=$a, b=$b
## 这个$t1=$b;
用于参数替代中,表示首字母小写,如果是两个逗号,则表示全部小写,注意,这个特性在bash version 4的时候被添加的。例子:
a="ATest"
echo ${a,}
echo ${a,,}
## 前面输出aTest,后面输出的是atest。
(7)\ 反斜线,反斜杆。
放在特殊符号之前,转义特殊符号的作用,仅表示特殊符号本身,这在字符串中常用;
放在一行指令的最末端,表示紧接着的回车无效(其实也就是转义了Enter),后继新行的输入仍然作为当前指令的一部分。
(8)/ 斜线,斜杆
作为路径的分隔符,路径中仅有一个斜杆表示根目录,以斜杆开头的路径表示从根目录开始的路径;
在作为运算符的时候,表示除法符号。如:a=4/2
(9)` 反引号,后引号
命令替换。这个引号包围的为命令,可以执行包围的命令,并将执行的结果赋值给变量。如:a=`dirname '/tmp/x.log'` 。后面dirname返回的结果会赋值给a,注意,此处Mitchell特地使用了反引号和单引号,注意区别。
(10): 冒号
空命令,这个命令什么都不做,但是有返回值,返回值为0(即:true)。这个命令的作用非常奇妙。
可做while死循环的条件;
在if分支中作为占位符(即某一分支什么都不做的时候);
放在必须要有两元操作的地方作为分隔符,如:: $ {username=`whoami`}
在参数替换中为字符串变量赋值,在重定向操作(>)中,把一个文件长度截断为0(:>>这样用的时候,目标存在则什么都不做),这个只能在普通文件中使用,不能在管道,符号链接和其他特殊文件中使用;
甚至你可以用来注释(#后的内容不会被检查,但:后的内容会被检查,如果有语句如果出现语法错误,则会报错);
你也可以作为域分隔符,比如环境变量$PATH中,或者passwd中,都有冒号的作为域分隔符的存在;
你也可以将冒号作为函数名,不过这个会将冒号的本来意义转变(如果你不小心作为函数名,你可以使用unset -f : 来取消function的定义)。
(11)! 感叹号
取反一个测试结果或退出状态。
表示反逻辑,比如后面的!=,这个是表示不等于;
表示取反,如:ls a[!0-9] #表示a后面不是紧接一个数字的文件;
在不同的环境里面,感叹号也可以出现在间接变量引用里面;
在命令行中,可以用于历史命令机制的调用,你可以试试!$,!#,或者!-3看看,不过要注意,这点特性不能在脚本文件里面使用(被禁用)。
星号(wildcard/arithmetic operator[asterisk])。
作为匹配文件名扩展的一个通配符,能自动匹配给定目录下的每一个文件;
正则表达式中可以作为字符限定符,表示其前面的匹配规则匹配任意次;
算术运算中表示乘法。
**
双星号(double asterisk)。算术运算中表示求幂运算。
?
问号(test operator/wildcard[Question mark])。
表示条件测试;
在双括号内表示C风格的三元操作符((condition?true-result:false-result));
参数替换表达式中用来测试一个变量是否设置了值;
作为通配符,用于匹配文件名扩展特性中,用于匹配单个字符;
正则表达式中,表示匹配其前面规则0次或者1次。
$ 美元符号。
作为变量的前导符,用作变量替换,即引用一个变量的内容,比如:echo $PATH;
在正则表达式中被定义为行末(End of line)。
${} 参数替换
用于在字符串中表示变量。
$‘…’
引用内容展开,执行单引号内的转义内容(单引号原本是原样引用的),这种方式会将引号内的一个或者多个[]转义后的八进制,十六进制值展开到ASCII或Unicode字符。
$*
$@
位置参数(Positional Parameters)。
这个在使用脚本文件的时候,在传递参数的时候会用到。两者都能返回调用脚本文件的所有参数,但$*是将所有参数作为一个整体返回(字符串),而$@是将每个参数作为单元返回一个参数列表。注意,在使用的时候需要用双引号将$*,$@括住。这两个变量受到$IFS的影响,如果在实际应用中,要考虑其中的一些细节。
$#
表示传递给脚本的参数数量。
$?
此变量值在使用的时候,返回的是最后一个命令、函数、或脚本的退出状态码值,如果没有错误则是0,如果为非0,则表示在此之前的最后一次执行有错误。
$$
进程ID变量,这个变量保存了运行当前脚本的进程ID值。
()
圆括号(parentheses)。
命令组(Command group)。由一组圆括号括起来的命令是命令组,命令组中的命令实在子shell(subshell)中执行。因为是在子shell内运行,因此在括号外面是没有办法获取括号内变量的值,但反过来,命令组内是可以获取到外面的值,这点有点像局部变量和全局变量的关系,在实作中,如果碰到要cd到子目录操作,并在操作完成后要返回到当前目录的时候,可以考虑使用subshell来处理;
用于数组的初始化。
{x,y,z,…} 花括号扩展
在命令中可以用这种扩展来扩展参数列表,命令将会依照列表中的括号分隔开的模式进行匹配扩展。注意的一点是,这花括号扩展中不能有空格存在,如果确实有必要空格,则必须被转义或者使用引号来引用。例子:echo {a,b,c}-{\ d,” e”,’ f’}
{a..z}
在Bash version 3时添加了这种花括号扩展的扩展,可以使用{A..Z}表示A-Z的所有字符列表,这种方式的扩展Mitchell测试了一下,好像仅适用于A-Z,a-z,还有数字{最小..最大}的这种方式扩展。
{} 代码块
这个是匿名函数,但是又与函数不同,在代码块里面的变量在代码块后面仍能访问。注意:花括号内侧需要有空格与语句分隔。另外,在xargs -i中的话,还可以作为文本的占位符,用以标记输出文本的位置。
{} \;
这个{}是表示路径名,这个并不是shell内建的,现在接触到的情况看,好像只用在find命令里。注意后面的分号,这个是结束find命令中-exec选项的命令序列,在实际使用的时候,要转义一下以免被shell理解错误。
[] 中括号
测试的表示,Shell会测试在[]内的表达式,需要注意的是,[]是Shell内建的测试的一部分,而非使用外部命令/usr/bin/test的链接;
在数组的上下文中,表示数组元素,方括号内填上数组元素的位置就能获得对应位置的内容,如:
Array[1]=xxx
echo ${Array[1]};
表示字符集的范围,在正表达式中,方括号表示该位置可以匹配的字符集范围。
[[]] 双中括号
这个结构也是测试,测试[[]]之中的表达式(Shell的关键字)。这个比单中括号更能防止脚本里面的逻辑错误,比如:&&,||,<,>操作符能在一个[[]]里面测试通过,但是在[]却不能通过。[[]]里面没有文件名扩展(filename expansion)或是词分隔符(Word splitting),但是可以用参数扩展(Parameter expansion)和命令替换(command substitution)。不用文件名通配符和像空白这样的分隔符。注意,这里面如果出现了八进制,十六进制等,shell会自动执行转换比较。
$[…] 词表达表示整数扩展
在方括号里面执行整数表达式。例:
a=3
b=7
echo
[
a+
##返回是10和21
(()) 双括号
表示整数扩展(integer expansion)。功能和上面的
[]差不多,但是需要注意的是,
[]是会返回里面表达式的值的,而(())只是执行,并不会返回值。两者执行后如果变量值发生变化,都会影响到后继代码的运行。可对变量赋值,可以对变量进行一目操作符操作,也可以是二目,三目操作符。
>
&<
&
>
<
<> 重定向
scriptname >filename 重定向scriptname的输出到文件filename中去,如果文件存在则覆盖;
command &>filename 重定向command的标准输出(stdout)和标准错误(stderr)到文件filename中;
command >&2 把command的标准输出(stdout)重定向到标准错误(stderr)中;
scriptname >>filename 把scriptname的输出(同>)追加到文件filenmae中,如果文件不存在则创建。
[i]<>filename 打开filename这个文件用来读或者写,并且给文件指定i为它的文件描述符(file descriptor),文件不存在就会创建。
(command)>
<(command) 这是进程替换
使用的时候注意,括号和<,>之间是不能有空格的,否则报错。其作用有点类似通道,但和管道在用法上又有些不同,管道是作为子进程的方式来运行的,这个命令会在/dev/fd/下面产生类似/dev/fd/63,/dev/fd/62这类临时文件,用来传递数据。
Mitchell个人猜测之所以用这种方法来传递,是因为前后两个不属于同一个进程,因此需要用共享文件的方式来传递资料(这么说其实管道也应该有同样的文件?)。网上有人说这个只是共享文件而已,但是经过测试,发现虽然有/dev/fd/63这样的文件产生,但是这个文件其实是指向pipe:[43434]这样的通道的链接。
<< 双小于号
这个也被称为Here-document,用来将后继的内容重定向到左侧命令的stdin中。<<可以节省格式化时间,别且使命令执行的处理更容易。在实作的时候只需要输入<<和终止标志符,而后(一般是回车后)你就可以输入任何内容,只要在最后的新行中输入终止标志符,即可完成数据的导入。使用here-document的时候,你可以保留空格,换行等。如果要让shell脚本更整洁一点,可以在<<和终止符之间放上一个连字符(-)。
<<<
三个小于号(here-strings)。Here-字串和Here-document类似,here-strings语法:command [args] <<<[“]
word["];
word会展开并作为command的stdin。
<
>
小于,大于号
ASCII比较,进行的是变量的ASCII比较,字串?数字?呃…这个…不就是ASCII比较么?
\<…> 词界符
这个是用在正则表达式中的一个特殊分隔符,用来标记单词的分界。比如:the会匹配there,another,them等等,如果仅仅要匹配the,就可以使用这个词界符,\