Mam krótki skrypt, który jest wykonywany przez demona systemu dla określonych zdarzeń. Wiem, że zdarzenie ma miejsce i skrypt działa, ale nie robi tego, co zamierzam. O dziwo dzieje się tak, gdy uruchamiam go ręcznie, więc jestem bardzo zdezorientowany.
Jak mogę dowiedzieć się, co się dzieje? Skrypt jest w zasadzie serią takich poleceń:
/bin/foo on 3
sudo bar a
U&L
. Źle odczytałem tytuł i zasugerowałem „Rejestrowanie danych wyjściowych skryptu systemowego w celu debugowania”, by cel był bardziej przejrzysty. Również mój mózg zawiesza się, gdy czytam tefoo
bar
przykłady, wolę coś, co wygląda bardziej realnie. Niechętnie edytuję dowolny post, więc zostawię to tobie, jeśli uważasz, że można go poprawić.Odpowiedzi:
Po pierwsze, jeśli skrypt jest uruchamiany przez demona systemowego i ten demon działa z uprawnieniami administratora, nie trzeba go używać
sudo
. Obejmuje toinit
(isystemd
), które obejmujerc.local
. Jeśli ten demon nie działa z uprawnieniami administratora,sudo
nie będzie działał, chyba że/etc/sudoers
jest skonfigurowany tak, aby na to pozwalać (i bez hasła). Użytkownicy Raspbian mogą być tym zdezorientowani, ponieważpi
użytkownik może domyślnie robić cokolwiek (a jeśli zajrzysz,/etc/sudoers
zobaczysz, jak to się robi ).Następnie możesz przechwycić dane wyjściowe z dowolnego
bash
skryptu lub dowolnego zestawu poleceń w skrypcie bash, wykonując je w podpowłoce: 1()
Wskazuje podpowłoce . Wszystkie dane wyjściowe z czegokolwiek w tym są przekierowywane do/var/log/myTestLog.txt
pliku. Kilka uwag:&>
to bashizm , więc jeśli skrypt jest wykonywany za pomocą shebang w pierwszym wierszu, powinno być#!/bin/bash
, nie tylko/bin/sh
. „Bashizmy” działają tylko wbash
powłoce.Obejmuje to
/etc/rc.local
, które domyślnie używa/bin/sh
(tj. Tak, możesz bezpiecznie zmienić to na/bin/bash
)./var/log
wymaga uprawnień roota do pisania. Jeśli proces nie ma takiego, użyj lub utwórz katalog, który znasz. W razie wątpliwości, jeśli możesz to przetestować bez konieczności zamykania lub ponownego uruchamiania systemu, użyj polecenia/tmp
, które można zapisać na całym świecie (tj. Przez kogokolwiek). Jednak/tmp
nie utrzymują się po drugiej stronie butów. Jest to także mała partycja oparta na pamięci RAM, więc nie zapisuj na niej żadnych danych. To nie jest twoja karta SD [tak naprawdę jest w obecnych wersjach Raspbian, ale nie licz na to w praktyce] .&>
nadpisze wszystko wmyTestLog.txt
. Jeśli zamiast tego chcesz dołączyć do istniejącego dziennika, co może być dobrym pomysłem do celów debugowania, użyj&>>
. Następnie możesz dodać polecenie na początku tej podpowłoki w następujący sposób:Aby oddzielić informacje od każdego uruchomienia. Jeśli nie masz pewności, co to robi, spróbuj w wierszu polecenia.
Ten ostatni punkt jest dobrą ilustracją czegoś, co możesz zrobić w odniesieniu do poleceń, które niczego nie wypisują - ale większość z nich robi to, jeśli na przykład użyjesz słowa
-v
„gadatliwy”. Uwaga na niektóre polecenia-v
oznacza „informację o wersji wydruku”. Zajrzyj na stronę podręcznika, aby sprawdzić, czy polecenie to działa i jak to działa (niektóre polecenia również używają innego przełącznika niż-v
).Zgodnie z konwencją polecenia również zwracają wartość 0 po zakończeniu. Czasami nazywa się to „statusem wyjścia” i zwykle go nie widzisz, ale powłoka pokaże ci
echo $?
. PróbowaćDostaniesz 0 i 2. Jeśli następnie przejrzysz stronę man
ls
pod „Status wyjścia”, zobaczysz dość nieokreśloną, tajemniczą:Co może, ale nie musi, być lepsze niż nic, ale proszę bardzo.
Przynajmniej oznacza to, że polecenie z jakiegoś powodu nie powiodło się. Status wyjścia umożliwia także wykonywanie takich czynności:
W
&&
tym przypadku oznacza „jeśli pierwsze polecenie się powiedzie”, zakładając, że pierwsze polecenie stosuje konwencję zwracania 0 (dlatego zwykle tak się dzieje). Jeśli/bin/foo
nie działa, nie można go znaleźć itp.,sudo bar
To nigdy się nie wydarzy.Użycie kombinacji rejestrowania komunikatów i wykonania warunkowego (
&&
) powinno znacznie przybliżyć Cię do rozwiązania problemu lub przynajmniej uzyskać informacje, które mogą być przydatne dla innych osób w rozwiązaniu problemu. Bez tego, większość osób, które często mogą to zrobić, to zgadywanie.1. Możesz wykonać to samo przekierowanie wyjścia dla całego skryptu od wewnątrz, używając:
Na górze (lub w dowolnym miejscu i będzie to dotyczyło wszystkiego później).
źródło
Jednym ważnym aspektem, który ludzie często zapominają, uruchamiając skrypty, ponieważ demony są środowisko powłoki, a
$PATH
w szczególności zmienne. W twoim przykładzie druga linia polega na$PATH
: pełnej nazwiesudo
jest/usr/bin/sudo
, a twoja powłoka użytkownika wie to tylko dlatego, że kazano jej szukać/usr/bin
podczas szukania plików wykonywalnych. To samo dotyczybar
.Biorąc pod uwagę, że
sudo
nie jest to konieczne podczas uruchamiania skryptów jako demonów, druga linia powinna wyglądać następująco:źródło