exec命令有什么可能的用途?


10

我正在学习exec命令。我知道该exec命令将替换启动它的进程。因此,不可能返回到被exec命令替换的过程。

可以说,这样做的目的是使不可能返回到启动它的过程。

但是,像exec命令这样可用的东西还有什么其他用途呢?



1
维基百科文章中的内容:“包装程序脚本在设置环境变量或其他配置后,经常使用此命令来运行程序(直接或通过解释器或虚拟机)。”
knb

1

2
我个人觉得exec ssh server-that-does-byobu-on-login.example.com很高兴,因为^ A ^ D完全关闭了终端。(更一般地,exec byobu(或exec screenexec tmux)。
Williham托特兰

Answers:


9

在包装脚本中

exec 主要用于包装脚本中。

如果要在执行主程序之前修改程序的环境,通常会编写一个脚本,并在脚本结束时启动主程序。但是,此时无需将该脚本保留在内存中。因此,exec在这些情况下使用以便主程序可以替换母脚本。

这是一个实际的例子。它的mate-terminal.wrapper脚本带有mate-terminal。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网站回答了类似的问题- https://unix.stackexchange.com/q/270929/19288

重定向文件描述符

的另一个常见用法exec是重定向文件描述符。stdinstdoutstderr可以被重定向到执行exec文件。

  1. 重定向stdout- exec 1>file将导致标准输出是一个以file当前Shell会话的结尾命名的文件。输出到显示器的所有内容都将在文件中。

  2. 重定向stdin-也可以用于将重定向stdin到文件。例如,如果要执行脚本文件script.sh,则可以stdin使用重定向到该文件exec 0<script.sh


好的。之后,“ mate-terminal”将具有包装脚本具有的PID吗?并会使用包装脚本使用的内存吗?因此包装脚本消失了。否则,这两个脚本将作为系统上的单独进程(具有两个不同的PID)存在吗?
mizech '16

@mizech是的。他们使用相同的PID
Anwar

@mizech很高兴知道它有所帮助:)
Anwar

1
一个很好的例子,这很清楚
Zanna

这个答案是不完整的,错过了一个重要的(典型的)用法,exec它是在文件描述符的重定向中使用的。
heemayl

9

exec 命令用指定的 命令替换当前的shell进程。通常,当您运行命令时,会生成(分叉)新进程。该exec 命令不会产生新进程。而是,当前过程被新命令覆盖。换句话说,exec在不创建新进程的情况下,该命令将代替当前外壳程序执行。

exec命令有三种最常见的用法:

1.更换工序

示例1: 如果您bash

$ bash 

pstree它看起来像

├─gnome终端
        ├─bash───bash───pstree

以前的bash外壳仍然在那里,您得到了一个新的bash外壳。而如果您打开一个新的bash shell,

$ exec bash

pstree节目

├─gnome终端
        ├─bash───pstree

在这里旧bash的被新的代替。在一个命令中退出多次登录特别有用。它更安全,并且消除了错误地离开开放终端的机会。请参阅使用一个命令从root和user退出

示例2:您可以将文件打开为

$ exec vi filename.txt

退出时vi,由于外壳已被更换,因此无需单独关闭终端。一旦关闭vi,终端也将关闭。

2.一种在shell脚本中重定向文件描述符的方法

exec 命令还可用于动态打开,关闭和复制文件描述符的shell脚本中。这样就可以将STDIN,STDERR,STDOUT和其他文件描述符重定向到Shell脚本中的各种文件,而不是命令调用字符串。如果未指定命令或参数,则可以指定重定向符号和文件描述符以执行这些功能。

假设您有一个Shell脚本script.sh想要一个日志文件script.log,您可以将其exec用作,

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调用下一阶段的命令。

有关更多信息,请参见Shell脚本中命令的用法exec

注意:以上部分摘自此。


1
完整答案(到目前为止)。
heemayl

我使用exec的所有时间都是为了提高效率。如果使用exec运行守护程序,则只需要一个活动进程,而不是两个。离开bash进程浪费了数MB的ram,等等。
gmatht

2

据我所知,它还用于重定向bas​​h脚本的文件描述符(例如STDOUT,STDERR,STDIN)。

因此,例如,您可以使用STDIN重定向从文件读取而不是从键盘读取,并通过STDOUT(或者根据程序而定为STDERR)重定向来写入文件,而不是从终端写入文件。


1
这个答案部分,只补充了这个答案
heemayl
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.