Jak wyłączyć RPi podczas pracy bez głowy

33

Jeśli korzystam z Pi bez głowy, czy istnieje polecenie, którego mogę użyć do bezpiecznego wyłączenia, czy powinienem po prostu odłączyć przewód zasilający?

Eric Wilson
źródło
poweroff to najlepszy sposób, aby go wyłączyć
RahulAN,
poweroffto prawdopodobnie symboliczny link do halt...! 8-)
SlySven

Odpowiedzi:

40

Możesz bezpiecznie zamknąć pi za pomocą

shutdown -h now

-H po prostu zatrzymuje wszystkie procesy

Impulsy
źródło
7
Może warto się nauczyć w tym samym czasie, że -r wykona restart (zamknięcie + ponowne uruchomienie).
XTL,
6
Nie zapomnij, że musisz być rootem, aby zamknąć system lub użyć sudo.
keiki
1
Alternatywniesudo poweroff
dniu
3
-hRobi zatrzymanie całego systemu - bez że opcja shutdownweźmie initdo run-Poziom 1 - tzn trybie pojedynczego użytkownika, czekając logowania super-użytkownika (root password potrzebna). Po zalogowaniu się jako root, a następnie wylogowaniu, initponownie wykona czynności niezbędne do uruchomienia RPi w trybie wielu użytkowników - tak jak w przypadku oryginalnego rozruchu (po zakończeniu wszystkich rzeczy, tj. fsckItp /etc/rc.local.) robi to). W tym kontekście „zamknięcie” oznacza „wyłączenie systemu dla zwykłych użytkowników” ...
SlySven,
Tak, ale w shutdownrzeczywistości zajmuje trochę czasu i rozłącza wszystkich klientów ssh, gdy jest w tym czasie. Skąd więc wiesz, kiedy można bezpiecznie wyjąć kartę SD?
Tom Auger,
40

Nie należy po prostu odłączać przewodu, ponieważ może to czasami (być może często) prowadzić do uszkodzenia systemu plików.

Jak mówi Impluss, użyj shutdown. Niedawno natknąłem się na poradę dotyczącą konfigurowania udev, aby uruchamiał zamykanie lub restart, gdy określone urządzenie USB jest odłączone. Jest to przydatne, jeśli system przestał reagować lub utracił połączenie sieciowe, a Ty nie możesz lub nie zawracasz sobie głowy podłączaniem do niego ukrytych urządzeń (interfejs użytkownika).

Jest dobre, być może nieco przestarzałe, ale dobrze napisane wprowadzenie do reguł udev | tutaj | . Podstawową ideą jest uzyskanie niektórych informacji o urządzeniu za pośrednictwem lsusb, na przykład:

Bus 002 Device 003: ID 0bda:8176 Realtek Semiconductor Corp. RTL8188CUS 802.11n WLAN

Trzecie pole oznaczone identyfikatorem to identyfikator dostawcy i modelu oddzielone dwukropkiem. Zakładając, że nie masz podłączonych wielu identycznych urządzeń, ta kombinacja powinna być unikalna.

Możesz uzyskać bardziej szczegółowe istotne informacje za pośrednictwem udevadm monitor --udev --property, które będą raportować do standardu, dopóki go nie zabijesz, np. po odłączeniu od góry klucza Teenie weenie wifi wypluwa się:

UDEV  [2834.504860] remove   /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.6 (usb)
ACTION=remove
[...]
ID_BUS=usb
ID_MODEL=802.11n_WLAN_Adapter
ID_MODEL_ENC=802.11n\x20WLAN\x20Adapter
ID_MODEL_ID=8176
[...]
ID_VENDOR=Realtek
ID_VENDOR_ENC=Realtek
ID_VENDOR_ID=0bda

Zwróć uwagę na pola ID_MODEL i ID_VENDOR. Oto, czego chcesz użyć w swojej regule udev. Istnieje kilka nieaktualnych lub niepoprawnych źródeł online, które sugerują użycie pól ATTR, ale są to pola ENV w odniesieniu do zdarzenia „usuń”.

Utwórz plik w /etc/udev/rules.d. Tak samo jest niezależnie od dystrybucji. Plik musi się kończyć, .rulesa wszystkie pliki w tym katalogu są przetwarzane leksykograficznie. Uważam, że reguły zadeklarowane wcześniej mają pierwszeństwo, więc użycie 00-my_pi.rulesspowoduje zachowanie go na początku wiersza (liczby będą sortowane przed literami). Dodaj w nim wiersz taki jak:

ACTION=="remove", ENV{ID_VENDOR_ID}=="0bda", ENV{ID_MODEL_ID}=="8176", RUN+="/sbin/shutdown -h now"

Uważaj ==i nie =. Jeśli użyjesz później, kryteria nie mają znaczenia. W takim przypadku możesz otrzymać regułę udev pasującą do dowolnego wydarzenia!

