2012-10-21 13 views
29

Próbuję poprawić mój skrypt powiadamiający. Sposób działania skryptu polega na tym, że umieściłem go za długo działającym poleceniem powłoki, a następnie wszystkie rodzaje powiadomień są wywoływane po zakończeniu długiego działania skryptu.Uzyskiwanie kodu wyjścia ostatniego polecenia powłoki w innym skrypcie

Na przykład:

sleep 100; my_notify 

Byłoby miło, aby uzyskać kod zakończenia długiego skrypt uruchomiony, problemem jest to, że wywołanie my_notify tworzy nowy proces, który nie ma dostępu do zmiennej $?.

Porównaj:

~ $: ls nonexisting_file; echo "exit code: $?"; echo "PPID: $PPID" 
ls: nonexisting_file: No such file or directory 
exit code: 1 
PPID: 6203 

vs.

~ $: ls nonexisting_file; my_notify  
ls: nonexisting_file: No such file or directory 
exit code: 0 
PPID: 6205 

Skrypt my_notify ma w nim następujące:

#!/bin/sh 
echo "exit code: $?" 
echo "PPID: $PPID" 

szukam sposób, aby uzyskać kod zakończenia poprzednie polecenie bez zbytniej zmiany struktury polecenia. Mam świadomość, że jeśli zmienię to tak, by działał bardziej jak time, np. my_notify longrunning_command... mój problem zostałby rozwiązany, ale ja naprawdę podoba mi się, że mogę to zrobić pod koniec polecenia i obawiam się komplikacji tego drugiego rozwiązania.

Czy można to zrobić, czy jest to zasadniczo niezgodne ze sposobem działania muszli?

Moja powłoka to zsh, ale chciałbym, aby działała również z bash.

Odpowiedz

31

Aby to osiągnąć, naprawdę trzeba użyć funkcji powłoki. W przypadku takiego prostego skryptu powinno być dość łatwe, aby działało zarówno w zsh, jak i bash. Wystarczy umieścić w pliku:

my_notify() { 
    echo "exit code: $?" 
    echo "PPID: $PPID" 
} 

Następnie należy pobrać ten plik z plików startowych powłoki. Chociaż od tego będzie uruchamiany z wnętrza interaktywnej powłoki, możesz użyć $$ zamiast $ PPID.

6

Jest niezgodny. $?tylko istnieje w bieżącej powłoce; jeśli chcesz, aby była dostępna w podprocesach, musisz skopiować ją do zmiennej środowiskowej.

Alternatywą jest napisanie funkcji powłoki, która używa jej w pewien sposób.

2

Jedną z metod wdrożenia tego może być użycie znacznika EOF i skryptu głównego, który utworzy skrypt my_notify.


#!/bin/bash 

if [ -f my_notify ] ; then 
rm -rf my_notify 
fi 

if [ -f my_temp ] ; then 
rm -rf my_temp 
fi 

retval=`ls non_existent_file &> /dev/null ; echo $?` 
ppid=$PPID 
echo "retval=$retval" 
echo "ppid=$ppid" 
cat >> my_notify << 'EOF' 
#!/bin/bash 

echo "exit code: $retval" 
echo " PPID =$ppid" 
EOF 

sh my_notify 

Można udoskonalić ten skrypt na swoim celu.

Powiązane problemy