我正在學習exec
指揮。我知道該exec
命令替換了啟動它的進程。因此不可能返回到被exec
命令替換的進程。
可以說,它的目的是使其不可能回到啟動它的進程。
exec
但是像命令這樣的東西還有什麼其他用途呢?
答案1
此 exec
命令以指定的命令取代目前的 shell 進程。通常,當您執行命令時,會產生(分叉)一個新進程。該exec
指令不會產生新進程。相反,當前進程會被新指令覆蓋。換句話說,該exec
命令將取代目前 shell 執行,而無需建立新進程。
exec 指令有三種最常見的用法:
1、製程更換
範例1:
如果您打開一個新bash
外殼
$ bash
看起來pstree
像
├─gnome 終端 ├─bash────bash────pstree
以前的bash
外殼仍然存在,你得到了一個新的bash
外殼。而如果你打開一個新的 bash shell,
$ exec bash
pstree
節目
├─gnome 終端 ├─bash───pstree
在這裡,舊的bash
被新的取代了。在一個命令中退出多次登入特別有用。它更加安全,並且消除了錯誤地離開開放終端的可能性。看透過一條命令退出 root 和用戶
範例2:你可以開啟一個文件
$ exec vi filename.txt
當您退出時,vi
無需單獨關閉終端,因為外殼已經被替換。一旦關閉 vi,終端也會關閉。
2. shell腳本內重定向檔案描述符的方法
該exec
命令還可以用在 shell 腳本中動態開啟、關閉和複製檔案描述符。這允許將 STDIN、STDERR、STDOUT 和其他文件描述符重定向到 shell 腳本內的各種文件,而不是命令呼叫字串。如果不指定命令或參數,則可以指定重定向符號和檔案描述符來執行這些功能。
假設你有一個 shell 腳本,script.sh
你想要一個日誌文件script.log
,你可以使用exec
as,
LOG=/path/to/script.log
exec 1>>$LOG
exec 2>&1
這相當於
./script &>> /path/to/script.log
./script >> /path/to/script.log 2>&1
3. 使用 exec 指令建立進程的階段
您也可以使用 exec 命令建立一組 shell 腳本,這些腳本就像進程的各個階段一樣順序執行。每次需要將控制權轉移到下一個腳本時,您不必執行 exec 命令來產生新進程。
在這種情況下,每個階段的最後一個語句應該是exec
呼叫下一個階段的命令。
看exec
shell 腳本中命令的使用了解更多。
筆記:以上部分內容摘自這。
答案2
在包裝腳本中
exec
主要用在包裝腳本。
如果您想在執行主程式之前修改程式的環境,您通常會編寫腳本並在其末尾啟動主程式。但當時腳本沒有必要留在記憶體中。因此,exec
在這些情況下使用,以便主程式可以替換母腳本。
這是一個實際的例子。它的mate-terminal.wrapper
腳本帶有伴侶終端。它mate-terminal
透過檢查使用者環境來啟動一些額外的參數。
#!/usr/bin/perl -w
my $login=0;
while ($opt = shift(@ARGV))
{
if ($opt eq '-display')
{
$ENV{'DISPLAY'} = shift(@ARGV);
}
elsif ($opt eq '-name')
{
$arg = shift(@ARGV);
push(@args, "--window-with-profile=$arg");
}
elsif ($opt eq '-n')
{
# Accept but ignore
print STDERR "$0: to set an icon, please use -name <profile> and set a profile icon\n"
}
elsif ($opt eq '-T' || $opt eq '-title')
{
push(@args, '-t', shift(@ARGV));
}
elsif ($opt eq '-ls')
{
$login = 1;
}
elsif ($opt eq '+ls')
{
$login = 0;
}
elsif ($opt eq '-geometry')
{
$arg = shift(@ARGV);
push(@args, "--geometry=$arg");
}
elsif ($opt eq '-fn')
{
$arg = shift(@ARGV);
push(@args, "--font=$arg");
}
elsif ($opt eq '-fg')
{
$arg = shift(@ARGV);
push(@args, "--foreground=$arg");
}
elsif ($opt eq '-bg')
{
$arg = shift(@ARGV);
push(@args, "--background=$arg");
}
elsif ($opt eq '-tn')
{
$arg = shift(@ARGV);
push(@args, "--termname=$arg");
}
elsif ($opt eq '-e')
{
$arg = shift(@ARGV);
if (@ARGV)
{
push(@args, '-x', $arg, @ARGV);
last;
}
else
{
push(@args, '-e', $arg);
}
last;
}
elsif ($opt eq '-h' || $opt eq '--help')
{
push(@args, '--help');
}
}
if ($login == 1)
{
@args = ('--login', @args);
}
exec('mate-terminal',@args);
這裡要注意的一點是,有一個exec
調用,它替換了記憶體中的這個腳本。
這是 Unix & Linux StackExchange Site 中回答的類似問題 -https://unix.stackexchange.com/q/270929/19288
重定向檔案描述符
另一個常見用途exec
是重定向檔案描述符。stdin
, stdout
,stderr
可以使用 exec 重定向到檔案。
重定向
stdout
-exec 1>file
將導致標準輸出成為file
以目前 shell 會話結束命名的檔案。任何要輸出到顯示器的內容都會在文件中。重定向
stdin
- 它也可用於重定向stdin
到檔案。例如,如果你想執行一個腳本文件script.sh
,你可以stdin
使用 重定向到該文件exec 0<script.sh
。
答案3
據我所知,它也用於重定向 bash 腳本的檔案描述符(例如,STDOUT、STDERR、STDIN)。
例如,您可以使用 STDIN 重定向從檔案而不是鍵盤讀取數據,並透過 STDOUT(或可能是 STDERR,這取決於程式)重定向寫入檔案而不是終端。