Bash中的特殊字符

Bash中,用在脚本和其他地方的字符叫做特殊字符。下面依次举例介绍每个字符的用途。

#

行首以#(#!是个例外)开头是注释。

# This line is a comment.

注释也可以放在于本行命令的后边。

echo "A comment will follow."   # 注释在这里。

命令是不能放在同一行上注释的后边的。因为没有办法把注释结束掉,好让同一行上后边的”代码生效”,只能够另起一行来使用下一个命令。

在echo中转义的#是不能作为注释的,同样也可以出现在特定的参数替换结构中,或者是出现在数字常量表达式中。

echo "The # here does not begin a comment."
echo 'The # here does not begin a comment.'
echo The \# here does not begin a comment.    #转义字符\
echo The # 这里开始一个注释.
echo ${PATH#*:}   # 参数替换, 不是一个注释
echo $(( 2#101011 ))   # 数制转换, 不是一个注释

标准的引用和转义字符" ' \可以用来转义#,某些特定的模式匹配操作也可以使用#

;

分号作为命令行分隔符,可以在同一行上写两个或两个以上的命令。

echo hello; echo there

if [ -x "$filename" ]; then
    echo "File $filename exists.";
else
    echo "File $filename not found."; touch $filename
fi; echo "File test complete."

在某些情况下,也可以被转义。

;;

终止case选项。

case "$variable" in
    abc) echo "\$variable = abc" ;;
    xyz) echo "\$variable = xyz" ;;
esac

.

点命令等价于source命令,这是一个bash的内建命令。

如果点放在文件名的开头的话,那么这个文件将会成为”隐藏”文件,并且ls命令将不会正常的显示出这个文件。

如果作为目录名的话,一个单独的点代表当前的工作目录,而两个点表示上一级目录。

点也可以表示当前目录。

cp /home/javachen/current_work/* .

当用作匹配字符的作用时,通常都是作为正则表达式的一部分来使用,点用来匹配任何的单个字符。

",'

双引号为部分引用,单引号为全引用。

echo "The # here does not begin a comment."
echo 'The # here does not begin a comment.'

,

逗号操作费,链接了一系列的算术操作。 虽然里边所有的内容都被运行了,但只有最后一项被返回。

let "t2 = ((a = 9, 15 / 3))" # a = 9   t2 = 15 / 3

也可以这样使用:

mkdir -p {a,b,c}  #创建三个目录a、b、c

\

转义符,一种对单字符的引用机制,通常是用于对单字符进行转义。\通常用来转义"',这样双引号和但引号就不会被解释成特殊含义了。

/

文件名路径分隔符,分隔文件名不同的部分,也可以用来作为除法算术操作符。

/home/bozo/projects/Makefile
let "t2 = ((a = 9, 15 / 3))" # a = 9   t2 = 15 / 3

`

命令替换,command结构可以将命令的输出赋值到一个变量中去。

date=`date`

:

空命令,等价于”NOP”,什么都不做,也可以被认为与shell的内建命令true作用相同。”:”命令是一个bash的内建命令,它的退出码是”true”,即为0。

:
echo $? # 0

死循环:

while :   # while true
do
    date
done

在 if/then 中的占位符,什么都不做,引出分支。

if condition
then :          # 什么都不做,引出分支
else
    take-some-action
fi

在一个二元命令中提供一个占位符。

n=1
: $((n = $n + 1))  # 如果没有":"的话,Bash 将会尝试把 $((n = $n + 1)) 解释为一个命令,运行时会报错
echo -n "$n "

在here document中提供一个命令所需的占位符或者用于注释代码。

: <<TESTVARIABLES
${HOSTNAME?}${USER?}${MAIL?} # 如果其中某个变量没被设置, 那么就打印错误信息.
TESTVARIABLES

: <<COMMENTBLOCK
echo "This line will not echo."
This is a comment line missing the "#" prefix.
This is another comment line missing the "#" prefix.
&*@!!++=
The above line will cause no error message,
because the Bash interpreter will ignore it.
COMMENTBLOCK

使用参数替换来评估字符串变量。

: ${HOSTNAME ?} ${USER?} ${MAIL?}  #如果一个或多个必要的环境变量没被设置的话,就打印错误信息.

在与>重定向操作符结合使用时,将会把一个文件清空,但是并不会修改这个文件的权限。如果之前这个文件并不存在,那么就创建这个文件。

: > data.xxx  # 文件"data.xxx" 现在被清空了
# 与 cat /dev/null >data.xxx 的作用相同
# 然而,这并不会产生一个新的进程,因为":"是一个内建命令

在与>>重定向操作符结合使用时,将不会对预先存在的目标文件产生任何影响。如果这个文件之前并不存在,那么就创建它。这只适用于正规文件,,而不适用于管道、符号连接和某些特殊文件

: >> target_file

也可能用来作为注释行,虽然我们不推荐这么做。使用#来注释的话,将关闭剩余行的错误检查,所以可以在注释行中写任何东西。然而,使用:的话将不会这样。

: This is a comment that generates an error, ( if [ $x -eq 3] fi ).

”:”还用来在/etc/passwd和$PATH变量中做分隔符。

echo $PATH
/usr/java/default/bin:/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

!

取反操作符。操作符将会反转命令的退出码的结果:

true        # "true" 是内建命令
echo "exit status of \"true\" = $?"         # 0

! true
echo "exit status of \"! true\" = $?"       # 1

如果一个命令以!开头,那么会启用Bash的历史机制。

true
!true
# 这次就没有错误了, 也没有反转结果.它只是重复了之前的命令(true).

在另一种上下文中,如命令行模式下,!还能反转bash的历史机制。需要注意 的是,在一个脚本中,历史机制是被禁用的。

$ history |head -n 10
   18  date
   19  ls
   20  cd
   21  pwd
   22  jps
   23  java
   24  ll
   25  ps
   26  history

#执行bash历史中的一条命令
$ !25

操作符还是Bash的关键字。

在一个不同的上下文中,也会出现在变量的间接引用中。

a=letter_of_alphabet
letter_of_alphabet=z

# 直接引用.
echo "a = $a"   # a = letter_of_alphabet

# 间接引用.
eval a=\$$a
echo "Now a=$a"    #Now a = z

# 间接引用.
echo ${!a}  # a = z

*

用来做文件名匹配:

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

也可以用在正则表达式中,用来匹配任意个数(包含0个)的字符。

在算术操作符的上下文中, *号表示乘法运算。如果要做幂运算,使用**,这是求幂操作符。

测试操作符。在一个特定的表达式中,?用来测试一个条件的结果。

在一个双括号结构中,?就是C语言的三元操作符。

(( t = a<45?7:11 )) # C语言风格的三元操作

在参数替换表达式中,?用来测试一个变量是否set。

在通配中,用来做匹配单个字符的”通配符”,在正则表达式中,也是用来表示一个字符。

$

变量替换中,用于引用变量的内容。

var1=5
echo $var1

在一个变量前面加上$用来引用这个变量的值。

在正则表达式中,表示行结束符。

${} 是参数替换,$*$@是位置参数,$? 是退出状态码变量,$$是进程id变量,保存所在脚本的进程 ID。

()

命令组:

(a=hello; echo $a)

在括号中的命令列表,将会作为一个子shell来运行。

例外: 在pipe中的一个大括号中的代码段可能运行在一个 子shell中。

ls | { read firstline; read secondline; }

#错误. 在大括号中的代码段, 将运行到子shell中, 所以"ls"的输出将不能传递到代码块中
echo "First line is $firstline; second line is $secondline"  # 不能工作

初始化数组:

Array=(element1 element2 element3)

{xxx,yyy,zzz,...}

大括号扩展:

cat {file1,file2,file3} > combined_file

cp file22.{txt,backup} # 拷贝"file22.txt"到"file22.backup"中

一个命令可能会对大括号中的以逗号分的文件列表起作用。在通配符中,将对大括号中的文件名做扩展。

在大括号中,不允许有空白,除非这个空白引用或转义。

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

{}

代码块,又被称为内部组,这个结构事实上创建一个匿名函数。与”标准”函数不同的是,在其中的变量,对于脚本其他部分的代码来还是可见的。

{ local a; a=1; }
-bash: local: can only be used in a function
a=123
{ a=321; }
echo "a = $a"  # a = 321 (说明在代码块中对变量a所作的修改影响了外边的变量)

下边的代码展示在大括号结构中代码的I/O 重定向。

#!/bin/bash
# 从/etc/fstab中读行. 3
File=/etc/fstab

{
 read line1
 read line2
} < $File

echo "First line in $File is:" "$line1"
echo "Second line in $File is:" "$line2"
exit

与上面所讲到的()中的命令组不同的是,大括号中的代码块将不会开一个新的子shell。

'{}' \;

路径名。一般都在find命令中使用,这不是一个shell内建命令。;用来结束find命令序列的-exec选项,它需要被保护以防止被shell所解释。

find . -mtime -1 -type f -exec tar rvf archive.tar '{}' \;

[]

条件测试。

在一个array结构的上下文中,中括号用来引用数组中每个元素的编号。

Array[1]=a
echo ${Array[1]}

用作正则表达式的一部分,方括号描一个匹配的字符范围。例如,正则表达式中,”[xyz]” 将会匹配字符x, y, 或z。

[[ ]]

测试表达式在[[ ]]中。

(( ))

双圆括号结构,扩展并计算在(( ))中的整数表达式。

与let命令很相似,((...))结构允许算术扩展和赋值。举个简单的例子,a=$(( 5 + 3 )),将把变量”a”设为”5 + 3”或者8。

> &> >& >> < <>

重定向。

重定向scriptname的输出到文件filename中。如果filename存在的,那么将会被覆盖:

scriptname >filename

也可以清空文件内容:

> a.log

重定向command的stdout和stderr到filename中:

command &>filename

重定向command的stdout到stderr中:

command >&2

把scriptname的输出加到文件filename中。如果filename不存在的话,将被创建。

scriptname >> filename

打开文件filename用来读写,并且分配文件描述符i给这个文件。如果filename不存在,这个文件将会创建:

[i]<>filename

”<”或”>”还可以用于进程替换

在一种不同的上下文中,”<”和”>”可用来做字符串比较操作或者整数比较。

<<

用在here document中的重定向。

<<<

用在here string中的重定向。

\<,\>

正则表达式中的单词边:

grep '\<the\>' textfile

|

管道。分析前边命令的输出,并将输出作为后边命令的输入。这是一种产生命令链的好方法。

# 与一个简单的"ls -l"结果相同
echo ls -l | sh

# 合并和排序所有的".lst"文件, 然后删除所有重复的行.
cat *.lst | sort | uniq

输出的命令也可以传递到脚本中:

#!/bin/bash
# uppercase.sh : 修改输入, 全部转换为大写

tr 'a-z' 'A-Z'

exit 0

现在我们输送ls -l的输出到该脚本中:

$ ls -l | ./uppercase.sh
DRWXR-X--- 2 ROOT ROOT      4096 05-28 10:06 ML-1M
-RW-R--R-- 1 ROOT ROOT         0 2014-11-21 MONITOR_DISK.TXT
DRWXR-XR-X 2 ROOT ROOT      4096 2014-11-21 SCRIPT
-RW-R--R-- 1 ROOT ROOT        16 07-06 16:09 UPPERCASE.SH

管道中的每个进程的stdout比下一个进程作为stdin来读入,否则,数据流会阻塞,并且管道将产生一些非预期的行为:

# 从"cat file1 file2"中的输出并没出现
cat file1 file2 | ls -l | sort

作为子进程的运行的管道,不能够改变脚本的变量:

variable="initial_value"
echo "new_value" | read variable
echo "variable = $variable" # variable =initial_value

如果管道中的这个命令产生一个异常,并中途失败,那么这个管道将过早的终止,这种行为叫做broken pipe,并且这种状态下将发送一个SIGPIPE信号。

>|

强制重定向(使设置noclobber选项,就是-C选项),这将强制的覆盖一个现存文件。

||

或操作,在一个条件测试结构中,如果条件测试结构两边中的任意一边结果为true的话,||操作就会返回0(代表执行成功)。

&

后台运行命令,一个命令后边跟一个&表示在后台运行。

sleep 10 &

在一个脚本中,命令和循环都可能运行在后台:

for i in1 2 3 4 5 6 7 8 9 10
do
    echo -n "$i "
done &

在一个脚本中,使用后台运行命令可能会使这个脚本挂起,直到敲ENTER 键,挂起的脚本才会恢复。看起来只有在这个命令的结果需要输出到stdout的时候,这种现象才会出现。

只要在后台运行命令的后边加上一个wait命令就会解决这个问题。

#!/bin/bash
# test.sh

ls -l &
echo "Done."
wait

如果将后台运行命令的输出重定向到文件中或/dev/null中,也能解决这个问题。

&&

与逻辑操作。在一个条件测试结构中,只有在条件测试结构的两边结果都为true的时,&&操作才会返回0(代表sucess)。

-

选项,前缀。在所有的命令内如果使用选项参数的话,前边都要加上-

ls -al

sort -dfu $filename

set -- $variable

if [ $file1 -ot $file2 ]
then
    echo "File $file1 is older than $file2."
fi

用于重定向stdin或stdout:

# 从一个目录移动整个目录树到另一个目录
(cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xpvf -)

# 当然也可以这样写:
cp -a /source/directory/* /dest/directory
cp -a /source/directory/* /source/directory/.[^.]* /dest/directory  # 如果在/source/directory中有隐藏文件的话

bunzip2 -c linux-2.6.16.tar.bz2 | tar xvf -

注意,在这个上下文中,-本身并不是一个Bash操作,而是一个可以被特定的UNIX工具识别的选项,这些特定的UNIX工具特指那些可以写输出到stdout的工具,比如tar、cat等等。

$ echo "whatever" | cat -
whatever

使用diff命令来和另一个文件的一段进行比较:

grep Linux file1 | diff file2 -

一个更真实的例子是备份最后一天所有修改的文件:

#!/bin/bash

BACKUPFILE=backup-$(date +%m-%d-%Y)

# 如果在命令行中没有指定备份文件的文件名,那么将默认使用"backup-MM-DD-YYYY.tar.gz"
archive=${1:-$BACKUPFILE}

tar cvf - `find . -mtime -1 -type f -print` > $archive.tar

# 还有两种简单写法:
# find . -mtime -1 -type f -print0 | xargs -0 tar rvf  "$archive.tar"
# find . -mtime -1 -type f -exec tar rvf "$archive.tar" '{}' \;

gzip $archive.tar

echo "Directory $PWD backed up in archive file \"$archive.tar.gz\"."

exit 0

-还可以用来指先前的工作目录,cd -将会回到当前的工作目录,它使用了 $OLDPWD 环境变量。

另外,还可以当做减号来使用。

=

等号,赋值操作。

+

加号,也可以用在正则表达式中。某些内建命令使用+来打开特定的选项,用-来用这些特定的选项。

%

取模操作,也可以用于正则表达式。

~

home目录。

~+

当前工作目录,相当于$PWD内部变量。

~-

当前的工作目录,相当于$OLDPWD内部变量。

^

行首,在正则表达式中,^表示定位到文本行的行首。

控制字符

修改终端或文本显示的行为。控制字符以CONTROL + key这种方式进行组合(同时按下)。控制字符也可以使用8进制或16进制表示法来进行表示,但是前边必须要加上转义符。

控制字符比较多,这里不一一列出了。

空白

用来分隔函数,命令或变量。空白包含空格、tab、空行,或者是它们之间任意的组合体。在某些上下文中,比如变量赋值,空白是不被允许的,会产生语法错误。

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

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

如果想在字符串或变量中使用空白,那么应该使用引用。例如下面例子:

hello="A B  C   D"
echo $hello                  # A B C D
echo "$hello"               # A B  C   D
时间: 2024-10-03 04:06:57

Bash中的特殊字符的相关文章

Bash 中的特殊字符大全

Linux下无论如何都是要用到shell命令的,在Shell的实际使用中,有编程经验的很容易上手,但稍微有难度的是shell里面的那些个符号,各种特殊的符号在我们编写Shell脚本的时候如果能够用的好,往往能给我们起到事半功倍的效果,为此,特地将Shell里面的一些符号说明罗列成对照表的形式,以便快速的查找.看看你知道下表中的哪些Shell符号呢? Shell符号及各种解释对照表: Shell符号 使用方法及说明 # 注释符号(Hashmark[Comments]) 1.在shell文件的行首,

Bash中的变量

变量是脚本编程中进行数据表现的一种方法.说白了,变量不过是计算机为了保留数据项,而在内存中分配的一个位置或一组位置的标识或名字.变量既可以出现在算术操作中,也可以出现在字符串分析过程中. 变量赋值 变量使用=来实现赋值操作,前后都不能有空白.例如: a=314 echo "The value of \"a\" is $a." 也可以使用let来赋值: let a=16+5 echo "The value of \"a\" is now

网页(HTML)中的特殊字符

网页 一般来说,在HTML中,一个特殊字符有两种表达方式,一种称作数字参考,一种称作实体参考. 所谓数字参考,就是用数字来表示文档中的特殊字符,通常由前缀"",加上数值,再加上后缀";"而组成,它可以采用如下两种方式.D; 其中D是一个十进制数值 下面是一些特殊字符的数字参考示例: 对应于特殊字符"" 对应于特殊字符"" 所谓实体参考,实际上就是用有意义的名称来表示特殊字符,通常由前缀"&",加上字

解决在ASP中执行数据库查询中的特殊字符的问题

解决在ASP中执行数据库查询中的特殊字符的问题 在进行数据库的查询时,会经常遇到这样的情况: 例如想在一个用户数据库中查询他的用户名和他的密码,但恰好该用户使用的名字和密码中有特殊的字符,例如单引号,"|"号 双引号或者连字符"&". 例如他的名字是1'test,密码是A|&900 这时当你执行以下的查询语句时,肯定会报错: SQL = "SELECT * FROM SecurityLevel WHERE UID='" &

正则表达式中的特殊字符一览

正则 正则表达式中的特殊字符: 字符 意义:对于字符,通常表示按字面意义,指出接着的字符为特殊字符,不作解释. 例如:/b/匹配字符'b',通过在b 前面加一个反斜杠,也就是/b/,则该字符变成特殊字符,表示 匹配一个单词的分界线. 或者: 对于几个字符,通常说明是特殊的,指出紧接着的字符不是特殊的,而应该按字面解释. 例如:*是一个特殊字符,匹配任意个字符(包括0个字符):例如:/a*/意味匹配0个或多个a. 为了匹配字面上的*,在a前面加一个反斜杠:例如:/a*/匹配'a*'. 字符^ 意义

如何在win7电脑中编辑特殊字符?

  如何在win7电脑中编辑特殊字符?那么下面小编就以ghost win7 64位旗舰版下载为例,为大家具体介绍一下方法吧! 1.首先,咱们直接单击键盘上的windows图标或者是鼠标左键点击左下角的开始菜单,然后在弹出来的窗口中找到下方的搜索框,咱们在搜索框中输入字符编辑并单击回车,这样就可以打开电脑中自带的字符编辑程序了,如下图中所示. 2.接下来,咱们点击上方任务栏中的窗口-参照,然后咱们就可以在打开的窗口中选定自己需要的字符来作为参照,并可以截取其中咱们需要的部分,之后挪到左侧窗口中.

中文匹配-bash中怎么匹配中文字符

问题描述 bash中怎么匹配中文字符 正则表达式[u4e00-u9fa5]在shell中为什么匹配不出中文,且在grep中报出grep:Invalid range end,我想在shell中匹配输入的中文该怎么做呢 解决方案 Bash 字符匹配正则匹配中文字符中文字符及其中文标点符号正则表达式匹配 解决方案二: 还要看bash是对中文如何编码的,不然没办法直接匹配.

cordova 发起的请求,用于登录,当密码中存在特殊字符时,URL会被截断,.net端接收不全

问题描述 cordova 发起的请求,用于登录,当密码中存在特殊字符时,URL会被截断,.net端接收不全 $.ajax({ type: "get", url: "http://192.168.0.1:80/AppService.asmx/Login", data: "{UserID: '123',Password:'123456*#' }", dataType: "json", success: function(data)

bash中 2&gt;&amp;1 &amp; 的解释

bash中 2>&1 & 的解释 1.首先,bash中0,1,2三个数字分别代表STDIN_FILENO.STDOUT_FILENO.STDERR_FILENO,即标准输入(一般是键盘),标准输出(一般是显示屏,准确的说是用户终端控制台),标准错误(出错信息输出). 2.输入输出可以重定向,所谓重定向输入就是在命令中指定具体的输入来源,譬如 cat < test.c 将test.c重定向为cat命令的输入源.输出重定向是指定具体的输出目标以替换默认的标准输出,譬如ls >