exec命令是一个内置的shell命令, 它用来执行一个可执行文件, 并用该文件替换当前的shell进程。这样, 当执行完该文件后, shell进程就不再存在, 也就不会返回到原来的shell环境中。exec命令可以提高系统的性能, 因为它减少了创建新进程的开销。exec命令还可以用来修改当前shell的环境变量, 文件描述符, 信号处理等设置。

exec命令是一个通用的Linux命令 , 它适用于所有的Linux发行版 , 包括Ubuntu , Debian , Fedora , CentOS , RedHat等。exec命令不需要安装 , 它是shell的一部分 , 常见的shellbash , zsh , ksh , csh等。不同的shell可能有一些细微的差别 , 比如选项 , 语法 , 行为等。你可以通过echo $SHELL命令查看你当前使用的shell , 或者通过man exec命令查看你当前shellexec命令的手册。

  • 语法 : exec [options] [command] [arguments]

如果没有指定command , 根据options的不同, exec命令会修改当前shell的环境变量 , 文件描述符 , 信号处理等设置。如果指定了command , 那么exec命令会执行该command , 并用它替换当前的shell进程。如果command不存在或者不可执行 , 那么exec命令会返回一个非零的退出码 , 并且不会替换当前的shell进程。

常用选项

选项

参数

说明

-a

name

name作为command的名称 , 而不是command本身

-c

在执行command之前 , 清除所有的环境变量 , 只保留SHELL , TERM , USER , HOME , PATH等几个基本的变量

-l

在执行command之前 , 给command的名称加上一个破折号- , 这样可以模拟一个登录shell的行为

-s

如果command是一个shell脚本 , 那么用当前的shell来执行它 , 而不是用脚本中指定的shell

+n

关闭文件描述符n , n是一个整数 , 表示文件描述符的编号

-n

打开文件描述符n , n是一个整数 , 表示文件描述符的编号

n<&word

把文件描述符n重定向到word指定的文件或者文件描述符 , word可以是一个文件名 , 或者一个&后面跟着一个文件描述符的编号

n>&word

把文件描述符n重定向到word指定的文件或者文件描述符 , word可以是一个文件名 , 或者一个&后面跟着一个文件描述符的编号

n<>word

把文件描述符n重定向到word指定的文件 , 以读写的方式打开 , word必须是一个文件名

示例

exec命令

作用

exec ls

shell中执行ls , ls结束后不返回原来的shell中了

exec <file

file中的内容作为标准输入(替代STDIN)

exec >file

将标准输出写入file(替代STDOUT)

exec 3<file

file读入到文件描述符3中(此时 , 创建了文件描述符3 )

sort <&3

将文件描述符3作为临时输入 , 用于sort排序

exec 4>file

将写入文件描述符4中的内容写入file中(此时 , 创建了文件描述符4 )

ls >&4

ls将不会有显示 , 直接写入文件描述符4中了 , 即上面的file

exec 5<&4

创建文件描述符4的拷贝文件描述符5

exec 3<&-

关闭文件描述符3

实例1: 执行一个可执行文件 , 并用它替换当前的shell进程

[linux@bashcommandnotfound.cn ~]$ exec /bin/ls
a.txt b.txt c.txt
[linux@bashcommandnotfound.cn ~]$ # 这里不会返回到原来的shell , 因为已经被ls替换了

实例2: 执行一个shell脚本 , 并用它替换当前的shell进程

[linux@bashcommandnotfound.cn ~]$ cat test.sh
#!/bin/bash
echo "This is a test script"
[linux@bashcommandnotfound.cn ~]$ chmod +x test.sh
[linux@bashcommandnotfound.cn ~]$ exec ./test.sh
This is a test script
[linux@bashcommandnotfound.cn ~]$ # 这里不会返回到原来的shell , 因为已经被test.sh替换了

实例3: 修改当前shell的环境变量

[linux@bashcommandnotfound.cn ~]$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
[linux@bashcommandnotfound.cn ~]$ exec PATH=$PATH:/opt/bin
[linux@bashcommandnotfound.cn ~]$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/bin
[linux@bashcommandnotfound.cn ~]$ # 这里会返回到原来的shell,因为没有执行其他的命令

实例4: 修改当前shell的文件描述符

[linux@bashcommandnotfound.cn ~]$ exec 3>output.txt # 打开文件描述符3,并重定向到output.txt
[linux@bashcommandnotfound.cn ~]$ echo "Hello" >&3 # 把输出写入到文件描述符3
[linux@bashcommandnotfound.cn ~]$ cat output.txt
Hello
[linux@bashcommandnotfound.cn ~]$ exec 3>&- # 关闭文件描述符3
[linux@bashcommandnotfound.cn ~]$ echo "World" >&3 # 这里会报错,因为文件描述符3已经关闭了
bash: 3: Bad file descriptor

实例5: 用指定的名称执行一个命令

[linux@bashcommandnotfound.cn ~]$ exec -a myname /bin/ps
  PID TTY          TIME CMD
  123 pts/0    00:00:00 bash
  456 pts/0    00:00:00 myname
  789 pts/0    00:00:00 ps
