Mam skrypt bash z różnymi instrukcjami if opartymi na argumentach wiersza poleceń, które przekazuję podczas jego wywoływania. Posiadanie pewnego rodzaju danych wyjściowych dotyczących uruchamianych poleceń jest pomocne w potwierdzeniu przepływu przez wszystkie instrukcje if, ale moje obecne rozwiązanie daje mi zbyt wiele informacji.
Używanie set -v
w skrypcie było nieco pomocne w wyświetlaniu poleceń drukowanych na ekranie podczas ich uruchamiania w skrypcie, jednak dostaję zbyt wiele poleceń. To prawie jak cała kopia skryptu.
Chcę danych wyjściowych, które pokazują, jakie polecenia są wykonywane, ale nie chcę widzieć komentarzy, nowych wierszy, wyrażeń w instrukcjach if itp.
Czy istnieje sposób, aby przed wydrukowaniem przekazać wszystkie możliwe dane wyjściowe wygenerowane przez opcję -v przez wyrażenie regularne? Lub jakieś inne rozwiązanie, aby uzyskać bash tylko do poleceń wyjściowych określonego „typu” (np. Które używają plików wykonywalnych, a nie tylko konkretnych poleceń, komentarzy itp.?)
[1] /programming/257616/sudo-changes-path-why był bardzo pomocny w tym i dostałem propozycję set -v
użycia.
Edytuj :
Podobny (ale nie identyczny) skrypt do tego, który uruchamiam:
#!/bin/bash
#get verbose command output
set -v
env=$1
if [ "$env" == "dev" ]; then
python ascript.py
fi
if [ "$env" == "prod" ]; then
#launching in prod will most likely fail if not run as root. Warn user if not running as root.
if [ $EUID -ne 0 ]; then
echo "It doesn't look like you're running me as root. This probably won't work. Press any key to continue." > /dev/stderr
read input
fi
#"stop" any existing nginx processes
pkill -f nginx
nginx -c `pwd`/conf/artfndr_nginx.conf
fi
Chcę tylko 2 możliwe zestawy linii wyjściowych z tego skryptu. Pierwszy:
python ascript.py
Drugi:
pkill -f nginx
nginx -c /some/current/directory/conf/artfndr_nginx.conf
źródło
set -v
wyniku chcesz, a które nie.Odpowiedzi:
Kiedy piszę bardziej złożone skrypty bash, używam małej funkcji do uruchamiania poleceń, które również wypisują polecenia uruchamiane do pliku dziennika:
Następnie w moim skrypcie uruchamiam takie polecenia:
Jeśli nie chcesz drukować polecenia, po prostu uruchom je normalnie.
Możesz ustawić
$LOG
nazwę pliku lub po prostu go usunąć i wydrukować na stdout lub stderr.źródło
v python ascript.py
nieeval ..... || ok=1
: ustawi ok na „1” tylko wtedy, gdy „eval ...” nie powiedzie się ?? Może miałeś na myśli „&&”? A jeśli miałeś na myśli, dodaj „ok = 0” przed linią eval, aby za każdym razem „resetować”. Lub po prostu zmień nazwę „ok” na „błąd”? wydaje się, że o to tu chodziło. Tak więc na koniec:eval "$@" 2>> "$LOG" && error=0 || error=1
ok
zmienną, która zatrzyma skrypt, jeśli jakiekolwiek polecenie zawiedzie. Ponieważ nie miało to tutaj znaczenia, usunąłem go, ale zapomniałem usunąć|| ok=1
. Dzięki, naprawione teraz."
otaczającą instrukcję eval, ponieważ polecenie jest już otoczone przez"
sUżyj podpowłoki, tj .:
Na przykład:
odbitki
źródło
set -x; cmd; set +x
kilku powodów. Po pierwsze, nie resetuje sięset -x
w przypadku, gdy był wcześniej włączony. Po drugie, zakończenie skryptu wewnątrz nie powoduje, że pułapki są wykonywane przy ustawionych szczegółach.Widziałem stosowane metody podobne do @ terdona. To początki tego, które języki programowania wyższego poziomu wywołują rejestratory i oferują jako pełnowymiarowe biblioteki, takie jak log4J (Java), log4Perl (Perl) itp.
Możesz dostać coś podobnego używając
set -x
Bash, jak wspomniałeś, ale możesz go użyć, aby podkręcić debugowanie tylko podzbioru poleceń, owijając nimi bloki kodu.Przykłady
Oto jeden wzór wkładki, którego możesz użyć.
Możesz owinąć je w ten sposób dla wielu poleceń w skrypcie.
Log4Bash
Większość ludzi jest nieświadoma, ale Bash ma również log4 *, Log4Bash . Jeśli masz bardziej skromne potrzeby, warto poświęcić czas na ich skonfigurowanie.
Przykłady
Oto kilka przykładów użycia log4bash.
Log4sh
Jeśli chcesz czegoś, co sklasyfikowałbym jako więcej pełnej mocy frameworka log4 *, dałbym Log4sh szansę.
fragment
Log4sh obsługuje kilka powłok, nie tylko Bash.
Został również przetestowany na kilku systemach operacyjnych, nie tylko na Linuksie.
Korzystanie z frameworka log4 * zajmie trochę czasu, ale warto, jeśli masz bardziej wymagające potrzeby związane z logowaniem. Log4sh korzysta z pliku konfiguracyjnego, w którym można zdefiniować programy dołączające i kontrolować formatowanie wyświetlanych danych wyjściowych.
Przykład
Teraz kiedy go uruchomię:
UWAGA: Powyższe konfiguruje program dołączający jako część kodu. Jeśli chcesz, możesz to wyodrębnić do własnego pliku,
log4sh.properties
itp.Skorzystaj z doskonałej dokumentacji Log4sh, jeśli potrzebujesz dodatkowych informacji.
źródło
set
polecenia, które muszę wprowadzić, na przemian wokół komentarzy itp., Więc po prostu posiadanie funkcji na górze mojego skryptu, z wywołaniem funkcji pojedynczego znaku poprzedzonego wszystkie „ważne” wiersze skryptu wydawały mi się na razie ładniejsze. (pojedynczy znak, ponieważ funkcja ma nazwę jednego znaku)echo
własnej funkcjimecho
, a następnie przekazanie przełącznika do programu zwanego-v
verbose, gdy chcę wyłączyć. Mogę też sterować za pomocą 2. przełącznika argumentów, który określa nazwę funkcji, więc mam 2 osie, na których można kontrolować rejestrowanie. Jest to często brama do log4bash.set -x
drukuje polecenia podczas ich wykonywania. Nie drukuje komentarzy.set -x
jest praktyczny do debugowania (w przeciwieństwie do tego,set -v
co nie jest bardzo przydatne). Zsh ma lepszą wydajnośćset -x
niż bash, na przykład pokazuje, która funkcja jest aktualnie wykonywana i numer linii źródłowej.Można
trap
DEBUG
, a następnie przetestować naBASH_COMMAND
zmienną . Dodaj to na początku skryptu:Kod jest czytelny; po prostu sprawdza, czy pierwszy argument zaczyna się od
python
lubpkill
, i wypisuje go, jeśli tak jest. I pułapka używaBASH_COMMAND
(który zawiera polecenie, które zostanie wykonane) jako pierwszego argumentu.Pamiętaj, że podczas
case
korzystania z globów równie łatwo możesz:I używaj wyrażeń regularnych.
źródło
To jest poprawiona wersja zgrabnej funkcji Stevena Penny'ego. Drukuje argumenty w kolorze i przytacza je w razie potrzeby. Użyj go, aby selektywnie powtórzyć polecenia, które chcesz śledzić. Ponieważ cytaty są wyprowadzane, możesz kopiować wydrukowane linie i wklejać je do terminala w celu natychmiastowego ponownego wykonania podczas debugowania skryptu. Przeczytaj pierwszy komentarz, aby dowiedzieć się, co zmieniłem i dlaczego.
Przykładowe użycie z wyjściem:
# xc echo "a b" "c'd" "'" '"' "fg" '' " " "" \# this line prints in green
echo 'a b' c\'d \' '"' fg '' ' ' '' '#' this line prints in green
a b c'd ' " fg # this line prints in green
Druga linia powyżej jest drukowana na zielono i można ją skopiować i wkleić, aby odtworzyć trzecią linię.
Dalsze uwagi
Oryginalny xc Stevena-Penny'ego jest sprytny i zasługuje na wszystkie kredyty. Zauważyłem jednak pewne problemy, ale nie mogłem bezpośrednio skomentować jego postu, ponieważ nie mam wystarczającej reputacji. Zrobiłem więc sugerowaną edycję jego postu, ale recenzenci odrzucili moją zmianę. Dlatego uciekłem się do opublikowania moich komentarzy jako tej odpowiedzi, chociaż wolałbym móc edytować własną odpowiedź Steve'a Penny'ego.
To, co zmieniłem, to odpowiedź Stevena-Penny'ego
Naprawiono: drukowanie ciągów zerowych - nie były drukowane. Naprawiono: drukowanie ciągów, które obejmują
%
- powodowały błędy składniowe awk. Zastąpionyfor (j in ...)
przez,for (j = 0, ...)
ponieważ ten pierwszy nie gwarantuje kolejności przechodzenia przez tablicę (zależy od implementacji awk). Dodano 0 do liczb ósemkowych dla przenośności.Aktualizacja
Od tego czasu Steven Penny naprawił te problemy w swojej odpowiedzi, więc te uwagi pozostały tylko dla historycznego zapisu mojej odpowiedzi. Więcej informacji znajduje się w sekcji Komentarze.
źródło
Możesz użyć funkcji powłoki „sh_trace” z biblioteki stdlib POSIX, aby wydrukować polecenie w kolorze przed uruchomieniem. Przykład:
Podstawowa funkcja Awk:
źródło