暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Linux Bash Shell基础知识全览

志芯 2019-06-30
513

shell是用户和Linux操作系统之间的接口。Linux中有多种shell,其中缺省使用的是Bash。本文讲述了shell的工作原理,shell的种类,shell的一般操作及Bash的特性。

1 什么是shell

Linux系统的shell作为操作系统的外壳,为用户提供使用操作系统的接口。它是命令语言、命令解释程序及程序设计语言的统称。

shell是用户和Linux内核之间的接口程序,如果把Linux内核想象成一个球体的中心,shell就是围绕内核的外层。当从shell或其他程序向Linux传递命令时,内核会做出相应的反应。


shell是一个命令语言解释器,它拥有自己内建的shell命令集,shell也能被系统中其他应用程序所调用。用户在提示符下输入的命令都由shell先解释然后传给Linux核心。


有一些命令,比如改变工作目录命令cd,是包含在shell内部的。还有一些命令,例如拷贝命令cp和移动命令rm,是存在于文件系统中某个目录下的单独的程序。对用户而言,不必关心一个命令是建立在shell内部还是一个单独的程序。


shell首先检查命令是否是内部命令,若不是再检查是否是一个应用程序(这里的应用程序可以是Linux本身的实用程序,如ls和rm,也可以是购买的商业程序,如xv,或者是自由软件,如emacs)。然后shell在搜索路径里寻找这些应用程序(搜索路径就是一个能找到可执行程序的目录列表)。如果键入的命令不是一个内部命令并且在路径里没有找到这个可执行文件,将会显示一条错误信息。如果能够成功找到命令,该内部命令或应用程序将被分解为系统调用并传给Linux内核。


shell的另一个重要特性是它自身就是一个解释型的程序设计语言,shell程序设计语言支持绝大多数在高级语言中能见到的程序元素,如函数、变量、数组和程序控制结构。shell编程语言简单易学,任何在提示符中能键入的命令都能放到一个可执行的shell程序中。


当普通用户成功登录,系统将执行一个称为shell的程序。正是shell进程提供了命令行提示符。作为默认值(TurboLinux系统默认的shell是BASH),对普通用户用“$”作提示符,对超级用户(root)用“#”作提示符。


一旦出现了shell提示符,就可以键入命令名称及命令所需要的参数。shell将执行这些命令。如果一条命令花费了很长的时间来运行,或者在屏幕上产生了大量的输出,可以从键盘上按ctrl+c发出中断信号来中断它(在正常结束之前,中止它的执行)。


当用户准备结束登录对话进程时,可以键入logout命令、exit命令或文件结束符(EOF)(按ctrl+d实现),结束登录。

  我们来实习一下shell是如何工作的。

  $ make work

  make:***No rule to make target ‘work’. Stop.

  $

注释:make是系统中一个命令的名字,后面跟着命令参数。在接收到这个命令后,shell便执行它。本例中,由于输入的命令参数不正确,系统返回信息后停止该命令的执行。


在例子中,shell会寻找名为make的程序,并以work为参数执行它。make是一个经常被用来编译大程序的程序,它以参数作为目标来进行编译。在 “make work”中,make编译的目标是work。因为make找不到以work为名字的目标,它便给出错误信息表示运行失败,用户又回到系统提示符下。


另外,用户键入有关命令行后,如果shell找不到以其中的命令名为名字的程序,就会给出错误信息。例如,如果用户键入:

  $ myprog

  bash:myprog:command not found

  $

可以看到,用户得到了一个没有找到该命令的错误信息。用户敲错命令后,系统一般会给出这样的错误信息。

2 shell的种类

Linux中的shell有多种类型,其中最常用的几种是Bourne shell(sh)、C shell(csh)和Korn shell(ksh)(另外,Bourne Again shell(简称bash)是Bourne shell的增强版本)。三种shell各有优缺点。Bourne shell是UNIX最初使用的shell,并且在每种UNIX上都可以使用。Bourne shell在shell编程方面相当优秀,但在处理与用户的交互方面做得不如其他几种shell。Linux操作系统缺省的shell是Bourne Again shell,它是Bourne shell的扩展,简称Bash,与Bourne shell完全向后兼容,并且在Bourne shell的基础上增加、增强了很多特性。Bash放在/bin/bash中,它有许多特色,可以提供如命令补全、命令编辑和命令历史表等功能,它还包含了很多C shell和Korn shell中的优点,有灵活和强大的编程接口,同时又有很友好的用户界面。


