Existe-t-il un moyen POSIX de définir l'argument zéro d'une application cible?

21

En bashvous pouvez utiliser exec -aet en zshalternativement vous pouvez également définir ARGV0pour exécuter un programme avec un certain argument zéro, mais existe-t-il également une manière POSIX de le faire?

Comme suggéré dans ce commentaire, vous pouvez créer un lien symbolique (temporaire) pour y parvenir, mais de cette façon, je ne pouvais pas définir la nouvelle valeur de l'argument zéro sur une valeur vraiment arbitraire, par exemple la commande avec un certain chemin absolu. Y a-t-il donc une autre solution?

phk
la source

Réponses:

27

Non, il n'y a pas de méthode POSIX, autre que la compilation d'un programme C qui le fait. Comme rapide et sale:

$ 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 -aest pris en charge par ksh93, bash, zsh, busybox ash(depuis la version 1.27.0), yash, mksh( depuis la version R50e ), le Schily Bourne Shell (depuis Août 2015) est donc la plus répandue parmi les coquilles.

Le plus portable serait probablement de recourir à perlce qui est plus susceptible d'être disponible qu'un compilateur 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
Stéphane Chazelas
la source
15

Pour être complet, voici quelques programmes C et C ++ pour ce faire que les gens ont déjà compilés.

En vous basant sur le commentaire que vous signalez, votre motivation apparente à demander "une manière POSIX" de faire cela est de savoir comment on peut atteindre ce même but avec des shells tels que le shell Debian Almquist, le shell MirBSD Korn (avant la version R50e ), le shell ordinaire Debian conforme à POSIX et d'autres shells qui n'ont pas d'extensions pour définir le 0ème argument comme les shells Bourne Again et Z. (Le shell Korn de 1993 et ​​le shell Korn MirBSD à partir de la version R50e prennent en charge une -aoption pour leurs execcommandes intégrées .)

execline

Laurent Bercot estexecline livré avec une execcommande . Donc, pour reproduire l'exemple de M. Chazelas, on aurait un execlinescript tel que

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

Bercot execest une commande externe ordinaire, bien sûr. On pourrait donc l'exécuter à partir d'un script Debian Almquist Shell. Pour superposer le programme shell actuel, on utiliserait le shell execpour superposer avec Bercot exec, qui à son tour définirait le 0ème argument et superposerait avec le programme cible:

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

bouffe

Le jeu d'outils nosh comprend une execcommande. Pour reproduire l'exemple de M. Chazelas, on aurait un noshscript tel que

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

Bien qu'il s'agisse d'une fonction noshintégrée, elle execest également accessible en tant que commande externe ordinaire. On pourrait donc l'exécuter à partir d'un script Debian Almquist Shell. Pour superposer le programme shell actuel, on utiliserait le shell execpour superposer avec le jeu d'outils nosh exec, qui à son tour définirait le 0ème argument et superposerait avec le programme cible:

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

perp

Le perp de Wayne Marshall comprend une runargv0commande . Il s'agit d'une commande externe ordinaire. On pourrait donc l'exécuter à partir d'un script Debian Almquist Shell. Pour superposer le programme shell actuel, on utiliserait le shell execpour superposer avec le jeu d'outils perp runargv0, qui à son tour définirait le 0ème argument et superposerait avec le programme cible:

exec runargv0 printer.sh "$ argv0"

exécuter

Le runit de Gerrit Pape comprend une chpstcommande . Il s'agit d'une commande externe ordinaire. On pourrait donc l'exécuter à partir d'un script Debian Almquist Shell. Pour superposer le programme shell actuel, on utiliserait le shell execpour superposer avec runit chpst, qui à son tour définirait le 0ème argument et superposerait avec le programme cible:

exec chpst -b "$ argv0" printer.sh

JdeBP
la source
1
En tant que réfugié de qui runits'est tourné à contrecœur systemd, je suis très heureux d'être présenté à nosh. Merci beaucoup!
Charles Duffy