Shell学习:理解Shell

Posted 漂亮姐姐1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shell学习:理解Shell相关的知识,希望对你有一定的参考价值。

大多数Linux发行版本的默认shell都是GNU bash shell。
除了我们平时登录使用的shell,系统中还有一个默认的shell — sh,它用于那些需要在启动时使用的系统shell脚本

shell的父子关系

用于登录某个虚拟控制器终端或在GUI中终端仿真器中启动默认的交互的shell,是一个父shell。
在CLI提示符(命令行提示符)后输入其他的bash命令,如/bin/bash,sh等,会创建一个新的shell程序,这个shell程序被称为子shell(child shell)。
一个bash shell就是一个进程,可以通过 ps -ef|grep bash 来查看现在的bash shell,并查看shell父子进程

[root@smartgirl~]# ps -ef|grep bash
root       1947   1657  0 Jun18 tty1     00:00:00 -bash
root      42340  42337  0 13:34 pts/0    00:00:00 -bash
[root@smartgirl~]# bash
[root@smartgirl~]# ps -ef|grep bash
root       1947   1657  0 Jun18 tty1     00:00:00 -bash
root      42340  42337  0 13:34 pts/0    00:00:00 -bash
root      52798  42340  0 16:58 pts/0    00:00:00 bash

进程列表

进程列表是一种命令分组(command grouping)。在多个命令外添加括号,就形成了一个进程列表,列表中的命令将由一个子shell来执行。

# 多条命令连续执行
[root@smartgirl~]# pwd ; ls ; cd /etc ; pwd ; cd ; pwd ; ls
# 进程列表
[root@smartgirl~]# (pwd ; ls ; cd /etc ; pwd ; cd ; pwd ; ls)

ps: 另一种命令分组是将命令放入花括号中,并在命令列表的尾部加上分号,使用花括号进行命令分组并不会像进程列表那样创建出子shell

在shell脚本中经常会使用子shell进行多进程处理,但是采用子shell的会明显拖慢处理速度,在交互式的CLI会话中,子shell同样存在问题,它并非真正的多进程处理,,因为终端控制着子shell的I/O。

子shell用法

进程列表,协程和管道都利用了子shell。
在交互式shell中,一个高效的子shell用法就是使用后台模式。

后台模式

后台模式非常方便,它可以让我们在CLI中创造出有实用价值的子shell

[root@smartgirl~]# sleep 3000&    # 使用后台模式执行命令
[root@smartgirl~]# ps --forest    # 使用ps查看进程树情况
[root@smartgirl~]# jobs    		  # 使用jobs命令查看当前有运行在后台的所有用户的程序
[1]+  Running                 sleep 3000 &
作业号 当前状态				  命令
[root@smartgirl~]# jobs -l        # 同时显示PID
[1]+ 48984 Running            sleep 3000 &
作业号 PID  当前状态			  命令

将进程列表置于后台

在CLI中运用shell的创造性方法之一就是将进程列表置为后台模式。这样,既可以在子shell中进行繁重的处理工作,同时不会让子shell的I/O受制于终端。

# 举例:
[root@smartgirl~]# (sleep 10)&
# 实例:在后台执行压缩命令
[root@smartgirl~]# (tar -cf backup01.tar.gz /var/log/backup01;tar -cf backup02 /var/log/backup01)&

协程

协程同样可以实现在子shell中完成命令。
协程可以在后台生成一个子shell,并在这个shell中执行命令
要进行协程处理,得使用coproc命令

# 创建一个后台进程
[root@smartgirl ~]# coproc sleep 1000
[root@smartgirl ~]# ps --forest
   PID TTY          TIME CMD
 42340 pts/0    00:00:00 bash
 53800 pts/0    00:00:00  \\_ sleep
 53806 pts/0    00:00:00  \\_ ps
[root@web01 ~]# jobs -l
[1]+ 53800 Running                 coproc COPROC sleep 1000 &
# 使用扩展语法给协程设置名字
# 注意:最后一个命令必须以分号结尾,花括号和命令之间必须有一个空格,如下面示例
# 创建了一个嵌套的子shell
[root@smartgirl~]# coproc Sleep_Job { sleep 200; }&
[root@smartgirl~]# jobs -l
[1]+ 54057 Running                 coproc Sleep_Job { sleep 200; } &
[root@smartgirl~]# ps --forest
   PID TTY          TIME CMD
 42340 pts/0    00:00:00 bash
 54057 pts/0    00:00:00  \\_ bash
 54058 pts/0    00:00:00  |   \\_ sleep
 54081 pts/0    00:00:00  \\_ ps
# 将协程和进程列表结合 --- 创建一个嵌套的子shell
coproc ( sleep 200 ) # 同coproc Sleep_Job { sleep 200; }& 一样

生成子shell的成本不低,而且速度还慢,创建嵌套的shell更是火上浇油

shell 命令

外部命令

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

内部命令

shell自带的命令

查看命令类型可以查看博文:Linux基础命令

历史命令

历史命令会保存在 .bash_history 中,位于用户家目录下

ps: bash命令的历史记录先保存在内存中,当shell退出时才被写入到历史文件中,要强制写入可使用history -a

# 使用历史记录中的命令
[root@smartgirl~]# history 
   93  tail .bash_history 
   94  history 
[root@smartgirl~]# !93
history 
tail .bash_history 
history -a

以上是关于Shell学习:理解Shell的主要内容,如果未能解决你的问题,请参考以下文章

Shell学习:理解Shell

Shell学习:理解Shell

shell学习四十九天----进程建立

用于确保在任何给定时间仅运行一个 shell 脚本的 shell 片段 [重复]

Shell外壳的简易模拟

shell学习——关于shell函数库的使用