C shell是一种比Bourne shell更适于编程的shell,它的语法与C语言很相似。Linux为喜欢使用C shell的人提供了Tcsh。Tcsh是C shell的一个扩展版本。Tcsh包括命令行编辑、可编程单词补全、拼写校正、历史命令替换、作业控制和类似C语言的语法,它不仅和Bash shell是提示符兼容,而且还提供比Bash shell更多的提示符参数。


Korn shell集合了C shell和Bourne shell的优点并且和Bourne shell完全兼容。Linux系统提供了pdksh(ksh的扩展),它支持任务控制,可以在命令行上挂起、后台执行、唤醒或终止程序。


Linux并没有冷落其他shell用户,还包括了一些流行的shell如ash、zsh等。每个shell都有它的用途,有些shell是有专利的,有些能从Internet网上或其他来源获得。要决定使用哪个shell,只需读一下各种shell的联机帮助,并试用一下。

3 bash shell命令行

用户在登录到Linux时由/etc/passwd文件来决定要使用哪个shell。例如:

  # fgrep lisa /etc/passwd

  lisa:x:500:500:TurboLinux User:/home/lisa:/bin/bash

shell被列每行的末尾(/bin/bash)。

由于Bash是Linux上默认的shell,本章主要介绍Bash及其相关知识。


用户登录到Linux系统时,可以看到一个shell提示符,标识了命令行的开始。用户可以在提示符后面输入任何命令及参数。例如:

  $ date

  11 23 01:34:58 CST 2019

用户登录时,实际进入了shell,它遵循一定的语法将输入的命令加以解释并传给系统。命令行中输入的第一个字必须是一个命令的名字,第二个字是命令的选项或参数,命令行中的每个字必须由空格或TAB隔开,格式如下:

  $ Command Option Arguments 


3.1选项和参数

选项是包括一个或多个字母的代码,它前面有一个减号(减号是必要的,Linux用它来区别选项和参数),选项可用于改变命令执行的动作的类型。例如:

  $ ls

  motd passwd

  $

这是没有选项的ls命令,可列出当前目录中所有文件,只列出各个文件的名字,而不显示其他更多的信息。

  $ ls -l

  total 2

  -rw-r--r-- 2 wzh book 22 Apr 20 20:37 motd

  -rw-r--r-- 2 wzh book 796 Apr 20 20:37 passwd

  $

加入-l选项,将会为每个文件列出一行信息,诸如数据大小和数据最后被修改的时间。


大多数命令都被设计为可以接纳参数。参数是在命令行中的选项之后键入的一个或多个单词,例如:

  $ ls -l text

  -rw-r--r-- 2 wzh book 22 Apr 20 20:37 motd

  -rw-r--r-- 2 wzh book 796 Apr 20 20:37 passwd

  $

将显示text目录下的所有文件及其信息。


有些命令,如ls可以带参数,而有一些命令可能需要一些最小数目的参数。例如,cp命令至少需要两个参数,如果参数的数目与命令要求不符,shell将会给出出错信息。例如:

  $ cp -i mydata newdata

注意:命令行中选项先于参数输入。


3.2命令行特征

命令行实际上是可以编辑的一个文本缓冲区,在按回车之前,可以对输入的文本进行编辑。比如利用BACKSPACE键可以删除刚键入的字符,可以进行整行删除,还可以插入字符,使得用户在输入命令,尤其是复杂命令时,若出现键入错误,无须重新输入整个命令,只要利用编辑操作,即可改正错误。


利用上箭头可以重新显示刚执行的命令,利用这一功能可以重复执行以前执行过的命令,而无须重新键入该命令。


bash保存着以前键入过的命令的列表,这一列表被称为命令历史表。按动上箭头,便可以在命令行上逐次显示各条命令。同样,按动下箭头可以在命令列表中向下移动,这样可以将以前的各条命令显示在命令行上,用户可以修改并执行这些命令。


在一个命令行中还可以置入多个命令,用分号将各个命令隔开。例如:

  $ ls -F;cp -i mydata newdata

 也可以在几个命令行中输入一个命令,用反斜杠将一个命令行持续到下一行。

  $ cp –i  \

  mydata    \

  newdata

