是否有设置目标应用程序的第零个参数的 POSIX 方法?

phk*_*phk 21 shell shell-script posix exec

bash你可以用exec -azsh你也可以替代设置ARGV0具有一定的第0个参数来执行程序,但也有这样做的POSIX方式?

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

Sté*_*las 27

不,除了编译执行它的 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
Run Code Online (Sandbox Code Playgroud)

exec -aksh93, bash, zsh, busybox ash(自 1.27.0 版起), yash, mksh(自 r50e 版起)、Schily Bourne Shell (自 2015 年 8 月起) 支持,因此是 shell 中最普遍的。

最可移植的方法可能是求助于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
Run Code Online (Sandbox Code Playgroud)


Jde*_*eBP 15

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

根据您所指的评论,您要求“一种 POSIX 方式”这样做的明显动机是了解如何使用诸如 Debian Almquist shell、MirBSD Korn shell(R50e 版之前的)、Debian POSIX-Compliant Ordinary shell,以及其他没有像 Bourne Again 和 Z shell 那样具有用于设置第 0 个参数的扩展的 shell。('93 Korn shell 和从 R50e 版本开始的 MirBSD Korn shell,支持-a其内置exec命令的选项。)

执行

Laurent Bercotexecline带有一个exec命令。因此,要复制 M. Chazelas 的示例,将有一个execline脚本,例如

#!/command/execlineb -P
exec -a zzz ps -f

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

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

小吃

nosh 工具集包括一个exec命令。要复制 M. Chazelas 的示例,可以使用一个nosh脚本,例如

#!/bin/nosh
exec -a zzz ps -f

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

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

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

exec runargv0 printer.sh "$argv0"

运行

Gerrit Pape 的 runit包含一个chpst命令. 这是一个普通的外部命令。因此可以从 Debian Almquist Shell 脚本中运行它。要覆盖当前的 shell 程序,可以使用 shellexec与 runit 的覆盖chpst,这反过来将设置第 0 个参数并与目标程序覆盖:

exec chpst -b "$argv0" 打印机.sh

ucspi-tcp

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

exec argv0 打印机.sh "$argv0"