Shell与其命令语法分析
一、什么是shell?
Shell俗称为“壳”,是一种命令解释器,类似于DOS系统下的command.com程序。
它负责将用户输入的命令提交给内核,由操作系统的内核来决定该命令是否可以执行或者说有无执行的权限。
Shell是由C语言编写的,它不仅是一种命令解析程序,shell还是功能强大的解释型程序设计语言,它可以定义各种选项和变量,几乎支持高级语言的所有程序结构,例如变量、函数、表达式和循环等。用shell可以编写shell脚本程序,类似于DOS下的批处理程序,但更加完善强大。
Linux有很多字符命令行界面即GLI(command line interface)。最为常见的是
bsh (Bourne again shell) ,其次还有
Sh (Bourn shell)
Csh (C shell)
Zsh (Z shell)
Ksh (korn shell)
tcsh (Tenex C shell)
内置命令:
是由shell自身去解释的命令,如cd、pwd、exit和echo等命令,都是bsh的内置命令。
当用户登录程序后,shell与其内置命令就会被系统一同载入至内存,并且一直运行,直到用户系统退出为止。
除了内置命令,Linux上还有许多可执行文件,可执行文件类似于Windows下的.exe文件,它可以作为shell的命令来执行。例如ls这个命令就是一个可执行文件,它在/bin/ls 中存放着,与shell的内置命令不同的是,这些外置命令或者说是可执行文件在什么时候调用,什么时候才被系统提交给内存。
Shell解释命令的过程:
Shell再接受用户输入的命令时,先检查是否为内置命令,如果是,就通过shell内部的命令解释器将命令解释为系统调用,然后提交给内核执行。
如果不是shell的内置命令,那么shell会按照用户给出的路径或者是根据系统环境变量的配置信息在硬盘中找到对应的命令,然后将其调入内存,并将其解释为系统调用,提交给内核执行。
二、shell命令的语法分析
1.shell的命令行格式
命令 选项 参数
Command options arguments
选项作用修正命令执行的方式
短选项: — character (字母)
长选项: —— word (单词)
短选项的多个选项可以组合,如 ls —a —l = ls —al;而长选项则不能组合。
很多命令都可以接受参数,参数就是跟在选项后面的一个或多个字符串,这些字符串指定了命令执行的对象,文件或目录等。例如你要查找目录 ./etc中的文件,就可以敲如下命令:
[[email protected] ~]# ls -al /etc
特殊情况下,有些命令可以不带参数,如ls命令,但是有些shell命令若不带参数会进行报错,就像mv必须要带两个参数。
[[email protected] ~]# mv door1.txt door2.txt
在shell命令行中,可以有多个命令,但要用“;”隔开,如:
[[email protected] ~]# ls -l ; cp door1.txt door2.txt
还可以在多行输入一个命令,用“\”将其持续到下一行
[[email protected] ~]# cp -i \
>door1.txt \
>door2.txt
2.shell的通配符
通配符主要是方便用户对文件或者目录的描述,例如用户仅仅需要以“.so”结尾的文件,靠通配符就可以很便捷地实现。各个版本的shell都有通配符,这些通配符是一些特殊的字符,用户可以在命令的参数中使用这些字符,进行文件名和路径名的匹配。Shell会将命令行中指定的符合匹配规则的所有文件名和路径名作为参数,然后执行这个命令。
Bsh中常用的通配符:“*”、“?”、“[ ]”。
⑴.* :匹配任意一个字符或多个字符。
例如:
[[email protected] ~]# ls *.txt
这个命令时列出当前目录中所有以“.txt”结尾的文件(除去以“.”开头的文件)。
[[email protected] ~]# cp doc/* /opt
表示将doc目录下的所有文件(除“.”开头的文件以外)拷贝到/opt目录下。
[[email protected] ~]# ls -al /etc/*/*.conf
表示在/etc目录的子目录下列出所有以“.conf”结尾的文件,但/etc目录下以“.conf”结尾的文件将不会被列出。
⑵.? :匹配任意单一字符。
例如:
[[email protected] ~]# ls ab?.txt
将列出当前目录下ab开头,随后一个字母是任意字符,接着以“.txt”结尾的文件。
[[email protected] ~]# ls ab??.txt
将列出当前目录下ab开头,随后两个字母是任意字符,接着以“.txt”结尾的文件。
⑶.[ ] :匹配任何包含在方括号内的单字符
例如:
[[email protected] ~]# ls /dev/sda[12345]
/dev/sda1 /dev/sda2 /dev/sda3 /dev/sda4 /dev/sda5
这样就列出了在/dev目录下以sda开头,第四个字符分别是1、2、3、4或5的所有文件。
[[email protected] ~]# ls /dev/sda[1-5]
这里的命令给出了[1-5]的匹配范围,与上一个命令完全等效。
⑷.通配符的组合使用
在Linux中通配符也可以组合使用。如:
[[email protected] ~]# ls [0-9]?.conf
列出当前目录下以数字开头,剩下一个是任意的字符,并且以“.conf”结尾的文件。
[[email protected] ~]# ls [xyz]*.txt
列出当前目录下分别以x、y和z开头的文件,并且以“.txt”结尾的文件。
3.shell重定向
在Linux下系统打开3个文件,即标准输入、标准输出和标准错误输出。用户的shell将键盘的输入默认为标准输入,将标准输出和标准错误输出设置为屏幕。也就是用户将键盘输入的命令,会将结果和错误输出到屏幕上。
所谓的重定向,就是不使用系统默认的标准输入输出,而是重新指定,因此重定向分为输入重定向、输出重定向和错误重定向。要实现重定向就需要了解重定向操作符。
1.输入重定向
输入重定向就是改变命令的输入源,利用输入重定向,就可以将一个文件的内容作为命令输入,而不是从键盘输入。
用于输入重定向的操作符有“<”和“<<”。例如:
[[email protected] ~]# wc </etc/inittab
53 229 1666
用wc命令统计输入给它的文件/etc/inittab的行数、单词数和字符数。
还有一种输入重定向“<<”,这种重定向告诉shell,当前命令的标准输入来自命令行中一对分隔号之间的内容。例如:
[[email protected] ~]# wc << aa
> # Default runlevel .The runlevels used by RHS are:
> # 0 - halt (Do Not set initdefault to this)
> # 1-single user mode
> # 2-Multiuser, without NFS (The same as 3,if you do not have networking )
> # 3-Full multiuser mode
> # 4-unused
> # 5-X11
> # 6-reboot (Do NOT set initdefault to this)
> aa
8 65 303
上面的命令将一对分隔号aa之间的内容作为wc命令的输入。分隔号可以是任意字符。Shell将在第一个分隔符后开始读取内容,直到出现另一个分隔号读取结束,然后将内容送给wc命令处理。
2.输出重定向
输出重定向是将命令的输出结果不在屏幕出,而是输入到指定文件中。
在Linux下输出定向用的很多,例如,某个命令的输出很长,一个屏幕无法显示完毕,我们可以将命令的输出指定到一个文件,然后用more这个命令查看这个文件,从而得到命令输出的完整信息。
用于输出重定向的操作符有“>”和“>>”。例如:
[[email protected] ~]#ps -ef >ps.txt
将ps -ef 输出的系统运行进程信息全部输入到了ps.txt文件,而不是输出到屏幕,可用more命令查看ps.txt文件。
[[email protected] ~]#more file1 file2 file3 file3 >file
more命令是查看文件的内容,上面的命令是将file1、file2 和file3的内容全部输出到file
文件中,类似于文件内容的合并。
如果在“>”后面指定的文件不存在的话,shell就会自动重建一个;如果文件已经存在的话,那么这个文件原有的内容将被覆盖;如果不想覆盖存在的文件,可以使用“>>”操作符。例如:
[[email protected] ~]# ls -al /etc/* >>/root/install.log
将/etc 目录及子目录下的所有文件信息追加到/root/install.log文件的后面。/root/install.log文件原来的内容仍然存在。
3.错误重定向
错误重定向和标准输出重定向一样,可以使用操作符“2>”和“2>>”实现对错误输出的重定向。例如:
[[email protected] ~]# tar zxvf text.tar.gz 2> error.txt
Tar是打包命令,可以在屏幕上显示tar的解压过程。如果“text.tar.gz”是个损坏压缩包,就会把错误信息输出到error.txt文件。
4.shell的管道:|
管道可以把很多命令连接起来,可以把第一个命令的输入当做第二个命令的输出,第二个命令的输出当做第三个命令的输入,以此类推。因此,管道的作用就是把一个命令的输出当做是下一个命令的输入,而不经过任何中间文件。
通过管道符“|”可以建立一个管道连接,例如:
[[email protected] ~]# ls -al /etc/* |more
表示将/etc目录及其子目录下的所有文件分屏显示。
[[email protected] ~]#ps -ef|grep httpd |wc -l
这个命令是查看系统中正在运行的httpd进程,并计算httpd的进程数。
5.shell中的引用
在bash中有很多特殊字符在,这些字符本身就有特殊含义。如果在shell参数中使用它们,就会出现问题。Linux中使用了“引用”技术来忽略这些字符的特殊含义,引用技术就是通知shell将这些特殊字符当做普通字符处理。Shell中用于引用的字符有转义字符“\”、单引号“’’”、双引号“”””。
①.转义字符“\”
如果将“\”放到特殊字符前面,shell就忽略这些特殊字符的原有含义,当作普通字符对待,例如:
[[email protected] ~]# ls
abc?* C:\backup
[[email protected] ~]#mv abc\?\* abc
[[email protected] ~]#mv C\: \ \backup backup
上面是将abc?*重命名为abc ,将C:\backup重命名为backup。因为文件名中含有特殊字符,所有都使用了转义字符“\”。
②.单引号“’’”
将字符串放到一对单引号之间,那么字符串中所有字符的特殊含义将被忽略,例如:
[[email protected] ~]#mv C\: \ \backup backup
[[email protected] ~]#mv ‘ C:\backup’ backup
上面两条命令完全等效。
③.双引号“”””
双引号的引用与单引号基本相同,包含在双引号内的大部分特殊字符可以当做普通字符处理,但是仍有一些特殊字符即使双引号括起来,也仍然保留自己特殊含义,比如“$”、“\”和“`”。
[[email protected] ~]#str=”the \$SHELL Current shell is $SHELL”
[[email protected] ~]#str=”\$$SHELL”
[[email protected] ~]#echo $str
The $SHELL Current shell is /bin/bash
[[email protected] ~]#echo $str1
$ /bin/bash
从上面的输出中可以看出,字符“$”和“\”在双引号内仍然保留了特殊含义。
[[email protected] ~]#str=”This hostname is ‘hostname’”
[[email protected] ~]#echo $str
This hostname is WEBServer
上面的输出中,字符“`”在双引号中也保留了自己的特殊含义。
6.shell的自动补齐命令行:Tab
自动补齐命令行是bash一个简单而且实用的功能,自动补齐命令行也就是在输入命令时不必把命令输全,shell就能智能判断用户所要输入的命令。
当用户输入某个命令的一部分后,按下“Tab”键,shell就会根据系统环境变量信息提示出与用户输入命令相似的所有命令和文件,例如:
[[email protected] ~]# if <按Tab键>
if ifcfg ifconfig ifdown ifenslave ifnames ifrename ifup
[[email protected] ~]# if
可以从上面看到,用户输入“if”后按“Tab”键,即可显示以“if”为前缀的所有命令和文件。如果需要的是ifconfig命令,那么只需要再次输入“co”,然后按“Tab”键,shell就能不全命令。
如果我们要进入一个很深的目录中,并且每个目录的名字又很长,此时利用bash的自动不全功能,就在好不过了。