exec命令

Last Updated: 2023-06-18 06:25:00 Sunday

-- TOC --

exec是个bash builtin命令,它有两个作用,通过以替换当前bash进程的方式执行命令,以及设置重定向。

Execute COMMAND, replacing this shell with the specified program. ARGUMENTS become the arguments to COMMAND. If COMMAND is not specified, any redirections take effect in the current shell.

命令行重定向是shell的特色,如果执行exec的时候只有重定向,那么重定向就发生在整个shell内。(bash自己也是一个进程,就是给自己这个进程设置重定向)

执行命令

简单来说,exec会执行一个命令,而且是直接在shell进程中执行,即销毁了当前的shell进程,执行新的命令,执行结束后,无法再返回shell,除非执行的是另一个shell。

在Linux中,创建新的进程使用fork系统调用,创建之后再调用exec执行新进程的代码。bash提供的exec命令,就像直接执行exec系统调用,没有用fork创建新进程,也没有新的PID,当前的shell进程就被替换了。(参考:exec系列接口

$ exec rbash

这条指令,用rbash替换普通当前的bash shell,此时用户无法返回普通bash shell,因为rbash中不能执行exec命令。

注意:exec不是shell,因此shell中定义的function和alias等,exec在执行时都找不到。

设置重定向

exec后面不跟command,而是设定一个整个shell都有效的输入输出重定向,比如:

$ exec > output.txt  # >> means append
$ exec 2>&1  # redirect stderr to stdout

设定后,对后面所有命令的执行都有效。

将所有输出全部重定向到output.txt,>>> 都可以用。这种用法,exec命令就不会销毁当前的shell进程,只是将所有的输出,重定向到文件。在脚本中这个技巧比较有用,可以统一将输出进行重定向,而不用在每一条命令上设置重定向,减少很多键盘工作。

$ cat exec_test.sh
exec > output.txt
echo 'cs.pynote.net'
$ bash exec_test.sh
$ cat output.txt
cs.pynote.net

上例中,exec_test.sh只有两行脚本,执行后生成output.txt,其中的内容就是脚本中echo命令的输出。

下面的代码,用exec命令打开FD5 for reading,FD5(File Descriptor)的内容来自文件:

$ cat output.txt
cs.pynote.net/about
$ exec 5< output.txt
$ read -u 5 aline
$ echo $aline
cs.pynote.net/about
$ exec 5<&-  # close the open read FD5

用exec命令,除了012这3个标准FD(File Descriptor)之外,还可以创建更多FD,通常是10个,0-9!上面代码中的read命令,只是读了一行,可以一行一行的读,参考read命令。

下面的代码,是一个打开FD7用来写的例子,注意 >>> 都可以用:

$ exec 7> shuchu.txt  # >> means append
$ echo 'haha...' 1>&7
$ cat shuchu.txt
haha...
$ exec 7>&-  # close the open write FD7

打开一个FD,同时用于读写:

$ exec 18<> rw.txt  # open rw.txt for reading and writing as FD18
$ exec 18<>&-  # close FD18

关闭exec设置的重定向

$ exec >> a.txt
$ command and output
$ exec 1>/dev/tty  # 恢复monitor输出

关于tty命令

查看进程所有fd(file descriptor)

$ exec 6< pp.py
$ ll /proc/$$/fd
total 0
dr-x------ 2 xinlin xinlin  0 7月   8 18:03 ./
dr-xr-xr-x 9 xinlin xinlin  0 7月   8 18:03 ../
lrwx------ 1 xinlin xinlin 64 7月   8 18:03 0 -> /dev/pts/1
lrwx------ 1 xinlin xinlin 64 7月   8 18:03 1 -> /dev/pts/1
lrwx------ 1 xinlin xinlin 64 7月   8 18:03 2 -> /dev/pts/1
lrwx------ 1 xinlin xinlin 64 7月   8 18:03 255 -> /dev/pts/1
lr-x------ 1 xinlin xinlin 64 7月   8 18:03 6 -> /home/xinlin/test/pp.py

fd6指向了一个文件,读取6就相当于读取这个文件。(这种重定向就像在代码中用fopen打开文件,得到fd)

本文链接:https://cs.pynote.net/sf/linux/shell/202110315/

-- EOF --

-- MORE --