Linux学习笔记(五)

第五章 理解shell

1.shell的类型

系统启动什么样的shell程序取决于你的人的用户ID配置。在/etc/passwd文件中,用户ID记录的第7个字段中列出了默认的shell程序,只要用户登录到某个虚拟机控制台终端或是在GUI中启动终端仿真器,默认的shell程序就会开始运行。

$ cat /etc/passwd
[...]
Christine:x:501:501:Christine B:/home/Christine:/bin/bash

上图配置的是bash,其他的shell程序还有tcsh(CentOS)dash(Debian)。这些shell都可以被设置为用户默认的shell。

2.shell的父子关系

用户登录某个虚拟机控制器终端或在GUI中运行终端仿真器时所启动的默认的交互shell,是一个父shell(下图PID1841的shell)。在CLI提示符后输出/bin/bashbash命令时(CLI内不会有任何显示),会创建一个新的shell程序。这个shell程序被称为子shell(child shell)。子shell(PID2430的shell)也拥有CLI提示符,同样会等待命令输入。

$ ps -f
UID PID PPID C STIME TTY TIME CMD
501 1841 1840 0 11:50 pts/0 00:00:00 -bash
501 2429 1841 4 13:44 pts/0 00:00:00 ps -f
$
$ bash
$
$ ps -f
UID PID PPID C STIME TTY TIME CMD
501 1841 1840 0 11:50 pts/0 00:00:00 -bash
501 2430 1841 0 13:44 pts/0 00:00:00 bash
501 2444 2430 1 13:44 pts/0 00:00:00 ps -f

在这里插入图片描述

exit命令可以退出子shell,还能用来登出当前的虚拟机控制台终端或终端仿真器软件,只需要在父shell中输入exit,就能够退出CLI。

进程列表

命令列表:允许你在一行中指定要依次运行的一系列命令,只需要在命令之间加入;即可。

$ pwd ; ls ; cd /etc ; pwd ; cd ; pwd ; ls
/home/Christine
Desktop Downloads Music Public Videos
Documents junk.dat Pictures Templates
/etc
/home/Christine
Desktop Downloads Music Public Videos
Documents junk.dat Pictures Templates

进程列表:将命令列表放在括号中就成为了进程列表。

$ (pwd ; ls ; cd /etc ; pwd ; cd ; pwd ; ls)
/home/Christine
Desktop Downloads Music Public Videos
Documents junk.dat Pictures Templates
/etc
/home/Christine
Desktop Downloads Music Public Videos
Documents junk.dat Pictures Templates

括号的加入使命令列表变成了进程列表,生成了一个子shell来执行对应的命令。可以查看环境变量(BASH_SUBSHELL,第六章介绍)来确定是否生成了子进程。使用命令echo $BASH_SUBSHELL,如果返回0表示没有子shell,返回≥1表明存在子shell。

$ pwd ; echo $BASH_SUBSHELL
/home/Christine
0
$ (pwd ; echo $BASH_SUBSHELL)
/home/Christine
1

可以在命令列表中嵌套括号来创建子shell的子shell。

$ ( pwd ; echo $BASH_SUBSHELL)
/home/Christine
1
$ ( pwd ; (echo $BASH_SUBSHELL))
/home/Christine
2

在shell脚本中,经常使用子shell进行多进程处理。

有趣的shell用法

后台模式:可以在运行命令的同时让出CLI,以供他用。sleep命令接受一个参数,表示希望进程等待(休眠)的秒数。如果要想命令置入后台模式,可以在命令末尾加上字符&

$ sleep 3000&
[1] 2396
$ ps -f
UID PID PPID C STIME TTY TIME CMD
christi+ 2338 2337 0 10:13 pts/9 00:00:00 -bash
christi+ 2396 2338 0 10:17 pts/9 00:00:00 sleep 3000
christi+ 2397 2338 0 10:17 pts/9 00:00:00 ps -f

sleep命令会在后台(&)休眠3000秒。shell CLI提示符返回之前,会出现两条信息,后台作业号(background job)1,后台进程ID(2396)。

jobs命令可以显示当前运行在后台模式中的所有用户的进程(作业)信息。

$ jobs
[1]+ Running sleep 3000 &

jobs显示了作业号(1),当前状态(running),对应命令(sleep 3000 &)。

