执行

执行

Inbash你可以使用exec -aand inzsh你也可以选择ARGV0使用某个第零个参数来执行一个程序,但是还有一种 POSIX 方法可以这样做吗?

按照建议在这一评论中您可以创建一个(临时)符号链接来实现此目的,但这样我就无法将新的第零个参数值设置为真正的任意值,例如具有特定绝对路径的命令。那么还有其他解决办法吗?

答案1

不,除了编译 C 程序之外,没有 POSIX 方法可以做到这一点。作为一种快速而肮脏的方法:

$ echo 'int main(int c,char*v[]){
  execvp(v[1],&v[2]);perror(v[1]);return 127;}'>r.c && make r
$ ./r ps zzz -f
UID        PID  PPID  C STIME TTY          TIME CMD
chazelas  7412  7411  0 10:44 pts/4    00:00:00 /bin/zsh
chazelas 21187  7412  0 22:33 pts/4    00:00:00 zzz -f

exec -a支持ksh93, bash, zsh, busybox ash(自版本 1.27.0 起), yash, mksh(从 r50e 版本开始), 这希利·伯恩外壳(自 2015 年 8 月起)因此是贝壳中应用最广泛的。

也许最可移植的是采用perl比 C 编译器更可用的编译器。

$ perl -e 'exec {shift} @ARGV' ps zzz -f
UID        PID  PPID  C STIME TTY          TIME CMD
chazelas  7554  7411  0 10:58 pts/12   00:00:00 /bin/zsh
chazelas  7630  7554  0 11:02 pts/12   00:00:00 zzz -f

答案2

为了完整起见,这里有一些人们拥有的用于执行此操作的 C 和 C++ 程序已经编译。

根据您指出的评论,您要求“一种 POSIX 方式”执行此操作的明显动机是了解如何使用 Debian Almquist shell、MirBSD Korn shell(版本 R50e 之前的版本)等 shell 实现相同的目标)、符合 Debian POSIX 标准的普通 shell,以及其他没有像 Bourne Again 和 Z shell 那样设置第 0 个参数的扩展的 shell。 ('93 Korn shell 和从版本 R50e 开始的 MirBSD Korn shell,支持-a其内置exec命令的选项。)

执行

洛朗·贝尔科特execline附带一个exec命令。因此,要复制 M. Chazelas 的示例,需要一个execline脚本,例如

#!/command/execlineb -P
执行-a zzz ps -f

exec当然,Bercot是一个普通的外部命令。因此,人们可以从 Debian Almquist Shell 脚本中运行它。要覆盖当前的 shell 程序,可以使用 shellexec来覆盖 Bercot exec,这反过来会设置第 0 个参数并覆盖目标程序:

exec /command/exec -a "$argv0" Printer.sh

开胃菜

小吃工具集包括一个exec命令。为了复制 M. Chazelas 的示例,我们需要一个nosh脚本,例如

#!/bin/nosh
执行-a zzz ps -f

虽然是nosh内置的,但是这exec可作为普通外部命令访问。因此,人们可以从 Debian Almquist Shell 脚本中运行它。要覆盖当前的 shell 程序,可以使用 shellexec与 nosh 工具集的覆盖exec,这又会设置第 0 个参数并与目标程序覆盖:

exec /usr/local/bin/exec -a "$argv0" Printer.sh

罪犯

韦恩·马歇尔的罪犯包括一个runargv0命令。这是一个普通的外部命令。因此,人们可以从 Debian Almquist Shell 脚本中运行它。要覆盖当前的 shell 程序,可以使用 shellexec与 perp 工具集进行覆盖runargv0,这又会设置第 0 个参数并与目标程序覆盖:

执行 runargv0 Printer.sh "$argv0"

运行

格里特·佩普的鲁尼特包括一个chpst命令。这是一个普通的外部命令。因此,人们可以从 Debian Almquist Shell 脚本中运行它。要覆盖当前的 shell 程序,可以使用 shellexec与 runit 进行覆盖chpst,这反过来会设置第 0 个参数并与目标程序覆盖:

执行 chpst -b "$argv0" Printer.sh

ucspi TCP协议

Daniel J. Bernstein 的 ucspi-tcp包括一个argv0命令。 (argv0也可用于DJBwares.) 这是一个普通的外部命令。因此,人们可以从 Debian Almquist Shell 脚本中运行它。要覆盖当前的 shell 程序,可以使用 shellexec与 ucspi-tcp 进行覆盖argv0,这又会设置第 0 个参数并与目标程序覆盖:

执行 argv0 打印机.sh "$argv0"

相关内容