phk*_*phk 21 shell shell-script posix exec
在bash
你可以用exec -a
和zsh
你也可以替代设置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 -a
由ksh93
, 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
Daniel J. Bernstein 的 ucspi-tcp包括一个argv0
命令。(argv0
在djbwares 中也可用。)这是一个普通的外部命令。因此可以从 Debian Almquist Shell 脚本中运行它。要覆盖当前的 shell 程序,可以使用 shellexec
来覆盖 ucspi-tcp's argv0
,这反过来会设置第 0 个参数并覆盖目标程序:
exec argv0 打印机.sh "$argv0"