shell的类型
etc/passwd的最后一个字段标识shell类型
bash shell程序位于/bin目录内。从长列表中可以看出/bin/bash(bash shell)是一个可执行程序
用软链接将默认的系统shell设置成bash shell
如何创建一个子shell?
bash
[root@iZ8vbis43wevefdej5xq5yZ ~]# bash [root@iZ8vbis43wevefdej5xq5yZ ~]# [root@iZ8vbis43wevefdej5xq5yZ ~]# bash [root@iZ8vbis43wevefdej5xq5yZ ~]# [root@iZ8vbis43wevefdej5xq5yZ ~]# bash [root@iZ8vbis43wevefdej5xq5yZ ~]# [root@iZ8vbis43wevefdej5xq5yZ ~]# ps j PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 1 950 950 950 ttyS0 950 Ss+ 0 0:00 /sbin/agetty 1 951 951 951 tty1 951 Ss+ 0 0:00 /sbin/agetty 1507637 1507842 1507842 1507842 pts/0 1507871 Ss 0 0:00 bash 1507842 1507871 1507871 1507842 pts/0 1507871 S+ 0 0:00 mysql -u roow 1539719 1539720 1539720 1539720 pts/0 1539850 Ss 0 0:00 -bash 1539750 1539751 1539751 1539751 pts/1 1539751 Ss+ 0 0:00 -bash 1539720 1539799 1539799 1539720 pts/0 1539850 S 0 0:00 bash 1539799 1539816 1539816 1539720 pts/0 1539850 S 0 0:00 bash 1539816 1539833 1539833 1539720 pts/0 1539850 S 0 0:00 bash 1539833 1539850 1539850 1539720 pts/0 1539850 R+ 0 0:00 ps j [root@iZ8vbis43wevefdej5xq5yZ ~]# [root@iZ8vbis43wevefdej5xq5yZ ~]# ps --forest PID TTY TIME CMD 1539720 pts/0 00:00:00 bash 1539799 pts/0 00:00:00 \_ bash 1539816 pts/0 00:00:00 \_ bash 1539833 pts/0 00:00:00 \_ bash 1539852 pts/0 00:00:00 \_ ps
第一个bash是当前终端的bash,紧接着三个bash 是使用bash命令创建的bash环境。ps j 是在最内层的shell执行的。
ps显示说明
小括号
pwd ; ls ; cd /etc ; pwd ; cd ; pwd ; ls
在上面的例子中,所有的命令依次执行,不存在任何问题。不过这并不是进程列表。
命令列表要想成为进程列表,这些命令必须包含在括号里。这样才会开启一个子shell执行。
$ (pwd ; ls ; cd /etc ; pwd ; cd ; pwd ; ls)
注意: 另一种命令分组是将命令放入花括号中,并在命令列表尾部加上分号(;)。语法为{ command; }。使用花括号进行命令分组并不会像进程列表那样创建出子shell。
如何验证是否开启了子shell
echo $BASH_SUBSHELL
返回值大于0 代表开启了子shell。
返回0,就表明没有子shell
如下图:
什么是shell的后台模式?
运行命令可以在处理命令的同时让出当前终端,以供他用。
- & 符号可以将命令放在后台执行
- 可以使用jobs -l 看到jobid 和 pid。([2] 代表的就是jobId,又称为后台作业(background job)号
- )
- 通过fg命令将后台命令可以返回到前台执行,调用方式是fg %2
- [2]+ +符号代表 CPU当前正在执行的进程
- -符号代表操作系统下次调度的进程
~]# sleep 300 & [2] 1539933 [root@iZ8vbis43wevefdej5xq5yZ ~]# ps -f UID PID PPID C STIME TTY TIME CMD root 1507842 1507637 0 Dec17 pts/0 00:00:00 bash root 1507871 1507842 0 Dec17 pts/0 00:00:00 mysql -u roowe -p root 1539720 1539719 0 16:18 pts/0 00:00:00 -bash root 1539933 1539720 0 17:37 pts/0 00:00:00 sleep 300 root 1539936 1539720 0 17:37 pts/0 00:00:00 ps -f [root@iZ8vbis43wevefdej5xq5yZ ~]# jobs -l [2]+ 1539933 Running sleep 300 & [root@iZ8vbis43wevefdej5xq5yZ ~]# [root@iZ8vbis43wevefdej5xq5yZ ~]# fg %2 sleep 300
后台job的状态
子shell与协程
协程可以同时做两件事。它在后台生成一个子shell,并在这个子shell中执行命令。
shell中的协程,使用命令 coproc。
重命名协程
发送或接收来自子shell中进程的信息。只有在拥有多个协程的时候才需要对协程进行命名,它们之间进行通信。
coproc my_job { sleep 20; } # {}前后要有空格,切命名结尾要有;
通过{ } 时通过子shell执行sleep。
注意: 生成子shell是有成本的。所以应该尽量避免可以为你减少debug时间和环境变量的问题。
什么时候进入新的shell环境?