Czy istnieje sposób POSIX na ustawienie zerowego argumentu aplikacji docelowej?

21

W bashyou can exec -ai in zshmożesz alternatywnie ustawić również ARGV0wykonanie programu z pewnym zerowym argumentem, ale czy istnieje również sposób POSIX?

Jak zasugerowano w tym jednym komentarzu, możesz stworzyć (tymczasowy) symboliczny link, aby to osiągnąć, ale w ten sposób nie mogłem ustawić nowej wartości zerowego argumentu na naprawdę dowolną dowolną wartość, np. Polecenie z określoną ścieżką bezwzględną. Czy jest jakieś inne rozwiązanie?

phk
źródło

Odpowiedzi:

27

Nie, nie ma innego sposobu POSIX, niż kompilacja programu w C, który to robi. Jako szybki i brudny:

$ 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 -ajest obsługiwany przez ksh93, bash, zsh, busybox ash(od wersji 1.27.0) yash, mksh( od wersji r50e ), przy czym Schily Bourne Shell (od sierpnia 2015), więc jest to najbardziej rozpowszechniona wśród muszli.

Prawdopodobnie najbardziej przenośne byłoby uciekanie się do tego, perlco jest bardziej prawdopodobne niż kompilator 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
źródło
15

Dla kompletności, oto niektóre programy C i C ++ do robienia tego, które ludzie już skompilowali.

Idąc za komentarzem, na który wskazujesz, twoją widoczną motywacją do poproszenia o „sposób POSIX” jest zrozumienie, w jaki sposób można osiągnąć ten sam cel za pomocą powłok takich jak powłoka Debian Almquist, powłoka MirBSD Korn (przed wersją R50e ), zwykła powłoka zgodna z Debian POSIX i inne powłoki, które nie mają rozszerzeń do ustawiania zerowego argumentu tak jak powłoki Bourne Again i Z. (Powłoka Korn '93 i powłoka Korn MirBSD od wersji R50e i późniejszej obsługują -aopcję wbudowanych execpoleceń.)

wykonać

Laurent Bercot użytkownikaexecline wyposażony w execkomendzie . Aby powielić przykład M. Chazelasa, należy mieć execlineskrypt taki jak

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

execOczywiście Bercot to zwykłe zewnętrzne polecenie. Można więc uruchomić go ze skryptu powłoki Debian Almquist Shell. Aby nałożyć bieżący program powłoki, należy użyć powłoki execdo nałożenia się na Bercot exec, który z kolei ustawi zerowy argument i nakłada się na program docelowy:

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

nosh

Zestaw narzędzi nosh zawiera execpolecenie. Aby zduplikować przykład M. Chazelasa, należy mieć noshskrypt taki jak

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

Chociaż jest to noshwbudowane, execjest to również dostępne jako zwykłe zewnętrzne polecenie. Można więc uruchomić go ze skryptu powłoki Debian Almquist Shell. Aby nałożyć bieżący program powłoki, należy użyć powłoki execdo nałożenia zestawu narzędzi nosh exec, co z kolei ustawi zerowy argument i nakłada się na program docelowy:

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

sprawca

Sprawca Wayne Marshall zawiera się runargv0polecenie . To jest zwykłe polecenie zewnętrzne. Można więc uruchomić go ze skryptu powłoki Debian Almquist Shell. Aby nałożyć bieżący program powłoki, należy użyć powłoki execdo nałożenia na zestaw narzędzi perp runargv0, który z kolei ustawi zerowy argument i nakłada się na program docelowy:

exec runargv0 printer.sh "$ argv0"

Uruchom

Runit Gerrit Pape zawiera się chpstpolecenie . To jest zwykłe polecenie zewnętrzne. Można więc uruchomić go ze skryptu powłoki Debian Almquist Shell. Aby nałożyć bieżący program powłoki, należy użyć powłoki execdo nałożenia na runit chpst, co z kolei ustawi 0-ty argument i nakłada się na program docelowy:

exec chpst -b "$ argv0" printer.sh

JdeBP
źródło
1
Jako uchodźca, do którego runitniechętnie się zwróciłem systemd, bardzo się cieszę, że się zapoznałem nosh. Wielkie dzięki!
Charles Duffy,