Is there a POSIX way of setting zeroth argument of a target application?
No, there's no POSIX way, other than compiling a C program that does it. As a quick and dirty one:
$ 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
is supported by ksh93
, bash
, zsh
, busybox ash
(since version 1.27.0), yash
, mksh
(since version r50e), the Schily Bourne Shell (since August 2015) so is the most widespread among shells.
Probably the most portable would be to resort to perl
which is more likely to be available than a C compiler.
$ 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
For completeness, here are some C and C++ programs for doing this that people have already compiled.
Going by the commentary that you point to, your apparent motivation for asking for "a POSIX way" of doing this is to know how one can achieve this same end with shells such as the Debian Almquist shell, the MirBSD Korn shell (before version R50e), the Debian POSIX-Compliant Ordinary shell, and other shells that do not have extensions for setting the 0th argument as the Bourne Again and Z shells have. (The '93 Korn shell, and the MirBSD Korn shell from version R50e onwards, support an -a
option to their built-in exec
commands.)
execline
Laurent Bercot's execline
comes with an exec
command. So to duplicate M. Chazelas' example one would have an execline
script such as
#!/command/execlineb -P exec -a zzz ps -f
Bercot's exec
is an ordinary external command, of course. So one could run it from within a Debian Almquist Shell script. To overlay the current shell program one would use the shell's exec
to overlay with Bercot exec
, which in turn would set the 0th argument and overlay with the target program:
exec /command/exec -a "$argv0" printer.sh
nosh
The nosh toolset includes an exec
command. To duplicate M. Chazelas' example one would have a nosh
script such as
#!/bin/nosh exec -a zzz ps -f
Although it is a nosh
built-in, this exec
is also accessible as an ordinary external command. So one could run it from within a Debian Almquist Shell script. To overlay the current shell program one would use the shell's exec
to overlay with the nosh toolset's exec
, which in turn would set the 0th argument and overlay with the target program:
exec /usr/local/bin/exec -a "$argv0" printer.sh
perp
Wayne Marshall's perp includes a runargv0
command. This is an ordinary external command. So one could run it from within a Debian Almquist Shell script. To overlay the current shell program one would use the shell's exec
to overlay with the perp toolset's runargv0
, which in turn would set the 0th argument and overlay with the target program:
exec runargv0 printer.sh "$argv0"
runit
Gerrit Pape's runit includes a chpst
command. This is an ordinary external command. So one could run it from within a Debian Almquist Shell script. To overlay the current shell program one would use the shell's exec
to overlay with runit's chpst
, which in turn would set the 0th argument and overlay with the target program:
exec chpst -b "$argv0" printer.sh
ucspi-tcp
Daniel J. Bernstein's ucspi-tcp includes an argv0
command. (argv0
is also available in djbwares.) This is an ordinary external command. So one could run it from within a Debian Almquist Shell script. To overlay the current shell program one would use the shell's exec
to overlay with ucspi-tcp's argv0
, which in turn would set the 0th argument and overlay with the target program:
exec argv0 printer.sh "$argv0"