Czy istnieje standardowe polecenie Unix, które robi coś podobnego do mojego przykładu poniżej?
$ <cmd here> 56
$ echo Return code was $?
Return code was 56
$
<cmd here>
powinno być czymś, co można wykonać za pomocą wideł, i pozostawia 56 jako kod wyjścia, gdy proces się kończy. Te exit
i return
powłoki builtins nie nadają się do tego, co szukam, ponieważ wpływają one na skorupę powołując się poprzez wychodzenia z niego. <some cmd>
powinno być czymś, co mogę wykonać w kontekście innym niż shell - np. wywołując ze skryptu Python za pomocą subprocess
.
Np. /usr/bin/false
Zawsze wychodzi natychmiast z kodem powrotu 1, ale chciałbym dokładnie kontrolować, co to jest kod powrotu. Mogę osiągnąć te same wyniki, pisząc własny skrypt opakowania
$ cat my-wrapper-script.sh # i.e., <some cmd> = ./my-wrapper-script.sh
#!/usr/bin/bash
exit $1
$ ./my-wrapper-script.sh 56
$ echo $?
56
ale mam nadzieję, że istnieje standardowa komenda Uniksa, która może to dla mnie zrobić.
źródło
exit
jest jedynym, o którym mogę myśleć, ale ma tendencję do kończenia twojej powłoki.bash -c 'exit 56'
lubbash -c "exit $1"
może pracować dla ciebie.(exit 56)
?true
ifalse
wbudowane, jeśli chcesz zwrócić 0 lub 1.Odpowiedzi:
return
Funkcja oparta będzie działać, i unika konieczności otwierać i zamykać kolejną powłokę, (zgodnie Tim Kennedy komentarzu „s ):Wydajność:
za
exit
pomocą podpowłoki:W przypadku powłok innych niż
ksh93
oznacza to rozwidlenie dodatkowego procesu, więc jest mniej wydajny niż powyższe.bash
/zsh
/ksh93
tylko trik:(co oznacza również dodatkowy proces (i IPC z rurą)).
zsh
funkcje lambda:źródło
<some cmd>
to możliwe w execve ()./bin/sh -c ...originalcommand...
Nie ma standardowej komendy UNIX służącej do zwrócenia określonej wartości. GNU Core Utilies zapewnia
true
ifalse
tylko.Możesz to jednak łatwo zaimplementować samodzielnie
ret
:Skompilować:
I biegnij:
Wydruki:
Jeśli potrzebujesz, aby działało to wszędzie (tam, gdzie dostępna jest wersja bash) bez instalowania dodatkowych narzędzi, prawdopodobnie musisz użyć następującego polecenia, jak sugeruje @TimKennedy w komentarzach:
Należy pamiętać, że prawidłowy zakres zwracanych wartości wynosi 0..255 włącznie .
źródło
true
ifalse
są również w systemie Unix (a nawet POSIX), nie tylko w GNU.Jeśli potrzebujesz, aby status wyjścia był ustawiany przez wykonywane polecenia. Nie ma dedykowanego polecenia dla tego 1 , ale można użyć interpretera dowolnego języka, który ma możliwość wyjścia z dowolnym statusem wyjścia.
sh
jest najbardziej oczywisty:W przypadku większości
sh
implementacji ogranicza się to do kodów wyjściowych od 0 do 255 (sh
zaakceptuje większe wartości, ale może je skrócić, a nawet spowodować wysłanie sygnału do procesu wykonującego sięsh
jak w przypadku ksh93 dla kodów 257 do 320).Kod wyjścia może być dowolną liczbą całkowitą (
int
), ale pamiętaj, że musisz pobrać go za pomocąwaitid()
interfejsu, aby wartość nie została obcięta do 8 bitów (w Linuksie również nadal jest obciętawaitid()
). Dlatego rzadko (i nie jest to dobry pomysł) używanie kodów wyjścia powyżej 255 (użyj 0-123 do normalnej pracy).Alternatywnie:
(nie obcinają kodu wyjścia do 8 bitów).
Dzięki NetBSD
find
możesz:1
exit
jest standardowym poleceniem służącym do tego, ale ponieważ jest to wbudowane specjalne narzędzie powłoki , nie ma wymogu, aby w systemie plików istniało również polecenie o tej nazwie, tak jak w przypadku zwykłych wbudowanych systemów, a większość systemów nie ma takiegoźródło
Zapisz to w pliku o nazwie
returncode.c
igcc -o returncode returncode.c
źródło
argv[argc-1]
zamiastargv[1]
, i dlaczego nie jesteś sędzią, jeśliargc>2
. (2) Byłbym skłonny zrobićargv[1]
test przedargv[0]
testem, pozwalając użytkownikowi powiedziećtrue 56
lubfalse 56
zamiastreturncode 56
. Nie podajesz wiadomości, jeśliargv[0]
jest to słowo iargc>0
- to może być mylące. (3) Mam obsesję na punkcie łatwości obsługi, więc skorzystałbymstrcasecmp
zamiaststrcmp
. (4) Mam tendencję do sprawdzania poprawności parametrów i nie używam wartości zwracanejatoi
bez jej weryfikacji. Wydaje mi się, że dla takiego programu 2 ¢ nie ma to znaczenia.true
niefalse
przetwarza żadnych argumentów w systemach Linuxargv[0]
; programy/bin/true
i/bin/false
są różnymi plikami wykonywalnymi z zakodowanymi kodami wyjścia. Napisałeś program, który można zainstalować zarówno jako (true
ifalse
połączony), co jest sprytne. Ale pytanie dotyczy sposobu uzyskania statusu wyjścia określonego przez użytkownika. Twój program odpowiada na to pytanie, ale tylko jeśli jest zainstalowany pod inną nazwą. Tak długo, jak na to patrzyszargv
, uważam, że robienie tego w sposób, który sugeruję, utrzyma poziom sprytu, unikając potrzeby trzeciego łącza.Nie byłem do końca pewien, czy twoim jedynym problemem z
exit
poleceniem było wyjście z bieżącej powłoki, ale jeśli tak, podpowłoka może działać.Właśnie przetestowałem to na Cygwin Bash i to działa dla mnie.
Edycja: Przepraszam, że tęskniłem za działaniem poza kontekstem powłoki. W takim przypadku thsi nie pomogłoby bez zawinięcia go w
.sh
skrypt i wykonania go ze środowiska.źródło
$(exit 42)
próbuje wykonać dane wyjścioweexit 42
jako proste polecenie, które nie ma sensu (nie działałoby równieżyash
).(exit 42)
(działający równieżexit
w podpowłoce, ale pozostawiający dane wyjściowe w spokoju) miałby więcej sensu i byłby bardziej przenośny (nawet do csh lub powłoki Bourne'a).