bash shell 父子关系及内外命令

shell 类型

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

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

CentOS发行版中还有其他一些shell程序。其中包括tcsh、ash shell、csh等。他们的程序位于/bin目录内

$ ls -lF /bin/bash
-rwxr-xr-x. 1 root root 938832 Jul 18 2013 /bin/bash*
$ls -lF /bin/tcsh
-rwxr-xr-x. 1 root root 387328 Feb 21 2013 /bin/tcsh*
$ls -lF /bin/dash
-rwxr-xr-x. 1 root root 109672 Oct 17 2012 /bin/dash*
$ls -lF /bin/csh
lrwxrwxrwx. 1 root root 4 Mar 18 15:16 /bin/csh -> tcsh*
$

要使用其他可用的shell,只需要输入对应的文件名就行了 

$ /bin/dash
$
$ exit
exit
$

shell 的父子关系

终端仿真器时所启动的默认的交互shell,是一个父shell。在CLI提示符后输入/bin/bash命令或其他等效的bash命令时,会创建一个新的shell程序。这个shell程序被称为子shell(child shell)。

$ ps -f
UID PID PPID C STIME TTY TIME CMD
501 1841 1840 0 11:50 pts/0 00:00:00 -bash
501 2532 1841 1 14:22 pts/0 00:00:00 ps -f
$
$ bash
$
$ bash
$
$ bash
$
$ ps --forest
PID TTY TIME CMD
1841 pts/0 00:00:00 bash
2533 pts/0 00:00:00     \_ bash
2546 pts/0 00:00:00         \_ bash
2562 pts/0 00:00:00             \_ bash
2576 pts/0 00:00:00                 \_ ps
$
  • 进程列表

要是想在一行中指定要依次运行的一系列命令。这可以通过命令列表来实现,只需要在命令之间加入分号(;)

$ 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来执行对应的命令。

$ (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
$

我们利用命令echo $BASH_SUBSHELL来检查是否生成子shell,该命令返回0,就表明没有子shell。如果返回
1或者其他更大的数字,就表明存在子shell。

$ ( pwd ; echo $BASH_SUBSHELL)
/home/Christine
1
$ ( pwd ; (echo $BASH_SUBSHELL))
/home/Christine
2
  • 后台模式

在后台模式中运行命令可以在处理命令的同时让出CLI,以供他用;你既可以在子shell中进行繁重的处理工作,同时也不会让子shell的I/O受制于终端。。演示后台模式的一个经典命令就是sleep。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
$

第一条信息是显示在方括号中的后台作业(background job)号(1)。第二条是后台作业的进程ID(2396)。jobs命令可以显示出当前运行后台模式中的所有用户的进程(作业)。

$ jobs
[1]+ Running sleep 3000 &
$ jobs -l
[1]+ 2396 Running sleep 3000 &
$

一旦后台作业完成,就会显示出结束状态

[1]+ Done sleep 3000 &
  • 将进程列表置入后台

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

使用tar创建备份文件是有效利用后台进程列表的一个更实用的例子。

$ (tar -cf Rich.tar /home/rich ; tar -cf My.tar /home/christine)&
[3] 2423
$
  • 协程

携程可以同时做两件事情,在后台生成一个子shell,并在子shell中执行命令。利用coproc命令进行协程处理。

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

将协程与进程列表结合起来产生嵌套的子shell

$ coproc (sleep 10;sleep 2)
[1] 2574
$ jobs
[1]+ Running coproc COPROC ( sleep 10; sleep 2 ) &
$ ps --forest
PID TTY TIME CMD
2483 pts/12 00:00:00 bash
2574 pts/12 00:00:00   \_ bash
2575 pts/12 00:00:00 |    \_ sleep
2576 pts/12 00:00:00         \_ ps

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 ps
-rwxr-xr-x 1 root root 93232 Jan 6 18:32 /bin/ps

作为外部命令,ps执行时会创建一个子进程

  • 内建命令

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

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

有些命令有多种实现。例如echo和pwd既有内建命令也有外部命令。两种实现略有不同。要查看命令的不同实现,使用type命令的-a选项。which命令只显示出了外部命令文件

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

history命令。bash shell会跟踪你用过的命令。你可以唤回这些命令并重新使用。

$ history
1 ps -f
2 pwd
[...]

命令历史记录被保存在隐藏文件.bash_history中,它位于用户的主目录中。

$ cat .bash_history

唤回历史列表中任意一条命令。只需输入惊叹号和命令在历史列表中的编号即可

$ history
[...]
20 type -a pwd
$ !20
type -a pwd
pwd is a shell builtin
pwd is /bin/pwd
$

alias命令允许你为常用的命令及参数创建另一个名称,从而减少输入量,你所使用的Linux发行版很有可能已经为你设置好了一些常用命令的别名。要查看当前可用的别名,使用alias命令以及选项-p。

$ alias -p
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'

可以使用alias命令创建属于自己的别名

$ alias li='ls -li'
$ li

猜你喜欢

转载自blog.csdn.net/linshuo1994/article/details/83986721