Upewnij się, że jest załadowany udevadm control --reload-rules. Teraz, gdy wyciągniesz klucz Wi-Fi, pi powinno całkowicie się zamknąć ... daj mu chwilę na zrobienie tego, a następnie możesz odłączyć zasilanie (spróbuj po podłączeniu ekranu po raz pierwszy). Możesz także użyć tego do ponownego uruchomienia - zobacz man shutdown, a właściwie stronę podręcznika dla wszystkich poleceń tutaj wymienionych;)

Złotowłosa
źródło
3
Nie sądzę, żeby o to pytał OP. Ale +1 za informację.
Vincent P
Schludny! Oczywiście powinieneś mieć także możliwość wyzwolenia (usunięcia lub podłączenia) dowolnego urządzenia USB
Tobias Kienzler
To dobry początek. Uruchomienie wyłączania uruchamiane przez przycisk GPIO (jakikolwiek sposób, aby dostać coś takiego do zdarzenia ACPI lub HID?) Lub coś byłoby jeszcze bardziej przydatne.
XTL,
@XTL: Wokół są demony apci, więc jest to możliwe (jądro zgłasza się za pośrednictwem proc itp.). To samo dotyczy co najmniej potencjalnie gpio na pi. Zdarzenia HID są bardziej kontekstowe (przykładowym kontekstem jest środowisko graficzne GUI), a fakt, że możesz wpisać „halt” (== shutdown -h nowna Linuksie) może złagodzić potrzebę takiego;)
goldilocks
Jest to idealne, klucz sprzętowy jest jedyną rzeczą, która jest podłączona do naszego Pi, i często tracimy połączenie, więc musimy go przenieść, nie powodując utraty zasilania.
noio
8

Aby zamknąć, możesz wydać następujące polecenie:

sudo init 0

Aby ponownie uruchomić:

sudo init 6
zarejestrowany użytkownik
źródło
Jest to w dużym stopniu uzależnione od poziomu uruchamiania, który jest koncepcją wciąż używaną przez system operacyjny. Przejście na systemd sprawia, że ​​jest to obecnie mniej użyteczne.
Stephen Michael Kellat,
Pomijając dzisiejszą edycję, być może zauważyłeś, że jest to dość stara odpowiedź. Pytanie ma również więcej niż dwa lata.
Zarejestrowany użytkownik
1
W tym zastosowaniu uważa się, że lepiej jest użyć sudo telinit #gdzie # jest liczbą od 0 do 6 - telinit jest dowiązaniem symbolicznym do init, który rozpoznaje, że nie jest wywoływany przez swoją pierwotną nazwę „init” (i że nie ma PID 1!), Więc tworzy potok do prawdziwego procesu „init” i każe mu zmienić bieżący poziom działania na nową wartość podaną jako argument liczbowy . telinitto skurcz „powiedz init nowemu poziomowi działania”.
SlySven
7

Moją preferowaną metodą jest użycie sudo poweroff, która jest aliasem dla polecenia zamykania, która również zabija zużycie energii.

sdenton4
źródło
7

Chociaż pytanie zostało już odpowiednio udzielone; moje preferencje różnią się od tych, na które już udzielono odpowiedzi.

Jak powiedzieli inni, unikaj tylko ciągnięcia za moc. Moje preferowane polecenia (zarówno jako root, jak i przed sudo):

Aby zatrzymać: halt(dla Wheezy i wcześniejszych polecenie to również wyłącza system; dla Jessie tak naprawdę nie wyłącza się, chociaż można bezpiecznie wyciągnąć wtyczkę po zakończeniu) halt -p; shutdown now -hlub po prostu poweroffsą wymagane dla Jessie ...

Uruchomić ponownie: reboot

Wolę te polecenia, ponieważ są one proste, łatwe do zapamiętania i oczywiste ...