上面的cp命令是在三行中输入的,开始的两行以反斜杠结束,把三行作为一个命令行。

4 bash shell功能 

4.1 命令记忆功能

history [选项] [历史命令保存文件]

选项:

-c:   清空历史命令

-w:   把缓存中的历史命令写入历史命令保存文件  ~/.bash_history

vim /etc/profile中的 Histsize可改存储历史命令数量

历史命令的调用

使用上、下箭头调用以前的历史命令

使用“!n”重复执行第n条历史命令

使用“!!”重复执行上一条命令

使用“!字串”重复执行最后一条以该字串开头的命令。


在很多版本中,bash shell默认的命令记忆功能可以达到1000个。意味着,你曾经执行过的命令几乎都被记录下来了。


4.2 命令与文件补全

[Tab]键补齐功能最开始也是在bash中才有的(当然现在很多命令行指令都有这种功能)。经常在bash中使用[Tab]可以少打字且保证输入正确。


在Bash中,命令与文件补全是非常方便与常用的功能,我们只要在输入命令或文件时,按“Tab”键就会自动进行补全。


[Tab]接在一串命令的第一个字后面,则为命令补全。[Tab]接在一串命令的第二个字以后时,则为文件补齐。


4.3 命令别名

alias 别名=‘原命令’

#设定命令别名

alias

#查询命令别名

备注:

命令执行顺序:

1 第一顺位  绝对路径或相对路径命令

2 第二顺位  别名命令

3 第三顺位 执行bash的内部命令

4 第四顺位 执行按照$PATH环境变量定义的目录查找顺序找到的第一个命令。


让别名永久生效

vi /root/.bashrc

vi /home/lsx/.bashrc


删除别名

unalias  别名


4.4作业控制、前台、后台控制

Shell支持作用控制,有以下命令实现前后台切换:

  1. command& 让进程在后台运行

  2. jobs 查看后台运行的进程

  3. fg %n 让后台运行的进程n到前台来

  4. bg %n 让进程n到后台去
  5. kill %n 杀死job

其中"n"为jobs命令查看到的job编号,不是进程编号。


fg、bg、jobs、&、ctrl + z都是跟系统任务有关的,虽然现在基本上不怎么需要用到这些命令,但学会了也是很实用的。


& 最经常被用到,这个用在一个命令的最后,可以把这个命令放到后台执行;ctrl + z;可以将一个正在前台执行的命令放到后台,并且暂停;jobs,查看当前有多少在后台运行的命令。Fg,将后台中的命令调至前台继续运行,如果后台中有多个命令,可以用 fg %jobnumber将选中的命令调出;bg将一个在后台暂停的命令,变成继续执行,如果后台中有多个命令,可以用bg %jobnumber将选中的命令调出,%jobnumber是通过jobs命令查到的后台正在执行的命令的序号(不是pid)。


4.5 程序脚本

DOS年代就有把一堆命令写在一起的所谓“批处理文件”。Linux下面的shell script则发挥更为强大的功能,可以将你平时管理系统需要执行的连续命令写成一个文件,该文件并且可以通过交互的方式进行主机的检测工作。也可以通过shell提供的环境变量及相关命令来进行设计。整个设计下来几乎就是一个小型的程序语言了。该script的功能真是超乎我们的想象之外。

5bash shell中的特殊字符

