AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 693405
Accepted
Weihang Jian
Weihang Jian
Asked: 2022-03-09 01:24:21 +0800 CST2022-03-09 01:24:21 +0800 CST 2022-03-09 01:24:21 +0800 CST

`exec env` 与 `env`

  • 772

两者exec都env不要分叉,请参见以下示例:

docker run --rm -it ubuntu:18.04 sh -c 'exec sleep 1 & ps -Ho pid,ppid,cmd'
  PID  PPID CMD
    1     0 sh -c exec sleep 1 & ps -Ho pid,ppid,cmd
    7     1   sleep 1
    8     1   ps -Ho pid,ppid,cmd
docker run --rm -it ubuntu:18.04 sh -c 'env sleep 1 & ps -Ho pid,ppid,cmd'
  PID  PPID CMD
    1     0 sh -c env sleep 1 & ps -Ho pid,ppid,cmd
    7     1   sleep 1
    8     1   ps -Ho pid,ppid,cmd

问题

我看到很多人在使用exec env ...,但我认为没有exec必要,因为env不会像exec.

有没有我们需要使用的用例来exec env代替env?

environment-variables ps
  • 1 1 个回答
  • 218 Views

1 个回答

  • Voted
  1. Best Answer
    ilkkachu
    2022-03-09T03:04:53+08:002022-03-09T03:04:53+08:00

    env(可能)本身不会分叉,只是用它所做的程序替换自己。但这与父 shell 分叉不同env,或者只是用env.

    例如比较这两个:

    $ bash -c 'env ls > /dev/null; echo hi'
    hi
    $ bash -c 'exec env ls > /dev/null; echo hi'
    [no output]
    

    使用exec,外壳本身被替换,并且以下内容echo不运行。

    当然,你有exec env ... &。使用&,shell 无论如何都会分叉以启动后台进程,并且它可能不会再次分叉以在后台任务中运行单个命令。至少 Bash 优化了这样的情况,例如:

    $ bash -c 'ps -Ho pid,ppid,cmd; echo x'
      PID  PPID CMD
    11967  1545 -/bin/bash
    14851 11967   bash -c ps -Ho pid,ppid,cmd; echo x
    14852 14851     ps -Ho pid,ppid,cmd
    x
    $ bash -c 'ps -Ho pid,ppid,cmd'
      PID  PPID CMD
    11967  1545 -/bin/bash
    14853 11967   ps -Ho pid,ppid,cmd
    

    如果后者不显示中间bash过程,则行为与存在中间过程相同exec。(-/bin/bash是我的交互式外壳。)

    Bash 只对一个单独的命令执行此操作,如果有多个命令,shell 将等待最后一个退出。使用exec那里会有所作为:

    $ bash -c 'echo x; ps -Ho pid,ppid,cmd'
    x
      PID  PPID CMD
    11967  1545 -/bin/bash
    14929 11967   bash -c echo x; ps -Ho pid,ppid,cmd
    14930 14929     ps -Ho pid,ppid,cmd
    $ bash -c 'echo x; exec ps -Ho pid,ppid,cmd'
    x
      PID  PPID CMD
    11967  1545 -/bin/bash
    14933 11967   ps -Ho pid,ppid,cmd
    

    &,这与相同exec ps:

    $ bash -c 'ps -Ho pid,ppid,cmd & sleep 1'
      PID  PPID CMD
    11967  1545 -/bin/bash
    14867 11967   bash -c ps -Ho pid,ppid,cmd & sleep 1
    14868 14867     ps -Ho pid,ppid,cmd
    14869 14867     sleep 1
    

    但是使用复合块,我们也可以看到后台 shell 进程:

    $ bash -c '{ ps -Ho pid,ppid,cmd; } & sleep 1'
      PID  PPID CMD
    11967  1545 -/bin/bash
    14877 11967   bash -c { ps -Ho pid,ppid,cmd; } & sleep 1
    14878 14877     bash -c { ps -Ho pid,ppid,cmd; } & sleep 1
    14880 14878       ps -Ho pid,ppid,cmd
    14879 14877     sleep 1
    

    你没有提供这些人的任何具体来源exec env,所以我们不知道他们的确切情况。但是你会使用exec env相同的方式exec anyprogram:如果你想用其他进程替换 shell。例如这个模拟示例:

    #!/bin/bash
    . someconfigfile
    if [ "$someconfig" = blah ]; then
        exec env myprogram some args...
        echo "failed to start" >&2
        exit 1
    elif
        ... whatever
    fi
    

    那里用启动的exec程序替换脚本,这样shell就不会无用地留在内存中。此外,如果脚本只有一个中介来启动程序,那么执行 anexec将使 PID 保持不变,这使得父级(脚本和程序的)更容易监控其子级。

    • 5

相关问题

  • 查找变量 $CDPATH 所在的路径?

  • 定义包含目录路径(对于 *.h) CentOS

  • $PAGER 可以包含空格吗?

  • 我可以在环境中手动设置多个代理吗?

  • ps -vxa 不对内存进行排序

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve