Gibt es eine POSIX-Methode zum Setzen des nullten Arguments einer Zielanwendung?

21

In können bashSie verwenden exec -aund in können zshSie alternativ auch festlegen ARGV0, dass ein Programm mit einem bestimmten nullten Argument ausgeführt wird. Gibt es jedoch auch eine POSIX-Methode, um dies zu tun?

Wie in diesem einen Kommentar vorgeschlagen , könnten Sie eine (temporäre) symbolische Verknüpfung erstellen, um dies zu erreichen, aber auf diese Weise konnte ich den neuen Wert des nullten Arguments nicht auf einen wirklich willkürlichen Wert setzen, z. B. den Befehl mit einem bestimmten absoluten Pfad. Gibt es also eine andere Lösung?

phk
quelle

Antworten:

27

Nein, es gibt keinen POSIX-Weg, außer ein C-Programm zu kompilieren, das dies tut. Als schnelle und schmutzige:

$ 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 -aunterstützt wird ksh93, bash, zsh, busybox ash(ab Version 1.27.0) yash, mksh( seit Version R50e ), die Schily Bourne - Shell ist (seit August 2015) , so dass die am weitesten verbreitete unter den Muscheln.

Am portabelsten perlist es wahrscheinlich, auf einen zuzugreifen, der mit größerer Wahrscheinlichkeit verfügbar ist als ein 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
Stéphane Chazelas
quelle
15

Der Vollständigkeit halber sind hier einige C- und C ++ - Programme aufgeführt, die die Benutzer bereits kompiliert haben.

Nach dem Kommentar, auf den Sie verweisen, ist Ihre offensichtliche Motivation, nach einer "POSIX - Methode" zu fragen, zu wissen, wie man dasselbe Ziel mit Shells wie der Debian Almquist - Shell, der MirBSD Korn - Shell (vor Version R50e) erreichen kann ), die Debian-POSIX-kompatible Ordinary-Shell und andere Shells, die keine Erweiterungen zum Setzen des 0. Arguments wie die Bourne Again- und Z-Shells haben. (Die '93 Korn-Shell und die MirBSD Korn-Shell ab Version R50e unterstützen eine -aOption für ihre integrierten execBefehle.)

execline

Laurent Bercotexecline kommt mit einem execBefehl . Um das Beispiel von M. Chazelas zu kopieren, müsste man ein execlineSkript wie

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

Bercots execist natürlich ein gewöhnlicher Befehl von außen. Man könnte es also in einem Debian Almquist Shell-Skript ausführen. Um das aktuelle Shell-Programm execzu überlagern exec, würde man die Shell verwenden, um mit Bercot zu überlagern , was wiederum das 0. Argument setzen und mit dem Zielprogramm überlagern würde:

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

Nein

Das nosh-Toolset enthält einen execBefehl. Um das Beispiel von M. Chazelas zu kopieren, hätte man ein noshSkript wie

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

Obwohl es ein noshintegrierter Befehl execist , kann auf diesen auch als gewöhnlicher externer Befehl zugegriffen werden. Man könnte es also in einem Debian Almquist Shell-Skript ausführen. Um das aktuelle Shell-Programm execzu überlagern, würde man die Shell zum Überlagern mit dem nosh-Toolset verwenden exec, das wiederum das 0-te Argument setzt und mit dem Zielprogramm überlagert:

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

perp

Wayne Marshalls Täter enthält einen runargv0Befehl . Dies ist ein gewöhnlicher externer Befehl. Man könnte es also in einem Debian Almquist Shell-Skript ausführen. Um das aktuelle Shell-Programm execzu überlagern, würde man die Shell zum Überlagern mit dem perp-Toolset verwenden runargv0, das wiederum das 0-te Argument setzt und mit dem Zielprogramm überlagert:

exec runargv0 printer.sh "$ argv0"

starte es

Gerrit Papes Runit enthält einen chpstBefehl . Dies ist ein gewöhnlicher externer Befehl. Man könnte es also in einem Debian Almquist Shell-Skript ausführen. Um das aktuelle Shell-Programm execzu überlagern, würde man die Shell zum Überlagern mit runits verwenden chpst, was wiederum das 0. Argument setzen und mit dem Zielprogramm überlagern würde:

exec chpst -b "$ argv0" printer.sh

JdeBP
quelle
1
Als Flüchtling , an den ich mich nur runitungern gewandt habe systemd, bin ich sehr froh, vorgestellt zu werden nosh. Danke vielmals!
Charles Duffy