• 深入理解linux shell 中的exec内置命令&ubuntu bash


    在这里插入图片描述

    概览

    每当我们在Bash shell 中运行任何命令时,默认情况下都会创建一个子 shell,并生成(分叉)一个新的子进程来执行该命令。但是,当使用 exec时,exec 后面的命令将替换当前 shell。这意味着不会创建任何子 shell,并且当前进程将替换为此新命令。

    进程替换实验

    1. 先查看当前shell的PID

      jagitch@jagitch-MS-7B93:tmp$ echo $$
      280513
      
    2. 打开第二个shell,查看shell 1的进程信息

      jagitch@jagitch-MS-7B93:tmp$ ps -aef | grep 280513
      jagitch   280513   22748  0 11:37 pts/0    00:00:00 bash
      jagitch   281157  273610  0 11:38 pts/1    00:00:00 grep --color=auto 280513
      
    3. 在shell 1中执行exec命令

      jagitch@jagitch-MS-7B93:tmp$ exec sleep 40
      
    4. 在shell 2中再次查看shell 1的进程信息

      jagitch@jagitch-MS-7B93:tmp$ ps -aef | grep 280513
      jagitch   280513   22748  0 11:37 pts/0    00:00:00 sleep 40
      jagitch   281573  273610  0 11:38 pts/1    00:00:00 grep --color=auto 280513
      

      此时发现280513这个进程由之前的bash替换成了sleep 40,说明exec执行地命令不会创建子进程,而是替换掉当前进程的程序。这样可以达到节约计算机资源的目的。

    5. 等shell 1中地exec命令结束后,发现shell 1退出了,此时在shell 2中查看shell 1的进程ID

      jagitch@jagitch-MS-7B93:tmp$ ps -aef | grep 280513
      jagitch   281749  273610  0 11:39 pts/1    00:00:00 grep --color=auto 280513
      

      此时发现shell 1那个进程已经被销毁了,因为默认的bash进程被exec替换为了sleep命令,这个命令执行完后就会退出,而之前那个shell进程会一直循环解释执行用户输入的命令,它不会退出被销毁。

    exec的常用用法

    1. 脚本中进行命令替换

      jagitch@jagitch-MS-7B93:tmp$ cat ./execdemo.sh 
      #!/bin/bash
      
      echo first
      exec echo second
      echo last
      
      jagitch@jagitch-MS-7B93:tmp$ chmod +x ./execdemo.sh 
      jagitch@jagitch-MS-7B93:tmp$ ./execdemo.sh 
      first
      second
      

      我们可以发现last没有被输出,因为./execdemo.sh在一个子进程中执行,第一个echo正常输出,但是遇到exec echo second后,这个子进程就被替换成echo second了,执行完这条命令该进程就退出销毁了,自然就不会执行后面的echo last了。

    2. 使用exec进行日志记录

      jagitch@jagitch-MS-7B93:tmp$ cat execlog.sh 
      #!/bin/bash
      
      LOG_FILE="output.log"
      
      exec &> "$LOG_FILE"
      
      echo "1. script started at $(date +'%Y-%m-%d')"
      
      echo "2. find all .txt files in current dir"
      find -type f -name "*.txt"
      
      echo "3. make some error"
      cat hello
      
      echo "4. script finished at $(date +'%Y-%m-%d')"
      
      jagitch@jagitch-MS-7B93:tmp$ bash execlog.sh
      jagitch@jagitch-MS-7B93:tmp$ cat output.log
      1. script started at 2024-06-28
      2. find all .txt files in current dir
      ./2.txt
      ./1.txt
      ./favorite colors.txt
      3. make some error
      cat: hello: 没有那个文件或目录
      4. script finished at 2024-06-28
      

      execlog.sh脚本中使用`exec &> "$LOG_FILE"将标准输出和标准错误都重定向到指定地文件中。

    3. 使用exec操作文件描述符

      jagitch@jagitch-MS-7B93:tmp$ cat execfd.sh
      #!/bin/bash
      
      exec 3> fruit.txt
      exec 1>&3
      echo "apple"
      echo "orange"
      exec 3>&-
      jagitch@jagitch-MS-7B93:tmp$ bash execfd.sh
      jagitch@jagitch-MS-7B93:tmp$ cat fruit.txt 
      apple
      orange
      

      exec 3> fruit.txt将文件描述符重定向到fruit.txt文件

      exec 1>&3把标准输出重定向到文件描述符为3的文件中

      exec 3>&-的意思是关闭文件描述符



    每一次点赞,都是你独特的味道。每一次关注,都是我前行的动力。感谢有你,一起成长!

    推荐阅读

    1. 互联网、因特网和万维网傻傻分不清,一文带你彻底理解计算机中的各种网络

    2. 十分钟带你入门Go语言(Golang)开发

    3. 超级详细的Github双重验证开启教程&github Two-factor authentication

  • 相关阅读:
    缓存一致性(cache coherency)解决方案:MESI 协议状态转换详解
    人力资源服务升级正当时,法大大助力佩信集团加速数字化
    基于云计算的检验所云LIS系统源码(两癌筛查)
    Git分布式版本控制工具(一)
    【C++】模板
    51单片机 矩阵键盘
    代理模式之JDK动态代理
    二十三种设计模式全面解析-解密职责链模式:请求处理的设计艺术
    模型部署入门教程(八):如何添加 TensorRT 自定义算子
    华为培训笔记
  • 原文地址:https://blog.csdn.net/fuxily/article/details/140040524