Environment-Variables

exec envenv

  • March 8, 2022

兩者execenv不要分叉,請參見以下範例:

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

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 保持不變,這使得父級(腳本和程序)更容易監控其子級。

引用自:https://unix.stackexchange.com/questions/693405