5.1特殊符号(#)

注释符号(Hashmark[Comments])

1.在shell文件的行首,作为shebang标记,#!/bin/bash;

2. 其他地方作为注释使用,在一行中,#后面的内容并不会被执行,除非;

3. 但是用单/双引号包围时,#作为#号字符本身,不具有注释作用。


5.2特殊符号(;)

作为多语句的分隔符(Command separator [semicolon])。

多个语句要放在同一行的时候,可以使用分号分隔。注意,有时候分号需要转义。


5.3特殊符号(;;)

连续分号(Terminator [double semicolon])。

在使用case选项的时候,作为每个选项的终结符。在Bash version 4+ 的时候,还可以使用[;;&], [;&]。


5.4特殊符号(.)

点号(dot command [period])。

1. 相当于bash内建命令source,如:

#!/bin/bash

. data-file

#包含data-file;

2. 作为文件名的一部分,在文件名的开头,表示该文件为隐藏文件,ls一般不显示出来(ls -a 可以显示);

3. 作为目录名,一个点代表当前目录,两个点号代表上层目录(当前目录的父目录)。注意,两个以上的点不出现,除非你用引号(单/双)包围作为点号字符本身;

4. 正则表达式中,点号表示任意一个字符。


5.5特殊符号(")

双引号(partial quoting [double quote])。

部分引用。双引号包围的内容可以允许变量扩展,也允许转义字符的存在。如果字符串内出现双引号本身,需要转义,因此不一定双引号是成对的。


5.6特殊符号(')

单引号(full quoting [single quote])。

单引号括住的内容,被视为单一字符串,引号内的禁止变量扩展,所有字符均作为字符本身处理(除单引号本身之外),单引号必须成对出现。


5.7特殊符号(,)

逗号(comma operator [comma])。

1. 用在连接一连串的数学表达式中,这串数学表达式均被求值,但只有最后一个求值结果被返回。如:

#!/bin/bash

let t1=((a=5+1, b=7+2))

echo t1=$t1, a=$a, b=$b

## 这个$t1=$b;

2. 用于参数替代中,表示首字母小写,如果是两个逗号,则表示全部小写,注意,这个特性在bash version 4的时候被添加的。例子:

a="ATest"

echo ${a,}

echo ${a,,}

## 前面输出aTest,后面输出的是atest。


5.8特殊符号(\)与特殊符号(/)

反斜线,反斜杆(escape [backslash])。

1. 放在特殊符号之前,转义特殊符号的作用,仅表示特殊符号本身,这在字符串中常用;

2. 放在一行指令的最末端,表示紧接着的回车无效(其实也就是转义了Enter),后继新行的输入仍然作为当前指令的一部分。

斜线,斜杆(Filename path separator [forward slash])。

1.作为路径的分隔符,路径中仅有一个斜杆表示根目录,以斜杆开头的路径表示从根目录开始的路径;

2.在作为运算符的时候,表示除法符号。如:a=4/2。


5.9特殊符号(`)

反引号,后引号(Command substitution[backquotes])。

命令替换。这个引号包围的为命令,可以执行包围的命令,并将执行的结果赋值给变量。如:a=`dirname '/tmp/x.log'` 。

后面dirname返回的结果会赋值给a,注意,此处Mitchell特地使用了反引号和单引号,注意区别。


5.10特殊符号(!)

感叹号(reverse (or negate) [bang],[exclamation mark])。

取反一个测试结果或退出状态。

1. 表示反逻辑,比如后面的!=,这个是表示不等于;

2. 表示取反,如:ls a[!0-9] #表示a后面不是紧接一个数字的文件;

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

4. 在命令行中,可以用于历史命令机制的调用,你可以试试!$,!#,或者!-3看看,不过要注意,这点特性不能在脚本文件里面使用(被禁用)。


5.11特殊符号(*)

星号(wildcard/arithmetic operator[asterisk])。

1. 作为匹配文件名扩展的一个通配符,能自动匹配给定目录下的每一个文件;

2. 正则表达式中可以作为字符限定符,表示其前面的匹配规则匹配任意次;

3. 算术运算中表示乘法。


5.12特殊符号($)

美元符号(Variable substitution[Dollar sign])。

1. 作为变量的前导符,用作变量替换,即引用一个变量的内容,比如:echo $PATH;

2. 在正则表达式中被定义为行末(End of line)。


5.13特殊符号(${})

参数替换(Variable substitution)。

用于在字符串中表示变量。


5.14特殊符号($‘...’)

引用内容展开,执行单引号内的转义内容(单引号原本是原样引用的),这种方式会将引号内的一个或者多个[\]转义后的八进制,十六进制值展开到ASCII或Unicode字符。


5.15特殊符号($*或$@)

位置参数(Positional Parameters)。

这个在使用脚本文件的时候,在传递参数的时候会用到。两者都能返回调用脚本文件的所有参数,但$*是将所有参数作为一个整体返回(字符串),而$@是将每个参数作为单元返回一个参数列表。注意,在使用的时候需要用双引号将$*,$@括住。这两个变量受到$IFS的影响,如果在实际应用中,要考虑其中的一些细节。


5.16特殊符号($#)

表示传递给脚本的参数数量。


5.17特殊符号($?)

此变量值在使用的时候,返回的是最后一个命令、函数、或脚本的退出状态码值,如果没有错误则是0,如果为非0,则表示在此之前的最后一次执行有错误。


5.18特殊符号($$)

进程ID变量,这个变量保存了运行当前脚本的进程ID值。


5.19特殊符号(())

圆括号(parentheses)。

1, 命令组(Command group)。由一组圆括号括起来的命令是命令组,命令组中的命令实在子shell(subshell)中执行。因为是在子shell内运行,因此在括号外面是没有办法获取括号内变量的值,但反过来,命令组内是可以获取到外面的值,这点有点像局部变量和全局变量的关系,在实作中,如果碰到要cd到子目录操作,并在操作完成后要返回到当前目录的时候,可以考虑使用subshell来处理;

2. 用于数组的初始化。


5.20特殊符号({x,y,z,...})

花括号扩展(Brace Expansion)。

在命令中可以用这种扩展来扩展参数列表,命令将会依照列表中的括号分隔开的模式进行匹配扩展。注意的一点是,这花括号扩展中不能有空格存在,如果确实有必要空格,则必须被转义或者使用引号来引用。例子:echo {a,b,c}-{\ d," e",' f'}


5.21特殊符号({})

代码块(curly brackets)。

这个是匿名函数,但是又与函数不同,在代码块里面的变量在代码块后面仍能访问。注意:花括号内侧需要有空格与语句分隔。另外,在xargs -i中的话,还可以作为文本的占位符,用以标记输出文本的位置。


5.22特殊符号({} \;)

这个{}是表示路径名,这个并不是shell内建的,现在接触到的情况看,好像只用在find命令里。注意后面的分号,这个是结束find命令中-exec选项的命令序列,在实际使用的时候,要转义一下以免被shell理解错误。


5.23特殊符号([])

中括号(brackets)。

1. 测试的表示,Shell会测试在[]内的表达式,需要注意的是,[]是Shell内建的测试的一部分,而非使用外部命令/usr/bin/test的链接;

2. 在数组的上下文中,表示数组元素,方括号内填上数组元素的位置就能获得对应位置的内容,如:

Array[1]=xxx

echo ${Array[1]};

3. 表示字符集的范围,在正表达式中,方括号表示该位置可以匹配的字符集范围。


5.24特殊符号([[]])

双中括号(double brackets)。

这个结构也是测试,测试[[]]之中的表达式(Shell的关键字)。这个比单中括号更能防止脚本里面的逻辑错误,比如:&&,||,<,>操作符能在一个[[]]里面测试通过,但是在[]却不能通过。[[]]里面没有文件名扩展(filename expansion)或是词分隔符(Word splitting),但是可以用参数扩展(Parameter expansion)和命令替换(command substitution)。不用文件名通配符和像空白这样的分隔符。注意,这里面如果出现了八进制,十六进制等,shell会自动执行转换比较。


5.25特殊符号($[...])

词表达表示整数扩展(integer expansion)。

在方括号里面执行整数表达式。例:

a=3

b=7

echo $[$a+$b]

echo $[$a*$b]

##返回是10和21


5.26特殊符号((()))

双括号(double parentheses)。

表示整数扩展(integer expansion)。功能和上面的$[]差不多,但是需要注意的是,$[]是会返回里面表达式的值的,而(())只是执行,并不会返回值。两者执行后如果变量值发生变化,都会影响到后继代码的运行。可对变量赋值,可以对变量进行一目操作符操作,也可以是二目,三目操作符。


5.27特殊符号(> , &< ,>&,>>,<,<> )

重定向(redirection)。

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),文件不存在就会创建。


5.28特殊符号((command)>,<(command) )

这是进程替换(Process Substitution)。

使用的时候注意,括号和<,>之间是不能有空格的,否则报错。其作用有点类似通道,但和管道在用法上又有些不同,管道是作为子进程的方式来运行的,这个命令会在/dev/fd/下面产生类似/dev/fd/63,/dev/fd/62这类临时文件,用来传递数据。

Mitchell个人猜测之所以用这种方法来传递,是因为前后两个不属于同一个进程,因此需要用共享文件的方式来传递资料(这么说其实管道也应该有同样的文件?)。网上有人说这个只是共享文件而已,但是经过测试,发现虽然有/dev/fd/63这样的文件产生,但是这个文件其实是指向pipe:[43434]这样的通道的链接。


5.29特殊符号(<<)

双小于号(here-document[double less then marks])。

这个也被称为Here-document,用来将后继的内容重定向到左侧命令的stdin中。<<可以节省格式化时间,别且使命令执行的处理更容易。在实作的时候只需要输入<<和终止标志符,而后(一般是回车后)你就可以输入任何内容,只要在最后的新行中输入终止标志符,即可完成数据的导入。使用here-document的时候,你可以保留空格,换行等。如果要让shell脚本更整洁一点,可以在<<和终止符之间放上一个连字符(-)。


5.30特殊符号(<<<)

三个小于号(here-strings)。Here-字串和Here-document类似,here-strings语法:command [args] <<<["]$word["];$word会展开并作为command的stdin。


5.31特殊符号(>, <)

小于,大于号(ASCII Comparison)。

ASCII比较,进行的是变量的ASCII比较,字串?数字?呃...这个...不就是ASCII比较么?


5.32特殊符号(\<...\>)

词界符(word boundary)。

这个是用在正则表达式中的一个特殊分隔符,用来标记单词的分界。比如:the会匹配there,another,them等等,如果仅仅要匹配the,就可以使用这个词界符,\<the\>就只能匹配the了。


5.33特殊符号(|)

管道(pipe)。管道是Linux,Unix都有的概念,是非常基础,也是非常重要的一个概念。它的作用是将管道前(左边)的命令产生的输出(stdout)作为管道后(右边)的命令的输入(stdin)。如:ls | wc l,使用管道就可以将命令连接在一起。注意:管道是每一个进程的标准输出都会作为下一个命令的标准输入,期间的标准输出不能跨越管道作为后继命令的标准输入,如:cat filename | ls -al | sort 。想想这个的输出? 同时,管道是以子进程来运行的,所以管道并不能引起变量改变。


5.34特殊符号(>|)

强制重定向(force redirection)。

这会强制重写已经存在的文件。


5.35特殊符号(&)

与号(Run job in background[ampersand])。

如果命令后面跟上一个&符号,这个命令将会在后台运行。有的时候,脚本中在一条在后台运行的命令可能会引起脚本挂起,等待输入,出现这种情况可以在原有的脚本后面使用wait命令来修复。


5.36特殊符号(&&,||)

逻辑操作符(logical operator)。

在测试结构中,可以用这两个操作符来进行连接两个逻辑值。||是当测试条件有一个为真时返回0(真),全假为假;&&是当测试条件两个都为真时返回真(0),有假为假。


5.37特殊符号(-)

减号,连字符(Hyphen/minus/dash)。

1. 作为选项,前缀[option, prefix]使用。用于命令或者过滤器的选项标志;操作符的前缀。如:

## COMMAND -[选项列表]

ls -al

sort -dfu $file

set -- $variable


if [ $file -ot $file2 ]

then

    echo "$file is older than $file2."

fi

2. 用于stdin或者stdout的重定向的源或目的[dash].在tar没有bunzip2的程序补丁时,我们可以这样:bunzip2 linux-2.6.13.tar.bz2 | tar xvf - 。将前面解压的数据作为tar的标准输入(这里使用一个-表示)

注意:在实作的时候,如果文件名是以[-]开头的,那么在加上这个作为定向操作符的时候,可能会出错,此时应该为文件加上合适的前缀路径,以避免这种情况发生,同样的,在echo变量的时候,如果变量是以[-]开始,那么可能也会产生意想不到的结果,为了保险起见,可以使用双引号引用标量:

var="-n"

echo $var

## 试试看有什么输出?

还有,这种表示方法不是Bash内建的,要达到此点的这种效果,需要看你使用的软件是否支持这种操作;

3. 表示先前的工作目录(previous working directory),因此,如果你cd到其他目录下要放回前一个路径的时候,可以使用cd -来达到目的,其实,这里的[-]使用的是环境变量的$OLDPWD,注意:这里的[-]和前一点是不同的;

4. 减号或者负号,用在算术操作中。


5.38特殊符号(=)

等号(Equals)。

1. 赋值操作,给变量赋值,么有空格在等号两侧;

2. 在比较测试中作为比较符出现,这里要注意,如果在中括号中作为比较出现,需要有空格符在等号左右两侧。


5.39特殊符号(~)

波浪号(Home directory[tilde])。

这个和内部变量$HOME是一样的。默认表示当前用户的家目录(主目录),这个和~/效果一致,如果波浪号后面跟用户名,表示是该用户的家目录。


5.40特殊符号(^)

脱字符(caret)。

1. 在正则表达式中,作为一行的行首(beginning-of-line)位置标志符;

2. 在参数替换(Parameter substitution)中,这个用法有两种,一个脱字符(${var^}),或两个(${var^^}),分别表示第一个字母大写,全部大写的意思(Bash version >=4)。


5.41特殊符号(:)

冒号(null command [colon])。

空命令,这个命令什么都不做,但是有返回值,返回值为0(即:true)。这个命令的作用非常奇妙。

1. 可做while死循环的条件;

2. 在if分支中作为占位符(即某一分支什么都不做的时候);

3. 放在必须要有两元操作的地方作为分隔符,如:: ${username=`whoami`}

4. 在参数替换中为字符串变量赋值,在重定向操作(>)中,把一个文件长度截断为0(:>>这样用的时候,目标存在则什么都不做),这个只能在普通文件中使用,不能在管道,符号链接和其他特殊文件中使用;

5. 甚至你可以用来注释(#后的内容不会被检查,但:后的内容会被检查,如果有语句如果出现语法错误,则会报错);

6. 你也可以作为域分隔符,比如环境变量$PATH中,或者passwd中,都有冒号的作为域分隔符的存在;

7. 你也可以将冒号作为函数名,不过这个会将冒号的本来意义转变(如果你不小心作为函数名,你可以使用unset -f : 来取消function的定义)。


5.42特殊符号(**)


双星号(double asterisk)。算术运算中表示求幂运算。


5.43特殊符号(?)

问号(test operator/wildcard[Question mark])。

1. 表示条件测试;

2. 在双括号内表示C风格的三元操作符((condition?true-result:false-result));

3. 参数替换表达式中用来测试一个变量是否设置了值;

4. 作为通配符,用于匹配文件名扩展特性中,用于匹配单个字符;

5. 正则表达式中,表示匹配其前面规则0次或者1次。


5.44特殊符号({a..z})

在Bash version 3时添加了这种花括号扩展的扩展,可以使用{A..Z}表示A-Z的所有字符列表,这种方式的扩展Mitchell测试了一下,好像仅适用于A-Z,a-z,还有数字{最小..最大}的这种方式扩展。


5.45特殊符号(+)

加号(Plus)。

1. 算术操作符,表示加法;

2. 在正则表达式中,表示的是其前的这个匹配规则匹配最少一次;

3.在命令或过滤器中作为选项标记,在某些命令或者内置命令中使用+来启用某些选项,使用-来禁止;

4. 在参数替换(parameter substitution)中,+前缀表示替代值(当变量为空的时候,使用+后面的值)


5.46特殊符号(%)

百分号(modulo[percent sign])。

1.在算术运算中,这个是求模操作符,即两个数进行除法运算后的余数;

2. 在参数替换(parameter substitution)中,可以作为模式匹配。例子:

p=b*9

var="abcd12345abc479"

echo ${var%p}, ${var%%p}

##从右边开始查找(想想从左是那个符号?)

##任何在b和9之间的内容(含)

##第一个是找到最短的符合匹配项

##后一个是找最大符合的匹配项(贪婪匹配?)


5.47特殊符号(~+)

当前的工作目录(current working directory)。

这个和内置变量$PWD一样。


5.48特殊符号(~-)

前一个工作目录(previous working directory)。

这个和内部变量$OLDPWD一致,之前的[-]也一样。


5.49特殊符号(=~)

Bash 版本3中有介绍,这个是正则表达式匹配。可用在[[]]测试中,比如:

var="this is a test message."

[[ "$var" =~ tf*message ]] && echo "Sir. Found that." || echo "Sorry Sir. No match be found."


5.50特殊符号(空白)

空白符(Whitespace)。

空白符不仅仅是指空格(spaces),还包括制表符(tabs),空行(blank lines),或者这几种的组合。可用做函数的分隔符,分隔命令或变量,空行不会影响脚本的行为,因此可以用它来规划脚本代码,以增加可读性,在内置的特殊变量$IFS可以用来针对某些命令进行输入的参数进行分割,其默认就是空白符。在字符串或变量中如果有空白符,可以使用引号来规避可能的错误。


文章转载自志芯,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论