后台模式非常方便,可以在CLI中创建有意义的子shell。

将进程列表置入后台

可以将进程列表置入后台模式,允许你在子shell中进行耗时的工作,同时也不会让子shell的I/O受制于终端。

$ (sleep 2 ; echo $BASH_SUBSHELL ; sleep 2)&
[2] 2401
$ 1
[2]+ Done ( sleep 2; echo $BASH_SUBSHELL; sleep 2 )
$

协程

协程可以同时做两件事,在后台生成一个子shell,并在这个子shell中执行命令。命令为coproc

$ coproc sleep 10
[1] 2544

除了会创建子shell外,协程将命令置入后台模式。

$ jobs
[1]+ Running coproc COPROC sleep 10 &

可以使用命令的拓展语法自定义协程名称。(第一个{和命令之前必须有一个空格,以;结尾,;}之间也必须有一个空格)

$ coproc My_Job { sleep 10; }
[1] 2570
$
$ jobs
[1]+ Running coproc My_Job { sleep 10; } &
3.理解shell的内建命令

外部命令

也称为文件系统命令,是存在于bash shell之外的程序。外部命令并不是shell程序的一部分,外部命令程序通常位于/bin/usr/bin/sbin/usr/sbin中。

ps就是一个外部命令,可以使用whichtype命令查看命令程序的位置。

$ which ps
/bin/ps
$
$ type -a ps
ps is /bin/ps
$
$ ls -l /bin/ps
-rwxr-xr-x 1 root root 93232 Jan 6 18:32 /bin/ps

当外部命令执行时,会创建一个子进程。这种操作叫做衍生(forking)

$ ps -f
UID PID PPID C STIME TTY TIME CMD
christi+ 2743 2742 0 17:09 pts/9 00:00:00 -bash
christi+ 2801 2743 0 17:16 pts/9 00:00:00 ps -f

在这里插入图片描述

内建命令

与外部命令区别在于不需要使用子进程来执行。内建命令已经和shell编译成了一体,作为shell工具的组成部分存在,不需要借助外部程序文件来运行。

$ type cd
cd is a shell builtin
$
$ type exit
exit is a shell builtin

因为既不需要通过衍生出子进程来执行,也不需要打开程序文件,内建命令的执行速度快,效率更高。有些命令有多种实现,例如echopwd既有内建命令也有外部命令。可以通过type -a查看。

$ type -a echo
echo is a shell builtin
echo is /bin/echo
$
$ which echo
/bin/echo
$
$ type -a pwd
pwd is a shell builtin
pwd is /bin/pwd
$
$ which pwd
/bin/pwd

type -a命令显示了每个命令的两种实现,which命令只显示了外部命令文件。

一些有用的内建命令

history:查看最近用过的命令列表。通常历史记录会保存最近的1000条命令。命令历史记录被保存在隐藏文件.bash_history中,文件位于用户的主目录中。bash命令的历史记录是先存放在内存中,当shell退出时才被写入到历史文件中。可以在退出shell会话之前强制命令历史记录写入到.bash_history文件中,使用history -a命令。可以唤回历史列表中任意一条命令,只需要输入!和命令在历史列表中的编号即可。

$ history
19 which echo
20 type -a pwd
21 type -a echo
$
$ !20
type -a pwd
pwd is a shell builtin
pwd is /bin/pwd

alias:命令别名允许你为常用的命令(以及参数)创建另一个名称,从而将输入量减少到最低。可以使用alias -p查看当前可用的别名。

$ alias -p
[...]
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'

可以使用alias命令创建属于自己的别名(常用,提升工作效率)。

$ alias li='ls -li'
$
$ li
total 36
529581 drwxr-xr-x. 2 Christine Christine 4096 May 19 18:17 Desktop

在定义好别名之后,可以随时在shell中使用,也可以在shell脚本中使用。命令别名属于内部命令,一个别名仅在它所被定义的shell进程中有效。(可以修改shell的配置文件.bashrc对所有shell起作用)

本章小结

​ 1.介绍了shell的类型

​ 2.父进程与子进程

​ 3.shell的内建命令和外部命令

参考文献:Linux命令行与shell脚本编程大全(第三版)Richard Blum Christine Bresnahan著 门佳 武海峰译

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搬砖小张

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值