**

在脚本或其他别的地方出现的特殊字符

**

注释. 以一个#开头的行 (#!是例外) 是注释行.
1 # 这是一行注释.
注释也可以出现在一个命令语句的后面。
1 echo “A comment will follow.” # 这里可以添加注释.
2 # ^ 注意在#前面可以有空白符 #
注释行前面也可以有空白字符.
1 #注意这个注释行的开头是一个TAB键.

在同一行中,命令不会跟在一个注释的后面。因为这种情况下没有办法分辨注释的结尾,命令只能放在同一行的行首。用另外的一个新行开始下一个注释。

当然了,在echo命令给出的一个转义的#字符并不会开始一个注释。同样地,出现在一些参数代换结构和在数值常量表达式中的#字符也同样不会开始一个注释。
1 echo “The # here does not begin a comment.”
2 echo ‘The # here does not begin a comment.’
3 echo The # here does not begin a comment.
4 echo The # here begins a comment.
5
6 echo ${PATH#*:} # 前面的#是参数代换,不是注释.
7 echo $(( 2#101011 )) # 基本转换,不是注释.
8
标准的引用和转义 符("’\)可以转义#。
当然,模式匹配操作也可以使用#,而不必把它当做注释的开始。

命令分割符[分号]. 分割符允许在同一行里有两个或更多的命令.

1 echo hello; echo there
2
3
4 if [ -x “$filename” ]; then # 注意:“if” and "then"需要分隔符
5 # 思考一下这是为什么?
6 echo “File $filename exists.”; cp $filename $filename.bak
7 else
8 echo “File $filename not found.”; touch $filename
9 fi; echo “File test complete.”

注意”;”有时需要转义.

;; case语句分支的结束符[双分号].

1 case “$variable” in
2 abc) echo “$variable = abc” ;;
3 xyz) echo “$variable = xyz” ;;
4 esac

.

"点"命令[圆点]. 等同于source .这是一个bash的内建命令.

“点”, 作为一个文件名的组成部分.当点(.)以一个文件名为前缀时,起作用使该文件变成了隐藏文件。这种隐藏文件ls一般是不会显示出来的。[译者注:除非你加了选项-a]
bash$ touch .hidden-file
bash$ ls -l
total 10
-rw-r–r-- 1 bozo 4034 Jul 18 22:04 data1.addressbook
-rw-r–r-- 1 bozo 4602 May 25 13:58 data1.addressbook.bak
-rw-r–r-- 1 bozo 877 Dec 17 2000 employment.addressbook

bash$ ls -al
total 14
drwxrwxr-x 2 bozo bozo 1024 Aug 29 20:54 ./
drwx------ 52 bozo bozo 3072 Aug 29 20:51 …/
-rw-r–r-- 1 bozo bozo 4034 Jul 18 22:04 data1.addressbook
-rw-r–r-- 1 bozo bozo 4602 May 25 13:58 data1.addressbook.bak
-rw-r–r-- 1 bozo bozo 877 Dec 17 2000 employment.addressbook
-rw-rw-r-- 1 bozo bozo 0 Aug 29 20:54 .hidden-file

作为目录名时,单个点(.)表示当前目录,两个点(…)表示上一级目录(译者注:或称为父目录)。

bash$ pwd
/home/bozo/projects

bash$ cd .
bash$ pwd
/home/bozo/projects

bash$ cd …
bash$ pwd
/home/bozo/

bash$ cp /home/bozo/current_work/junk/* .

.

单点(.)文件名常常被当作文件移动命令的目的路径.

点(.)字符匹配.作为正则表达式的一部分,匹配字符时,单点(.)表示匹配任意一个字符。

"

部分引用[双引号]. "STRING"的引用会使STRING里的特殊字符能够被解释。请参考第五章.

完全引用[单引号].

'STRING’能引用STRING里的所有字符(包括特殊字符也会被原样引用). 这是一个比使用双引号(“)更强的引用。 参考第5章.

,

逗号操作符[逗号].

逗号操作符用于连接一连串的数学表达式。这一串的数学表达式每一个都被求值,但只有最后一个被返回。(译者注:换句话说,就是整个表达式的值取决于最后一个表达式的值。)
1 let “t2 = ((a = 9, 15 / 3))” # Set “a = 9” and “t2 = 15 / 3”

\

转义符[后斜杠].

用于单个字符的引用机制。

\X “转义"字符为X.它有"引用"X的作用,也等同于直接在单引号里的’X’.\符也可以用于引用双引号(”)和单引号(’),这时双引号和单引号就表示普通的字符,而不是表示引用了。

参考第五章对转义字符的更深入的解释。

/

文件路径的分隔符[前斜杠].

分隔一个文件路径的各个部分。(就像/home/bozo/projects/Makefile).

它也是算术操作符中的除法.

`

命令替换.

command 结构使字符(`)[译者注:这个字符不是单引号,而是在标准美国键盘上的ESC键下面,在字符1左边,在TAB键上面的那个键,要特别留心]引住的命令(command)执行结果能赋值给一个变量。它也被称为后引号(backquotes)或是斜引号(backticks).

:

空命令[冒号].

这个命令意思是空操作(即什么操作也不做). 它一般被认为是和shell的内建命令true是一样的。冒号":" 命令是Bash自身内建的, and its它的退出状态码是真(即0)。[译者注:shell中真用数字0表示].

1 :
2 echo $? # 0

;

死循环可以这么写:

1 while :
2 do
3 operation-1
4 operation-2
5 …
6 operation-n
7 done
8
9 # 等同于:
10 # while true
11 # do
12 # …
13 # done

在if/then的测试结构中用作占位符:

1 if condition
2 then : # 什么也不做的分支
3 else
4 take-some-action
5 fi

在必须要有两元操作的地方作为一个分隔符, 参考默认参数.

1 : ${username=whoami}
2 # ${username=whoami} 如果没有开头的:,将会出错
3 # 除非"username"是一个外部命令或是内建命令…

在here document中的一个命令作为一个分隔符.

在参数替换中为字符串变量赋值
1 : ${HOSTNAME?} ${USER?} ${MAIL?}
2 # 如果列出的一个或多个基本的环境变量没有设置,
3 #+ 将打印出错信息。

变量扩展/子串代换.

和重定向操作符(>)连用, 可以把一个文件的长度截短为零,文件的权限不变。如果文件不存在,则会创建一个新文件。
1 : > data.xxx # 文件"data.xxx"现在长度为0了
2
3 # 作用相同于:cat /dev/null >data.xxx(译者注:echo >data.xxx也可以)
4 # 但是,用NULL(:)操作符不会产生一个新的进程,因为NULL操作符是内建的。
请参考例子 12-14.

和添加重定向操作符(>>)连用(: >> target_file).如果目标文件存在则什么也没有发生,如果目标文件不存在,则创建它。

这只能应用在普通文件中,不能用在管道,符号链接和其他的特殊文件。

虽然这是不被推荐的,但是NULL操作符(:)也可以用于开始注释一行。使用#来注释一行将会使Bash不会检查这行后面的语法是否有错,因此#注释几乎可以出现任何的东西。但是,对于用NULL操作符(:)注释的行则不是这样。

下面一个会产生错误的注释。
1 : This is a comment that generates an error, ( if [ $x -eq 3] ).

字符”:”也用于域分割符。比如说在/etc/passwd和环境变量PATH里.bashPATH里. bashPATH里.bash echo $PATH
/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/sbin:/usr/sbin:/usr/games

!

取反

一个测试结果或退出状态[感叹号]. 取反操作符(!)取反一个命令的退出状态(参考例子 6-2).它也取反一个测试操作。例如,它能改相等符( = )为不等符( != ).取反操作符(!)是一个Bash的关键字.

在不同的环境里,感叹号也可以出现在间接变量引用.

还有一种环境里,在命令行中,感叹号(!)调用属于历史命令机制的调用(详细请看附录 J).值得一提的是,在一个脚本里,命令历史机制是被禁止的。

*

通配符[星号].

星号(*)字符在用于匹配文件名扩展的一个通配符.它自动匹配给定的目录下的每一个文件。

bash$ echo *
abs-book.sgml add-drive.sh agram.sh alias.sh

星号(*)也用于正则表达式中匹配任意数字字符。.

*

算术操作符.

在计算时,星号(*)表示乘法运算符。两个星号(**)表示求幂运算符。

?

测试操作符.

在一些表达式中,问号(?)表示一个条件测试.

在双括号结构里,问号(?)表示C风格的三元操作符.请参考例子 9-30.

在参数替换表达式里,问号(?)测试一个变量是否被设置了值.

?

通配符.

字符?被用于文件名扩展特性的文件名表达式的单字符匹配,同时也在扩展正则表达式中匹配任意一个字符.

$

变量替换 (引用一个变量的内容).
1 var1=5
2 var2=23skidoo
3
4 echo $var1 # 5
5 echo $var2 # 23skidoo

一个变量名前面加一个$字符前缀表示引用该变量的内容。

$

行的结尾. 在正则表达式里,一个$字符表示匹配一行的结尾。

${}

参数替换.

$*, $@

位置参数.

$?

保存退出码值的变量. 变量$?保存了一个命令,一个函数,或一个脚本的退出状态码的值。

$$

进程ID变量. 变量$$保存了脚本运行时的进程ID值。

()

命令组.
1 (a=hello; echo $a)

一组由圆括号括起来的命令是新开一个子shell来执行的.

因为是在子shell里执行,在圆括号里的变量不能被脚本的其他部分访问。因为父进程(即脚本进程)不能存取子进程(即子shell)创建的变量。(译者注:读者若对这部分内容感兴趣,可以参考stevens的<>一书中对进程的描述。).
1 a=123
2 ( a=321; )
3
4 echo “a = $a” # a = 123
5 # 在圆括号里的变量"a"实际上是一个局部变量,作用局域只是在圆括号内用于数组始初化

数组初始化.

1 Array=(element1 element2 element3)

{xxx,yyy,zzz,…}
扩展支持.
1 cat {file1,file2,file3} > combined_file
2 # 连接file1,file2,和file3的内容并写到文件combined_file里去.
3
4
5 cp file22.{txt,backup}
6 # 拷贝"file22.txt"内容为"file22.backup"

一个命令可以在文件名扩展中从逗号分隔的各模式来扩展参数列表。 [1] 文件名将会依照列表中逗号分隔开的模式匹配扩展。

在扩展中的所有模式都不能包含空白字符,除非空白字符是被转义或引用的。

echo {file1,file2}\ :{\ A," B",’ C’}

file1 : A file1 : B file1 : C file2 : A file2 : B file2 : C

{}

代码块[花括号]

. 这个结构也是一组命令代码块,事实上,它是匿名的函数。然而与一个函数所不同的,在代码块里的变量仍然能被脚本后面的代码访问。

bash$ { local a;
a=123; }
bash: local: can only be used in a
function

1 a=123
2 { a=321; }
3 echo “a = $a” # a = 321 (结果是在代码块里的值)
4
5 # 多谢, S.C.

由花括号括起的代码块可以引起输入输出的I/O重定向。

{} ;

路径名. 基本上用于find命令里.它不是shell内建的.

分号";"结束find命令中-exec选项的命令序列.它应该转义一下以免被shell误解释。

[ ]

测试.

测试在[ ]中的表达式. 注意[是shell内建的测试的一部分(同义于测试),并非 是外部命令/usr/bin/test的链接.

[[ ]]

测试.

测试[[ ]]之中的表达式(shell的关键字).

参考[[ … ]]结构的讨论.

[ ]

数组元素.

在数组的上下文中,方括号表示数组的每个元素的数字编号.
1 Array[1]=slot_1
2 echo ${Array[1]}

[ ]

字符集的范围.

用于正则表达式的一部分,方括号描述一个匹配的字符集范围.

(( ))

整数扩展.

扩展并计算(( ))里的整数表达式[译者注:粗心的读者要注意了,是整数计算,可不能用来做浮点计算].

参考(( … ))结构的讨论.

> &> >& >> <

redirection重定向.

scriptname >filename重定向scriptname的输出到文件filename中去. 如果文件filename存在则将会被覆盖.

command &>filename 会重定向命令command标准输出(stdout)和标准错误(stderr)到文件filename中.

command >&2 把命令command的标准输出(stdout)重定向到标准错误(stderr).

scriptname >>filename appends把脚本scriptname的输出追加到文件filename.如果filename不存在,则它会被创建.

进程替换.

(command)>

<(command)

在不同的上下文中, 字符 "<“和”>"会被当作字符比较操作符.

在另一种不同的上下文中, 字符"<“和”>"被当作整数比较操作符. 请参考例子 12-9.

<<
在here document中使用的重定向.

<<<
在 here string中使用的重定向.

<, >

ASCII比较.
1 veg1=carrots
2 veg2=tomatoes
3
4 if [[ “veg1&quot;&lt;&quot;veg1&quot; &lt; &quot;veg1"<"veg2” ]]
5 then
6 echo “Although $veg1 precede $veg2 in the dictionary,”
7 echo “this implies nothing about my culinary preferences.”
8 else
9 echo “What kind of dictionary are you using, anyhow?”
10 fi

<, >

在 regular expression中的单词界线.

bash$ grep ‘<the>’ textfile

|

管道符. 把上一个命令的输出传给下一个命令,或是shell. 这是连接命令的一种方法.

1 echo ls -l | sh
2 # 把"echo ls -l"的输出传给shell,
3 #+ 这等同与直接的"ls -l".
4
5
6 cat *.lst | sort | uniq
7 # 合并且排序所有的".lst"文件,然后删除多余的相同行.

经典的进程间通信方法之一的管道能把一个进程的标准输出发到另一个进程的标准输入.在一种典型的情况,一个命令,比如说cat或echo, 管道传递一个数据流给过滤器(一个改变了它的输入的命令)。

cat $filename1 $filename2 | grep $search_word

一个命令或一组命令的输出可以由管道传给一个脚本.
1 #!/bin/bash
2 # uppercase.sh : 把输入字符改为大写.
3
4 tr ‘a-z’ ‘A-Z’
5 # 字母的范围一定要引号引起来,
6 #+ 这样才能保护文件名而不会被扩展成单个字母的文件名.
7
8 exit 0
现在,让我们把ls -l的输出用管道与这个脚本连起来.
bash$ ls -l | ./uppercase.sh
-RW-RW-R-- 1 BOZO BOZO 109 APR 7 19:49 1.TXT
-RW-RW-R-- 1 BOZO BOZO 109 APR 14 16:48 2.TXT
-RW-R–R-- 1 BOZO BOZO 725 APR 20 20:56 DATA-FILE

管道里的每一个进程的标准输出都被当成下一个命令的标准输入. 如果不是这种情况,那么数据流会阻塞,并且管道不会引起预期的效果。
1 cat file1 file2 | ls -l | sort
2 # 来自"cat file1 file2"的输出会消失.

管道以子进程来运行, 因此不能引起变量的改变。
1 variable=“initial_value”
2 echo “new_value” | read variable
3 echo “variable = $variable” # variable = initial_value

如果在管道中的一个命令失败了,会过早的终结整个管道的执行。这称为管道破坏(broken pipe),这时会发送一个叫SIGPIPE 的信号.

>|

强迫重定向 (即使noclobber选项设置). 这会强迫覆盖一个存在的文件.

||

或逻辑操作符. 在一个测试结构中,||操作符当测试条件的任何一个为真时返回0 (成功)的标志.

&

在后台运行作业. 一个后面跟一个&的命令会在后台运行.

bash$ sleep 10 &
[1] 850
[1]+ Done sleep 10

在一个脚本里,在后台运行的命令或是偶数的循环可以在后台运行.

例子 3-3. 在后台运行一个循环

1 #!/bin/bash
2 # background-loop.sh
3
4 for i in 1 2 3 4 5 6 7 8 9 10 # 第一个循环.
5 do
6 echo -n "KaTeX parse error: Expected 'EOF', got '&' at position 15: i " 7 done &̲ # 把这个循环放到后台去. …i "
15 done
16
17 echo # 这个’echo’有时不会打印出来.
18
19 # ======================================================
20
21 # 这个脚本的输出是:
22 # 1 2 3 4 5 6 7 8 9 10
23 # 11 12 13 14 15 16 17 18 19 20
24
25 # 然而有时你也有可能得到如下的输出:
26 # 11 12 13 14 15 16 17 18 19 20
27 # 1 2 3 4 5 6 7 8 9 10 bozo $
28 # (第二个 'echo’没有执行. 为什么?)
29
30 # 偶尔也会:
31 # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
32 # (第一个 ‘echo’ 没有执行. 为什么?)
33
34 # 非常罕有的情况可能是:
35 # 11 12 13 1 2 3 4 5 6 7 8 9 10 14 15 16 17 18 19 20
36 # 前台的循环抢占了后台的循环输出.
37
38 exit 0
39
40 # Nasimuddin Ansari 建议在第6行和第14行的:echo -n “$i” 加入sleep 1
41 #+ 将会更有趣
42 #

脚本中在一条在后台运行的命令可能会引起脚本悬挂,等待一个击键动作。幸运的是,有一个补救的办法.

&&

与逻辑操作符. 在测试结构中,&&操作只在测试条件两者 都为真时会返回0(成功).

选项, 前缀. 用于一个命令或过滤器的选项标志.或用于一个操作符的前缀.

COMMAND -[选项1][选项2][…]

ls -al

sort -dfu $filename

set – $variable

1 if [ $file1 -ot $file2 ]
2 then
3 echo “File $file1 is older than file2.&quot;4fi56if[&quot;file2.&quot; 4 fi 5 6 if [ &quot;file2."4fi56if["a” -eq “b&quot;]7then8echo&quot;b&quot; ] 7 then 8 echo &quot;b"]7then8echo"a is equal to b.&quot;9fi1011if[&quot;b.&quot; 9 fi 10 11 if [ &quot;b."9fi1011if["c” -eq 24 -a “d&quot;−eq47]12then13echo&quot;d&quot; -eq 47 ] 12 then 13 echo &quot;d"−eq47]12then13echo"c equals 24 and $d equals 47.”
14 fi

用于stdin或stdout重定向的源或目的[dash].

1 (cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xpvf -)
2 # 把整个目录树从一个目录移到另外一个目录
3 # [谦逊的 Alan Cox a.cox@swansea.ac.uk,作了一些修改]
4
5 # 1) cd /source/directory 源目录,这是要移动的目录所在地.
6 # 2) && 逻辑与: 如果’cd’命令操作成功,然后就执行下一条命令.
7 # 3) tar cf - . tar命令的’c’选项创建一个新的归档文件,
8 # 而’f’(file)选项,后跟一个’-‘表示创建的目标文件是标准输出,
9 # 并且要操作的源目录是当前目录 (’.’).
10 # 4) | 然后由管道输出…
11 # 5) ( … ) 一个子shell
12 # 6) cd /dest/directory 将当前目录切换到目的目录.
13 # 7) && 逻辑与,和上面的解释一样
14 # 8) tar xpvf - 解开归档文件(‘x’),保持文件属主和文件的权限(‘p’),
15 # 并且把输出的详细信息打印到标准输出 (‘v’),
16 # 从标准输入读(‘f’后跟’-’).
17 #
18 # 注意’x’是一个命令,而’p’, ‘v’, 'f’是选项.
19 # 哇!
20
21
22
23 # 更优雅的,但作用一样的:
24 # cd source/directory
25 # tar cf - . | (cd …/dest/directory; tar xpvf -)
26 #
27 # 也可以这样:
28 # cp -a /source/directory/* /dest/directory
29 # 或:
30 # cp -a /source/directory/* /source/directory/.[^.]* /dest/directory
31 # 如果在/source/directory有隐藏文件.

1 bunzip2 linux-2.6.13.tar.bz2 | tar xvf -
2 # –  解压tar文件  – | --然后把结果传给"tar"–
3 # 如果"tar"没有打上处理"bunzip2"程序的补丁,
4 # 就需要用管道连接两个不连续的步骤.
5 # 这个练习的目的是解压内核源码包.

注意"-"环境不是一个Bash操作符提供的,而是被由一些写标准输出的UNIX软件包来验证的,比如tar, cat,等等.

bash$ echo “whatever” | cat -
whatever

当希望提供一个文件名时, ‘-’ 重定向输出到标准输出(有时像tar cf),或者从标准输入接受输入,就好像它们是一个文件一样 . 这是在管道中使用文件导向(file-oriented)软件包作为一个过滤器的方法.

bash$ file
Usage: file [-bciknvzL] [-f namefile] [-m magicfiles] file…

只在命令行单独给出命令file,会引起一个错误信息.

加一个"-"来看看结果,这会使shell等候用户的输入。
bash$ file -
abc
standard input: ASCII text

bash$ file -
#!/bin/bash
standard input: Bourne-Again shell script text executable

现在命令从标准输入接受输入并分析它.

"-"能被用来把标准输出由管道输出到其他的命令.这样就允许使用在文件开头增加几行的技巧.

使用 diff 来比较一个文件和另一个文件的某一段:

grep Linux file1 | diff file2 -

最后Finally,再展示一个使用- 的tar命令的真实例子.

例子 3-4. 备份前24小时被修改的文件

1 #!/bin/bash
2
3 # 备份当前目录下所有前24小时被修改的文件为一个归档压缩包(归档并且压缩)
4 #
5
6 BACKUPFILE=backup-KaTeX parse error: Expected 'EOF', got '#' at position 23: …%m-%d-%Y) 7 #̲ …{1:-$BACKUPFILE}
10 # 如果没有在命令行上指定备份的归档文件名,
11 #+ 会以"backup-MM-DD-YYYY.tar.gz.“作为默认的文件名
12
13 tar cvf - find . -mtime -1 -type f -print > $archive.tar
14 gzip $archive.tar
15 echo “Directory KaTeX parse error: Can't use function '\"' in math mode at position 31: …n archive file \̲"̲archive.tar.gz”.”
16
17
18 # Stephane Chazelas指出:如果有许多文件被找到
19 #+ 或任何一个文件名中包含有空白字符
20 #+ 上面的代码将会失败.
21
22 # 他建议用下面的代码:
23 # -------------------------------------------------------------------
24 # find . -mtime -1 -type f -print0 | xargs -0 tar rvf “KaTeX parse error: Expected 'EOF', got '#' at position 19: …hive.tar" 25 #̲ using the…archive.tar” ‘{}’ ;
29 # portable to other UNIX flavors, but much slower.
30 # -------------------------------------------------------------------
31
32
33 exit 0

以"-“字符开头为文件名的文件当加上”-"的定向操作符时可能会引起问题.脚本应该检查这种情况并且给这种文件增加合适的路径前缀,例如 ./-FILENAME, PWD/−FILENAME,或PWD/-FILENAME, 或PWD/−FILENAME,或PATHNAME/-FILENAME.

如果一个变量的值以-开头,同样也可能会产生问题.
1 var="-n"
2 echo $var
3 # 和"echo -n"一样,什么也不会输出.

先前的工作目录. 命令cd - 可以回到原来的工作目录.它使用了$OLDPWD 环境变量.

不要弄混了这儿使用的"-“和上面刚讨论的”-“重定向操作符.对于”-"字符的解释应依赖于它出现的环境.

负号或减号. 减号用于算术操作.

=

等号. 赋值操作符
1 a=28
2 echo $a # 28

在不同的上下文, "="是一个字符串比较操作符.

+

加. 算术操作符加法.

在不同的上下文中, +是一个正则表达式操作符.

+

选项. 一个命令或是过滤器的选项标志.

一些命令和内建命令 用+来启用一些选项,用-来禁用它们.

%

取模. 取模 (一次除法的余数) 算术操作.

在不同的上下文中,%是一个模式匹配 操作符.

~

主目录或称为家目录[波浪号]. 它与内部变量 HOME是一致的.bozo是bozo′的主目录,而lsbozo会列出此目录的内容./是当前用户的主目录,并且ls/会列出此目录的内容.bashHOME 是一致的. ~bozo是bozo'的主目录,而ls ~bozo 会列出此目录的内容. ~/ 是当前用户的主目录,并且ls ~/ 会列出此目录的内容. bashHOME是一致的. bozo是bozo′的主目录,而ls bozo会列出此目录的内容. /是当前用户的主目录,并且ls /会列出此目录的内容.bash echo ~bozo
/home/bozo

bash$ echo ~
/home/bozo

bash$ echo ~/
/home/bozo/

bash$ echo ~:
/home/bozo:

bash$ echo ~nonexistent-user
~nonexistent-user

~+

当前工作目录. 它与外部变量$PWD是一致的.

~

先前的工作目录. 它与外部变量$OLDPWD是一致的.

=~

正则表达式匹配. 这个操作符由bash 版本3引入.

^

行首.在正则表达式中, 字符"^"表达匹配一个文本行的开头.

控制字符

更改终端行为或文本显示. 控制字符都是以CONTROL + key的组合键.

在脚本文件中控制字符是不起作用的.

Ctl-B

退格 (非破坏性的).

Ctl-C

中断. 终结一个前台作业.

Ctl-D

从一个shell中退出 (类似于exit).

“EOF” (文件结尾:end of file).它也用于表示标准输入(stdin)的结束.

在控制台或xterm 窗口输入文本时, Ctl-D删除在光标下的字符.如果没有字符存在,Ctl-D 则会登录出该会话. 在一个xterm窗口中,则会产生关闭此窗口的效果。

Ctl-G

“哔” (beep).在一些老式的打字机终端上,它会响一下铃.

Ctl-H

“杀掉” (破坏性的退格). 删除光标前的一个字符===.

1 #!/bin/bash
2 # 在一个字符串里嵌入 Ctl-H.
3
4 a=“HH” # 两个 Ctl-H (退格).
5 echo “abcdef” # abcdef
6 echo -n “abcdefKaTeX parse error: Expected 'EOF', got '#' at position 11: a " #̲ abcd f 7 #以…a” # abcdef
9 # 现在没有尾部的空格 不退格了 (为什么?).
10 # 结果和预料的不一样.
11 echo; echo

Ctl-I

水平制表符.

Ctl-J

新行(换一行并到行首).

Ctl-K

垂直制表符.

在控制台或xterm 窗口输入文本时, Ctl-K 会删除从光标所在处到行尾的所有字符。

Ctl-L

清屏 (重绘屏幕,清除前面的打印信息).这与clear命令作用相同.

Ctl-M

回车.

1 #!/bin/bash
2 # 多谢Lee Maschmeyer的例子.
3
4 read -n 1 -s -p $‘Control-M leaves cursor at beginning of this line. Press Enter. \x0d’
5 # 是的, '0d’是Control-M的十六进制值.
6 echo >&2 # '-s’使所有被键入的字符都不回显,
7 #+ 所以需要明确地键入新行.
8
9 read -n 1 -s -p $‘Control-J leaves cursor on next line. \x0a’
10 echo >&2 # Control-J 是换行.
11
12 ###
13
14 read -n 1 -s -p KaTeX parse error: Expected 'EOF', got '\x' at position 15: 'And Control-K\̲x̲0bgoes straight…‘\x0aThis is the bottom line\x0bThis is the top line\x0a’
20 echo “KaTeX parse error: Expected 'EOF', got '#' at position 11: var" 21 #̲ 这和上面的例子一样工作.但…var” | col
23 # 这使行的右端比左端更高.
24 # 这也解释了为什么我们以一个换行符开始和结束 –
25 #+ 是为了避免屏幕显示混乱.
26
27 # 这是Lee Maschmeyer的解释:
28 # --------------------------
29 # 在第一个垂直制表符例子中 . . . 垂直制表符使还未打印回车就直接垂直打印下来。
30 #
31 # 这只在不能“倒后”的设备里才成立,比如在Linux控制台,
32 #
33 # 垂直制表符真正的意图是能垂直地往上移,而不是往下移.
34 # 可以在打印机里用于打印上标.
35 # 这个要点的作用被用于仿效垂直制表符正确的功能.
36
37 exit 0

Ctl-Q

解冻 (XON).

它解冻终端的标准输入.

Ctl-S

挂起输入 (XOFF).

它冻结终端的标准输入. (用 Ctl-Q 可恢复输入.)

Ctl-U

删除从光标到行首的一行输入.在某些设置里,Ctl-U 删除整行的输入,而不管光标的位置.

Ctl-V

当输入一个文本, Ctl-V允许插入控制字符。例如,下面两个命令是相等的:
1 echo -e ‘\x0a’
2 echo

Ctl-V 主要用于文本编辑.

Ctl-W

当在控制台或一个xterm窗口敲入文本时, Ctl-W 会删除从在光标处往后的第一个空白符之间的内容.在某些设置里, Ctl-W 删除光标往后到第一个非文字和数字之间的字符.

Ctl-Z

暂停一个前台作业.

空白

用做函数的分隔符,分隔命令或变量. 空白是由空格(spaces),制表(tabs),空行(blank lines),或是由上述的组合造成的. [3] 在一些上下文中,比如说变量赋值, 空白是不被允许的,它会导致语法错误.

空行不会影响脚本的行为,因此使用它可以很好的划分独立的函数段以增加可读性。

特殊变量$IFS用来分隔一些输入命令的分隔符,默认是空白符。

为了在字符串或在变量中产生空白,应该使用引用.

Notes

[1]
shell处理花括号扩展. 这个命令处理扩展的结果.

[2]
例外: 作用管道一部分的花括号代码块可以在子shell中运行.
1 ls | { read firstline; read secondline; }
2 # 错误.在花括号内的代码块在一个子shell里运行,
3 #+ 以致"ls"的输出不能把值传到代码块里.
4 echo “First line is $firstline; second line is $secondline” # 这不会工作.
5
6 # 多谢, S.C.

[3]
一个换行(“新行”)也是一个空白字符。这就解释了为什么一个只包含一个换行符的空白行也被认为是空白了。

特殊字符(及其Ctrl快捷键)相关推荐

  1. Ctrl + / 快捷键失效解决方案

    ctrl + /失效 问题描述 解决方案 总结反思 问题描述   Windows11 安装 KB5010795 后,在所有IDE中均无法使用ctrl + / 快捷键注释代码,安装之前还可以用,安装之后 ...

  2. Idea使用“ctrl+/”快捷键进行 行注释 时,在//后自动添加空格

    踏破铁鞋无觅处,得来全不费工夫 废话不多说,Ctrl+Alt+S 快捷键打开setting后,根据截图设置即可:

  3. idea 缩小 放大 字体 鼠标 滚动 ctrl 快捷键

    省流: file --> setting --> keymap(键盘映射) -->搜索 font 搜font(中文版搜字体),双击 increase(增加) decrease(减少) ...

  4. 浏览器ctrl快捷键大全

    本小技巧适用于360安全浏览器和chorm浏览器 ctrl+w 关闭本窗口 ctrl+e 恢复关闭窗口 ctrl+r重载窗口 ctrl+t 新开窗口 ctrl+u查看当前网页的源代码 ctrl+o打开 ...

  5. Ctrl快捷键使用大全

    Ctrl+S 保存 Ctrl+W 关闭程序 Ctrl+N 新建 Ctrl+O 打开 Ctrl+Z 撤销 Ctrl+F 查找 Ctrl+X 剪切 Ctrl+C 复制 Ctrl+V 粘贴 Ctrl+A 全 ...

  6. linux下的ctrl快捷键使用

    ctrl键组合 ctrl+a:光标跳到行首. ctrl+b:光标左移一个字母 ctrl+c:杀死当前进程. ctrl+d: 删除提示符后一个字符或exit或logout. ctrl+e:光标移到行尾. ...

  7. c++全局监听ctrl s_号称史上最全!134个CAD快捷键强烈来袭,难道你只知道Ctrl+C?...

    想要提高CAD绘图速率你就必须熟记CAD快捷键,小编盘点了134个CAD个快捷键,号称史上最全,一起来看看吧. 一.常用字母键 CO:复制 MI:镜像 AR:阵列 O:偏移 RO:旋转 M:移动 E: ...

  8. c语言复制粘贴快捷键_大家还知道哪些快捷键方法?如:ctrl+c复制,ctrl+v粘贴

    Windows快捷键 单独按Windows:显示或隐藏"开始"功能表 Windows+BREAK:显示"系统属性"对话框 Windows+D:显示桌面 Wind ...

  9. 图解CTRL+数字符号快捷键组合,助你工作效率倍增

    欢迎关注微信公众号:excelwork 我们使用Excel的大部分动作,都是通过按键完成,Excel作为一个成熟的软件,赋予了我们超多便利.今天给大家介绍的是经常被提及的CTRL快捷键组合. 废话不多 ...

最新文章

  1. 比特大陆发布第三代AI芯片,INT8算力达17.6Tops
  2. iOS 开发 OpenGL 新手入门
  3. 最简实例说明wait、notify、notifyAll的使用方法
  4. Springboot中mongodb的使用
  5. hdu 1226(bfs+同余剪枝)
  6. Nacos配置管理-微服务配置拉取
  7. 【计算机思维】面向人的开发 站在巨人的肩膀上
  8. 复习Python DB-API
  9. [导入]C#实现WEB浏览器
  10. eclipse使用maven tomcat插件部署无法关联源代码
  11. 云服务器 ECS 搭建WordPress网站:购买 Linux 实例
  12. C#委托四(匿名方法)
  13. 宽带连接不上,拨号宽带连接的创建。
  14. 如何用UE4制作2D游戏文档(五)——战斗篇
  15. Echarts教程1_ ECharts官方教程(一)【5分钟上手ECharts】
  16. 学习Web前端的心得
  17. 记一次系统蓝屏处理IRQL_NOT_LESS_OR_EQUAL
  18. 如何科学预估开发时间
  19. Java 十进制转二进制
  20. ECharts地图显示不完整,只显示南海诸岛问题

热门文章

  1. 设置video标签的默认样式
  2. 华为汽车持续发力,夹缝中的造车新势力或已恐惧得瑟瑟发抖
  3. 浏览器主页被劫持,强制跳转hao123
  4. Logback手记(一)
  5. 修改layui框架html,模块化前端 UI 框架Layui
  6. 华为ax3怎么接光纤sc接口_华为路由器AX3 Pro与其他华为/荣耀路由器如何连接?...
  7. MOS管栅极串联电阻作用
  8. 曾“伪造”Solana七成TVL的“多重人格者”,正望向Aptos
  9. Tomb.Finance TVL突破1B大关
  10. 什么样的论文更容易通过论文检测?