Jeremy Davis
źródło
Nie chcę skręcać, ale myślę, że to trochę trudne, że moja odpowiedź (sprzed 8 miesięcy) została odrzucona, ponieważ Debian (tj. Powyżej Raspbian) zmienił sposób, w jaki działają ich polecenia (zakładając, że dlatego zostałem odrzucony) . Również moja odpowiedź (przed edycją) nadal odpowiadała OP (tj. Jeśli zatrzymasz system, możesz bezpiecznie wyciągnąć wtyczkę ...) FWIW Zaktualizowałem odpowiedź, więc jest jasne, że to nie działa już jako użytkownik mam nadzieję ...
Jeremy Davis,
Nie powinieneś przyzwyczajać się do używania haltlub poweroff, ponieważ są to tylko aliasy shutdown -h nowz narzędziami GNU, ale w innych systemach natychmiast wyłączysz system, zabijając wszystkie programy i prawdopodobnie uszkadzając system plików. To powiedziawszy, możesz używać go na Raspberry Pi z większością dystrybucji Linuksa, ale jeśli używasz pi do nauki, możesz to zrobić „we właściwy sposób”.
allo
@allo - Być może masz rację również w przypadku starszych wersji systemu operacyjnego Linux i innych wersji systemu operacyjnego Linux innych niż Linux (np. BSD). Ale w nowszym systemie operacyjnym Linux, który korzysta z SystemD (tj. Obecnie większość Linuksa), tak nie jest. halt, poweroff, rebootI shutdownsą wszystkie dowiązania do systemctl(z oryginalnego polecenia również minęła). To następnie wyzwala odpowiedni cel SystemD: np poweroff.target. FWIW poweroff.targetwyzwala wywołanie ACPI w celu czystego zamknięcia systemu. AFAIK w dzisiejszych czasach poweroff(lub systemctl poweroff) JEST „właściwą drogą”. :)
Jeremy Davis
Podobnie jak w wielu przypadkach z Linuksem, jest na to więcej niż jeden sposób. Ale powinieneś rozważyć, czy nie chcesz się tego uczyć w sposób opisany w standardzie, po którym następują również inne systemy uniksowe. Jako użytkownik Linuksa nie ma dla ciebie żadnych korzyści, ale kto wie, kiedy wypróbujesz inny system w przyszłości? nie polegaj na postoju i nie polegaj na rm, aby mieć --no-preserve-rootflagę. Nie polegaj na / bin / sh będącym / bin / bash (nie jest to nawet prawdą w przypadku systemów opartych na Debianie). Często przydaje się próba użycia „właściwej” metody, nawet jeśli obecnie działałoby to w inny sposób.
allo
1
@allo - Uczciwe punkty i myślę, że dzielenie się swoją wiedzą na temat różnych systemów jest naprawdę niesamowite, i zgadzam się, że z pewnością warto zauważyć różnice między systemami i odpowiednie ograniczenia. Chociaż nie zgadzam się z twoją sugestią, że twoja droga jest drogą „właściwą”. Może to być sposób „zgodny z POSIX-em”, ale to nie czyni, że jeden sposób jest „właściwy”, a drugi „zły”. Np. Używanie bash (i bashisms) jest całkowicie uzasadnione IMO, chociaż zgadzam się, że jeśli potrzebujesz / chcesz bash, powinieneś jawnie go użyć /bin/bash. FYI, moja perspektywa jest bardzo skoncentrowana na Debianie ...
Jeremy Davis,
4

Aby go dodać, jeśli chcesz dodać trochę sprzętu, możesz napisać małego demona, aby sondować piny GPIO, a po potwierdzeniu określonego pinu zrestartuj (lub zamknij) Pi.

Ponadto wszystkie wymienione tutaj polecenia mogą być uruchamiane przez SSH.

Maxthon Chan
źródło
3

Wiem, że minęły 3 lata od pierwszego pytania. Ale właśnie dostałem Raspberry Pi i mam problem z wyłączeniem go, jeśli zapomniałem podłączyć go do ekranu monitora i nie ma on żadnego połączenia sieciowego.

Napisałem mały skrypt w języku Python, który automatycznie wyłącza go w ciągu 60 sekund, podłączając napęd typu thumbdrive zawierający plik o nazwie „pi_auto_shutdown”.

Po prostu wywołaj ten skrypt z rc.local.

Mam nadzieję, że to pomoże.

shutdown_loop_delay = 60
shutdown_flag_file = 'pi_auto_shutdown'

def poll_shutdown_flag():
    """check whether a shutdown flag file in a usb drive exists"""

    ## run mount command
    ## sample mount output: "/dev/sda1 on /media/path/"
    output, error = subprocess.Popen('mount', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
    if len(error) > 0:
        log('mount error: {}'.format(error))
        return False

    ## parse mount output
    for output_line in output.split('\n'):
        output_words = output_line.split(' ')

        if len(output_words) < 3:
            continue

        if output_words[0].startswith('/dev/sd'):
            flag_file_path = os.path.join(output_words[2], shutdown_flag_file)
            if os.path.isfile(flag_file_path):
                return True

    return False

def shutdown():
    """shutdown the system immediately"""
    subprocess.Popen('sudo shutdown -h now', shell=True).communicate()

def loop_shutdown():
    while True:
        time.sleep(shutdown_loop_delay)
        if poll_shutdown_flag():
            shutdown()

loop_shutdown()
VoidMain
źródło
Ciekawe podejście
Eric Wilson,
1

I ssh do mojego pudełka RPI za pomocą polecenia

$ ssh rpi sudo poweroff

rpi to alias adresu IP mojej skrzynki RPi i jest zdefiniowany w pliku ~ / .ssh / config .

ismartbuoy
źródło