shell十三问笔记
sh:
burne shell (sh)
burne again shell (bash)
csh:
c shell (csh)
tc shell (tcsh)
korn shell (ksh)
bash 是 gnu project 最成功的产品之一,自推出以来深受广大 Unix
用户喜爱,且也逐渐成为不少组织的系统标准。
echo 在预设上,在显示完 argument 之后,还会送出一个换行符号(new-line
charactor)。若你要取消这个换行符号,可利用 echo 的 -n option ,举例:
wangnc>echo "test "
test
wangnc>echo -n "test "
test wangnc>
wangnc>
事实上,echo 除了 -n options 之外,常用选项还有:
-e :启用反斜线控制字符的转换(参考下表)
-E :关闭反斜线控制字符的转换(预设如此)
-n :取消行末之换行符号(与 -e 选项下的 \c 字符同意)
关于 echo 命令所支持的反斜线控制字符如下表:
\a:ALERT / BELL (从系统喇叭送出铃声)
\b:BACKSPACE ,也就是向左删除键
\c:取消行末之换行符号
\E:ESCAPE,跳脱键
\f:FORMFEED,换页字符
\n:NEWLINE,换行字符
\r:RETURN,回车键
\t:TAB,表格跳位键
\v:VERTICAL TAB,垂直表格跳位键
\n:ASCII 八进位编码(以 x 开首为十六进制)
\\:反斜线本身
举例:
wangnc>echo "a\tb\tc\nd\te\tf"
a\tb\tc\nd\te\tf
wangnc>echo -e "a\tb\tc\nd\te\tf"
a b c
d e f
wangnc>
除了 IFS 与 CR ,常用的 meta 还有:
= : 设定变量。
$ : 作变量或运算替换(请不要与 shell prompt 搞混了)。
> :重导向 stdout。
< :重导向 stdin。
|:命令管线。
& :重导向 file descriptor ,或将命令置于背境执行。
( ):将其内的命令置于 nested subshell 执行,或用于运算或命令替换。
{ }:将其内的命令置于 non-named function 中执行,或用在变量替换的界定范围。
; :在前一个命令结束时,而忽略其返回值,继续执行下一个命令。
&& :在前一个命令结束时,若返回值为 true,继续执行下一个命令。
|| :在前一个命令结束时,若返回值为 false,继续执行下一个命令。
!:执行 history 列表中的命令
....
在 bash 中,常用的 quoting 有如下三种方法:
* hard quote:' ' (单引号),凡在 hard quote 中的所有 meta 均被关闭。
* soft quote: " " (双引号),在 soft quoe 中大部份 meta
都会被关闭,但某些则保留(如 $ )。(注二)
* escape : \ (反斜线),只有紧接在 escape (跳脱字符)之后的单一
meta才被关闭。
举例:
wangnc>A=b c
-bash: c: command not found
wangnc>A=b\ c
wangnc>echo $A
b c
wangnc>echo "$A"
b c
wangnc>echo '$A'
$A
wangnc>echo "'$A'"
'b c'
wangnc>echo '"$A"'
"$A"
wangnc>
在 bash 中,你可以用 "=" 来设定或重新定义变量的内容:
name=value
在设定变量的时侯,得遵守如下规则:
* 等号左右两边不能使用区隔符号(IFS),也应避免使用 shell 的保留字符(meta
charactor)。
* 变量名称不能使用 $ 符号。
* 变量名称的第一个字母不能是数字(number)。
* 变量名称长度不可超过 256 个字母。
* 变量名称及变量值之大小写是有区别的(case sensitive)。
可利用命令行的变量替换能力来"扩充"(append)变量值,我们使用区隔符号( :
)来达到扩充目的,使用 {} 将变量名称的范围给明确定义出来:
wangnc>A=B:C:D
wangnc>echo $A
B:C:D
wangnc>A=$A:E
wangnc>echo $A
B:C:D:E
wangnc>A=BCD
wangnc>ech $A
-bash: ech: command not found
wangnc>echo $A
BCD
wangnc>A=$AE
-bash: AE: unbound variable
wangnc>A=${A}E
wangnc>echo $A
BCDE
wangnc>
严格来说,我们在当前 shell 中所定义的变量,均属于"本地变量"(local
variable),只有经过 export 命令的"输出"处理,才能成为环境变量(environment
variable),在使用 export 的时侯,请别忘记 shell
在命令行对变量的"替换"(substitution)处理,比方说:
wangnc>A=B
wangnc>B=C
wangnc>export $A
上面的命令并未将 A 输出为环境变量,而是将 B
作输出,这是因为在这个命令行中,$A 会首先被提换出 B 然后再"塞回"作 export
的参数。
()和{}的区别:
( ) 将 command group 置于 sub-shell 去执行,也称 nested sub-shell。
{ } 则是在同一个 shell 内完成,也称为 non-named command group。
有点类似fork和source的区别
$@与$*差在哪?
若在 command line 上跑 my.sh p1 "p2 p3" p4 的话,不管是 $@ 还是 $*
,都可得到 p1 p2 p3 p4 就是了。但是,如果置于 soft quote 中的话:
"$@" 则可得到 "p1" "p2 p3" "p4" 这三个不同的词段(word)﹔
"$*" 则可得到 "p1 p2 p3 p4" 这一整串单一的词段。