[linux@bashcommandnotfound.cn ~]$ # 这里不会返回到原来的shell,因为已经被ps替换了,注意CMD列显示的是myname,而不是ps

实例6: 清除所有的环境变量, 只保留几个基本的变量

[linux@bashcommandnotfound.cn ~]$ env | wc -l
23 # 当前有23个环境变量
[linux@bashcommandnotfound.cn ~]$ exec -c env | wc -l
7 # 清除所有的环境变量后,只剩下7个基本的变量
[linux@bashcommandnotfound.cn ~]$ # 这里不会返回到原来的shell,因为已经被env替换了

实例7: 模拟一个登录shell的行为

[linux@bashcommandnotfound.cn ~]$ exec -l /bin/bash
[linux@bashcommandnotfound.cn ~]$ echo $0
-bash # 注意名称前面有一个破折号-
[linux@bashcommandnotfound.cn ~]$ exit # 退出当前的shell
[linux@bashcommandnotfound.cn ~]$ # 这里不会返回到原来的shell,因为已经被bash替换了

实例8:用当前的shell执行一个shell脚本

[linux@bashcommandnotfound.cn ~]$ cat test.sh
#!/bin/zsh
echo "This is a test script"
[linux@bashcommandnotfound.cn ~]$ chmod +x test.sh
[linux@bashcommandnotfound.cn ~]$ exec -s ./test.sh
This is a test script
[linux@bashcommandnotfound.cn ~]$ # 这里不会返回到原来的shell,因为已经被test.sh替换了,注意这里用的是bash,而不是zsh

实例9: 执行一个不存在或者不可执行的文件

[linux@bashcommandnotfound.cn ~]$ exec /bin/foo
bash: exec: /bin/foo: No such file or directory
[linux@bashcommandnotfound.cn ~]$ # 这里会返回到原来的shell,因为exec命令执行失败了
[linux@bashcommandnotfound.cn ~]$ exec /etc/passwd
bash: exec: /etc/passwd: Permission denied
[linux@bashcommandnotfound.cn ~]$ # 这里会返回到原来的shell,因为exec命令执行失败了

实例10 : 执行一个命令,并传递一些参数

[linux@bashcommandnotfound.cn ~]$ exec /bin/echo "Hello World"
Hello World
[linux@bashcommandnotfound.cn ~]$ # 这里不会返回到原来的shell,因为已经被echo替换了,注意参数要用引号括起来,否则会被shell解释

实例11: 执行一个命令, 并重定向输入和输出

[linux@bashcommandnotfound.cn ~]$ exec /bin/cat < input.txt > output.txt
[linux@bashcommandnotfound.cn ~]$ # 这里不会返回到原来的shell,因为已经被cat替换了,注意重定向符号要放在command后面,否则会被shell解释

实例12: 执行一个命令, 并忽略某些信号

[linux@bashcommandnotfound.cn ~]$ exec - SIGINT /bin/sleep 10
[linux@bashcommandnotfound.cn ~]$ # 这里不会返回到原来的shell,因为已经被sleep替换了,注意-后面要跟一个空格,然后是信号的名称,可以用kill -l命令查看所有的信号,这样可以让command忽略该信号,比如按Ctrl+C不会中断sleep

实例13: 执行一个命令,并设置某些信号的处理方式

[linux@bashcommandnotfound.cn ~]$ exec - SIGINT=ignore /bin/sleep 10
[linux@bashcommandnotfound.cn ~]$ # 这里不会返回到原来的shell,因为已经被sleep替换了,注意-后面要跟一个空格,然后是信号的名称,再跟一个等号,然后是信号的处理方式,可以是ignore,default,或者一个函数名,这样可以让command自定义该信号的处理方式,比如按Ctrl+C不会中断sleep

实例14: 执行一个命令, 并设置某些环境变量

[linux@bashcommandnotfound.cn ~]$ exec - FOO=bar /bin/echo $FOO
bar
[linux@bashcommandnotfound.cn ~]$ # 这里不会返回到原来的shell,因为已经被echo替换了,注意-后面要跟一个空格,然后是环境变量的名称,再跟一个等号,然后是环境变量的值,这样可以让command使用该环境变量,而不影响原来的shell的环境变量

实例15: 执行一个命令, 并设置某些选项

[linux@bashcommandnotfound.cn ~]$ exec - -x /bin/echo "Hello World"
+ /bin/echo 'Hello World'
Hello World
[linux@bashcommandnotfound.cn ~]$ # 这里不会返回到原来的shell,因为已经被echo替换了,注意-后面要跟一个空格,然后是一个破折号-,再跟一个空格,然后是command,这样可以让command使用shell的某些选项,比如-x表示显示执行的命令
​


参考链接

Linux exec命令教程: 如何执行和替换命令(附实例详解和注意事项)-Linux入门自学网

linux--exec命令 - 步留痕 - 博客园


熊熊