• Shell系统学习之子Shell与进程处理


    系列文章目录

    Shell系统学习之什么是Shell

    Shell系统学习之创建一个Shell程序

    Shell系统学习之向Shell脚本传递参数

    Shell系统学习之如何执行Shell程序

    Shell系统学习之Shell变量和引用

     Shell系统学习之Shell条件测试,判断语句和运算符

     Shell系统学习之循环结构

     Shell系统学习之函数

    Shell系统学习之数组

    系统学习Shell之正则表达式

    Shell系统学习之文件操作

    Shell系统学习之子Shell与进程处理


    文章目录

    目录

    系列文章目录

    文章目录

    前言

    子Shell

    什么是子Shell

    Shell内部命令、外部命令和保留字

    在子Shell中执行命令 

    进程处理

    什么是进程和作业

    相关命令fd,jobs,disown

    通过信号和trap命令控制进程 

    小结 


    前言

    当我们在执行Shell脚本时,会感觉到Shell脚本就是在当前的Shell命令行提示符下被解释执行的,其实不是的,,当脚本被执行的时候,当前的Shell会启动一个子进程执行当前的Shell脚本。本篇文章就讲解下子Shell和进程处理


    子Shell

    什么是子Shell

    我们首先来了解第一个Shell是如何启动的?

    当用户登录Linux后,操作系统会根据用户/etc/passwd文件中的配置启动一个Shell进程,该Shell进程是当前用户所执行的Shell命令的父进程。每个用户都可以指定自动的默认Shell程序,下面显示部分/etc/passwd的内容:

    eden_ubuntu@edenubuntu:~/Documents/Shell/12$ cat /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    sys:x:3:3:sys:/dev:/usr/sbin/nologin
    sync:x:4:65534:sync:/bin:/bin/sync
    games:x:5:60:games:/usr/games:/usr/sbin/nologin
    man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
    lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
    mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
    news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
    uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
    proxy:x:13:13:proxy:/bin:/usr/sbin/nologin

    其中/etc/passwd每一行描述了一个用户信息,一共有7个字段,每个字段的含义如下:

    用户名:x:用户ID:用户组ID:备注信息:用户主目录:默认Shell程序 

    默认Shell程序使用绝对路径。如果这个字段的Shell程序不存在,不合法,则无法登录主机。如果用户不需要登录,则可以将路径设置为 /usr/sbin/nologin。

    下图描述了父子Shell的工作过程:

    Shell内部命令、外部命令和保留字

    在一些其他书籍中,我们经常看到所谓内部命令和外部命令这个说法,这里来解释下它们的区别。

    内部命令是指包含在Shell工具包中的命令,内部命令嵌入在Shell程序中,并不以单独的磁盘文件的形式(可执行文件)存在。比如cd, bg, exit,exec, eval,pwd等.

    外部命令是Linux系统中的实用程序部分,这些程序以磁盘文件的方式存在于磁盘中。在用户登录时,外部命令并不像内部命令一样随着默认Shell加载到内存中,而是在需要的时候才被调用进内存。Shell程序管理外部命令执行时的路径查找和代码加载,并控制命令的执行。比如ls,at,du,host等都是外部命令。外部命令通常都位于/usr/bin以及/usr/sbin等目录中,其中/usr/sbin中的命令通常与系统管理有关。

    Shell的保留字一般就是Shell语法中的关键字,这里不一一列出了。

    在子Shell中执行命令 

     (command1;command2;...)

     (command1;command2;...)&

    当把命令放到一个圆括号中执行时,该组命令会在子Shell中执行 ,如果在括号后面加上&,表示该子Shell后台执行,不会阻塞当前父进程。

    这种方法先了解,以后有地方需要再看看,目前我感觉还用不到,但是要了解,当看到这种代码时要懂。

    进程处理

    什么是进程和作业

    什么是进程,这里就不多做介绍了,我们首先理解下作业这个概念:一个作业可以包含多个进程,作业是针对用户而言的,是用户为了完成某项任务而启动的进程,1个作业可以包含1个,也可以包含多个进程,这些进程之间协同工作,共同完成任务。而进程是针对操作系统而言的,是操作系统程序执行的基本单位。

    比如:

    ls -l | grep 13 | more 

    上面一组命令可以称为一个作业,但是还会启动3个进程。

    当我们后台执行Shell脚本时,比如:

    eden_ubuntu@edenubuntu:~/Documents/Shell/13$ ./13-10.sh &
    [1] 16386

    会显示一个[1] 和 16386

    其中[1]中的1表示作业号,16386表示执行脚本的进程号。

    当该作业完成会有提示:

    [1]+  Done                    ./13-10.sh 

    以上提示包括作业号 状态 所执行的脚本命令

    再执行前台作业时,可以执行Ctrl+Z将当前任务挂起,比如我执行vi 命令编辑一个文件,然后按Ctrl+Z的效果:

    eden_ubuntu@edenubuntu:~/Documents/Shell/13$ vi 13-2.sh

    [2]+  Stopped                 vi 13-2.sh

     以上提示作业号为2的作业已经被挂起。

    相关命令fd,jobs,disown

    使用fd命令,是一个内部命令,将作业从后台移至前台运行

    fd [jobspec]

    jobsepc用来指定要切换的作业,fd指定切换作业的方法:

    fd指定切换作业的方法
    方法说明
    %nn为整数,表示作业号
    %string以string字符串开头的命令所对应的作业
    %?string包含string字符串的命令所对应的作业
    %+或者%%最近提交的作业
    %-倒数第二提交的作业

    jobs命令查看正在后台执行的作业的列表,基本语法如下:

    jobs [options]

    eden_ubuntu@edenubuntu:~/Documents/Shell/13$ jobs
    [2]-  Stopped                 vi 13-2.sh
    [3]+  Stopped                 vi 13-2.sh 

    其中[3]旁边的+表示最近的一个作业,[2]旁边的-号表示倒数第二的作业。

    作业的状态:

    作业的状态
    状态说明
    Running正在运行
    Stopped被挂起
    Done该作业已完成退出码为0
    Done(code)该作业已正常完成并退出,退出状态码非0,状态码使用10进制表示

    disown命令用来删除作业列表中的作业

    disown [jobsepc]

    用法与fd命令一样。

    通过信号和trap命令控制进程 

    kill 命令可以给进程传递信号。

    kill -l命令显示当前系统支持的信号:

    eden_ubuntu@edenubuntu:~/Documents/Shell/13$ kill -l
     1) SIGHUP     2) SIGINT     3) SIGQUIT     4) SIGILL     5) SIGTRAP
     6) SIGABRT     7) SIGBUS     8) SIGFPE     9) SIGKILL    10) SIGUSR1
    11) SIGSEGV    12) SIGUSR2    13) SIGPIPE    14) SIGALRM    15) SIGTERM
    16) SIGSTKFLT    17) SIGCHLD    18) SIGCONT    19) SIGSTOP    20) SIGTSTP
    21) SIGTTIN    22) SIGTTOU    23) SIGURG    24) SIGXCPU    25) SIGXFSZ
    26) SIGVTALRM    27) SIGPROF    28) SIGWINCH    29) SIGIO    30) SIGPWR
    31) SIGSYS    34) SIGRTMIN    35) SIGRTMIN+1    36) SIGRTMIN+2    37) SIGRTMIN+3
    38) SIGRTMIN+4    39) SIGRTMIN+5    40) SIGRTMIN+6    41) SIGRTMIN+7    42) SIGRTMIN+8
    43) SIGRTMIN+9    44) SIGRTMIN+10    45) SIGRTMIN+11    46) SIGRTMIN+12    47) SIGRTMIN+13
    48) SIGRTMIN+14    49) SIGRTMIN+15    50) SIGRTMAX-14    51) SIGRTMAX-13    52) SIGRTMAX-12
    53) SIGRTMAX-11    54) SIGRTMAX-10    55) SIGRTMAX-9    56) SIGRTMAX-8    57) SIGRTMAX-7
    58) SIGRTMAX-6    59) SIGRTMAX-5    60) SIGRTMAX-4    61) SIGRTMAX-3    62) SIGRTMAX-2
    63) SIGRTMAX-1    64) SIGRTMAX 

     也可以通过man 7 signal查看信号的帮助手册。

    常用信号及其含义
    信号含义
    SIGHUP1终端挂起或者控制进程终止
    SIGINT2键盘中断
    SIGQUIT3键盘退出键被按下
    SIGABRT6由about(3)发出的退出指令
    SIGKILL9立即结束进程

    下面表示使用kill命令给进程发信号的命令语法:

    kill [-s signal] pid

    对于有些信号,进程会由默认的响应动作,而有些信号进程可能会直接忽略。在Shell中用户可以通过trap命令来设定响应某个信号的动作。trap是一个内部命令,语法如下:

    trap [[arg] signspec ...]

    举例:

    1. #!/bin/bash
    2. function signal_handler()
    3. {
    4. echo "Good bye"
    5. }
    6. trap signal_handler 0

     在POSIX标准中把0定义为空信号,在程序退出时会触发,该程序的执行结果:

    eden_ubuntu@edenubuntu:~/Documents/Shell/13$ ./13-11.sh 
    Good bye

    小结 

    本篇文章主要说明了父子Shell,内部命令和外部命令,前后台运行,进程与作业以及对它们的控制。 

  • 相关阅读:
    计算机毕业设计Java游泳馆管理平台(系统+程序+mysql数据库+Lw文档)
    MySQL--视图&导入导出&索引&执行计划
    【VMware16 安装 Centos7 并配置固定IP】
    如何走出自动化测试第一步?
    SpringMVC实现增删改查(CRUD)--从头到尾全面详细讲解
    数据分析中的pandas文章目录汇总
    FlinkSQL自定义UDATF实现TopN
    Jackson,Fastjson详细教程
    2022 弱口令安全实验室招新赛-靶机挑战记录
    35的程序员被辞了可以自己接外包啊?为什么都那么悲观呢?
  • 原文地址:https://blog.csdn.net/MashiMaroJ/article/details/126198253