时间:2017年04月10日
说明:本文部分内容均摘取自书籍《Linux命令行与shell脚本编程大全》,版权归原作者所有。《Linux命令行与shell脚本编程大全》(第三版)第五章学习总结
第五章:理解shell
本章内容:
探究shell的类型
理解shell的父子关系
别出心裁的子shell用法
探究内建的shell命令
5.1 shell的类型
系统中启动什么样的shell程序取决于你个人的用户ID配置。在/etc/passwd文件中,在用户ID记录的第七个字段中列出了默认的shell程序。
默认的用户shell是bash shell,不过还有另外一个默认shell是/bin/sh,它作为默认的系统shell,用于那些需要启动时使用的系统shell脚本。
窍门:对bash shell脚本来说,这两种不同的shell(默认的交互shell和默认的系统shell)会造成问题。一定要阅读第十一章中有关bash shell脚本首行的语法要求,以避免这些麻烦。
5.2 shell的父子关系
通过输入命令bash,生成一个子shell。再执行其它命令时,会在子shell中执行。通过ps -f命令可以查看进程的父子关系,即子进程的PPID是父进程的PID。通过ps –forest命令,可以按层次查看进程。输入exit命令,退回子进程shell,回到父进程shell。exit还能用来登出当前的虚拟控制台终端。
base中可用的命令行参数:
-c string:从string中读取命令并进行处理
-i:启动一个能够接受用户输入的交互shell
-l:以登录shell的形式启动
-r:启动一个受限shell,用户会被限制在默认的目录中
-s:从标准输入中读取命令
5.2.1 进程列表
你可以在一行中指定要依次运行的一系列命令。通过分号(;)隔开即可。
通过使用中括号将命令列表变成进程列表。
命令列表:$ pwd ; ls ;cd /etc ; cd ; pwd ; ls
进程列表:$ (pwd ; ls ;cd /etc ; cd ; pwd ; ls)
要想知道是否生成了子shell,得借助一个使用了环境变量的命令。(环境变量会在第六章中详述。)这个命令就是echo $BASH_SUBSHELL。如果该命令返回0,就表明没有子shell。如果返回1或者其他更大的数字,就表明存在子shell。
5.2.2 别出心裁的子shell用法
在交互式的shell CLI中,还有很多更富有成效的子shell用法。进程列表、协程和管道(第十一章会讲到)都利用了子shell。在交互式shell中,一个搞笑的子shell用法就是使用了后台模式。
1.探索后台模式
在后台模式中运行命令可以在处理命令的同时让出CLI,以供他用。使用sleep命令来演示。sleep命令接受一个参数,该参数是你希望进程等待(睡眠)的秒数。
命令:sleep
命令演示:sleep 10
演示说明:将会话暂停10秒钟,然后返回shell CLI提示符。
要想将命令置入后台模式,可以在命令末尾加上字符&。当命令被置入后台,在shell CLI提示符返回之前,会出现两条信息。第一条在方括号中表示后台作业号;第二条表示后台作业的进程ID。
命令:jobs
命令格式:jobs -l
命令说明:显示后台作业信息。可以显示当前运行在后台模式中的所有用户的进程。
窍门:需要提醒的是:后台作业的结束状态可未必会一直等到合适的时候才现身。当作业结束状态突然出现在屏幕上的时候,你可别吃惊啊。
2.将进程列表置入后台
之前说过,进程列表是运行在子shell中的一条或多条命令。将进程列表置入后台模式会在命令输出上表现出些许不同。
命令演示:$ (sleep 2 ; echo $BASH_SUBSHELL ; sleep 2)&
演示说明:把进程列表置入后台模式。
把进程列表置入后台模式会产生一个作业号和进程ID,然后返回到提示符。 按一下回车键,得到另一个提示符。
3.协程
协程可以同时做两件事。它在后台生成一个子shell,并在这个shell中执行命令。
命令:coproc
命令格式:coproc 命令
命令说明:要在子shell中执行coproc命令。
协程会创建子shell执行命令,同时,将命令置入后台模式。使用jobs可以查看后台任务。
命令格式:coproc 任务名 { 命令 }
命令说明:为后台任务指定任务名并执行。
5.3 理解shell的內建命令
搞明白shell的內建命令和非內建(外部)命令非常重要。內建命令和非內建命令的操作方式大不相同。
5.3.1 外部命令
外部命令,有时候也被称为文件系统命令,是存在于bash shell之外的程序。它们并不是shell程序的一部分。外部程序通常位于/bin、/usr/bin、/sbin或/usr/sbin中。ps就是一个外部命令。你可以使用which和type命令找到它。
命令演示:swich ps
演示说明:查看ps命令程序所在路径。
命令演示:type -a ps
演示说明:查看ps命令程序所在路径。
当外部命令执行时,会创建出一个子进程。这种操作被称为衍生(forking)。作为外部命令,ps命令在执行时会创建出一个子进程。
5.3.2 內建命令
內建命令和外部命令的区别在于前者不需要使用子进程来执行。它们已经和shell编译成了一体,作为shell工具的组成部分。不需要借助外部程序文件来运行。
cd和exit命令都是內建与bash shell。
命令演示:type cd
演示说明:利用type命令来了解某个命令是否是內建的。
命令演示:type -a echo
演示说明:有些命令有多种实现。使用type命令的-a选项查看命令的不同实现。
命令演示:which pwd
演示说明:which命令只显示出了外部命令文件。
窍门:对于有多种实现的命令,如果想要使用其外部命令实现,直接指明对应的文件就可以了。例如,要使用外部命令pwd,可以输入/bin/pwd。
1.使用history命令
命令:history
命令格式:history
命令说明:查看最近用过的命令列表。通常历史记录会保存最近的1000条命令。
窍门:你可以设置保存在bash历史记录中的命令数。要想实现这一点,你需要修改名为HISTSIZE的环境变量(参见第六章)。
命令格式:history -a
命令说明:将命令历史记录写入.bash_history文件。
命令演示:!!
演示活门:执行上一条命令,即刚刚执行的命令。
命令演示:!20
演示说明:执行命令在历史列表中编号为20的命令。
2.命令别名
alias命令是另一个shell的內建命令。命令别名允许你为常用的命令(及其参数)创建另一个名称,从而将输入量减少到最低。
命令:alias
命令格式:alias -p
命令说明:查看当前可用的别名。
命令格式:alias li='ls -li'
命令说明:创建一个命令别名为li的命令,由ls -li组成。命令别名只在它被定义的shell进程中才有效。不过,可以使用环境变量,使得别名在不同的shell中都凑效。
5.4 小结
本章讨论了复杂的交互式程序:GNU bash shell。其中包括理解shell进程及其关系,如何生成子shell,以及子shell与父shell的关系。主要介绍了bash、exit、&、sleep、jobs、coproc、which、type、history、!、alias命令。
本章学习命令个人总结如下:
bash:创建一个子shell进程
exit:退出子shell进程,直到退出CLI客户端
&:将任务置入后台模式
sleep:将当前进程等待(休眠)
jobs:查看所有后台作业信息
coproc:创建一个子进程,并用子进程执行任务
which:查看命令程序所在文件路径(只显示外部命令文件)
type:查看命令程序所在文件路径(通过-a选项,显示每个命令的两种实现)
history:查看命令使用的历史记录(默认1000条,可修改HISTSIZE环境变量来控制显示条数)
!:执行命令历史记录里的命令(!!执行上一条命令,!n执行命令历史列表中编号为n的命令)
alias:为命令创建别名(默认只在被创建的shell进行中有效,可修改环境变量实现所有shell进程有效)