Як вимкнути RPi при запуску без голови


33

Якщо я запускаю Pi без голови, чи є команда, яку я можу використовувати для безпечного вимкнення, чи мені просто виймати шнур живлення?



poweroffце, мабуть, символічне посилання на halt…! 8-)
SlySven

Відповіді:


40

Ви можете безпечно вимкнути пі, використовуючи

shutdown -h now

-H просто зупиняє всі процеси


7
Можливо, варто вивчити одночасно, що -r зробить перезапуск (вимкнення + перезавантаження).
XTL

6
Не забувайте, що ви маєте права на вимкнення або використання sudo.
keiki

1
Як варіантsudo poweroff
берто

3
-hРобить зупинити всю систему - без такий варіант shutdownбуде приймати initдля виконання 1 -го рівня - тобто однокористувальницький режим, чекаючи входу в супер-користувача (корінь пароля). Після входу в систему як root, а потім виходу із системи init, потім повторюватимуться речі, необхідні для підключення RPi в багатокористувацькому режимі - як це було б під час початкового завантаження (після завершення всіх матеріалів, тобто fsckтощо, запускаючи /etc/rc.localце робить тоді). У цьому контексті "вимкнення" - це "зняти систему офлайн для звичайних користувачів" ...
SlySven

Так, але shutdownнасправді потрібен певний час для виконання та відключення будь-яких ssh-клієнтів, поки він працює. Тож як ви знаєте, коли безпечно, наприклад, вийняти SD-карту?
Том Ожер

40

Не відключайте шнур від розетки, оскільки це може час від часу (можливо, часто) призводити до пошкодження файлової системи.

Як каже Impluss, використовуйте shutdown. Нещодавно я наткнувся на підказку щодо налаштування udev для запуску або перезавантаження, коли певний пристрій USB відключено. Це корисно, якщо система перестала реагувати або втратила мережеве з'єднання, і ви не можете чи не хочете турбуватися про підключення до нього прихованих (пристрій людського інтерфейсу) типу клавіатури.

Є хороший, можливо, м'яко застарілий, але добре написаний, вступ до правил udev | тут | . Основна ідея полягає в тому, щоб ви отримали певну інформацію про пристрій lsusb, наприклад:

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

Третє поле, позначене ID, - ідентифікатор постачальника та моделі, розділених двокрапкою. Припускаючи, що у вас немає підключених декількох однакових пристроїв, ця комбінація повинна бути унікальною.

Ви можете отримати більш детальну релевантну інформацію через udevadm monitor --udev --property, яка буде повідомляти про стандарт, поки ви не вб'єте її, наприклад. коли я відключаю шнур wifi donile teenie weenie, він плюється:

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

Зауважте поля ID_MODEL та ID_VENDOR. Це те, що ви хочете використовувати у своєму праві udev. У мережі є деякі застарілі або неправильні джерела, які пропонують використовувати поля ATTR, але це поля ENV стосовно події "видалити".

Створіть файл у /etc/udev/rules.d. Це те саме, незалежно від розподілу. Файл повинен закінчуватися, .rulesі всі файли в цьому каталозі обробляються лексикографічно. Я вважаю, що правила, задекларовані раніше, мають перевагу, тому використання 00-my_pi.rulesбуде тримати його в передній частині рядка (числа впорядковуються перед літерами). До нього додайте рядок, як:

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

Остерігайся ==і ні =. Якщо ви використовуєте пізніші, критерії безглузді. У такому випадку ви можете закінчитись правилом udev, яке відповідає будь-якій події!

Переконайтеся, що це завантажено udevadm control --reload-rules. Тепер, коли ви виймаєте шнур Wi-Fi, пі має чисто закритись ... дайте йому хвилину, і ви можете відключити живлення (спробуйте це за допомогою екрана, який додається вперше). Ви також можете використати це для перезавантаження - дивіться man shutdown, і, власне, сторінку man для всіх згаданих тут команд;)


3
Я не думаю, що це те, що просив ОП. Але +1 для інформації.
Вінсент П

Акуратно! Звичайно, ви також повинні мати можливість видалення (або підключення) довільного USB-пристрою, що викликає це
Tobias Kienzler

Це приємний початок. Завершення роботи, викликане кнопкою GPIO (будь-який спосіб отримати щось подібне до події ACPI чи HID?), Або щось було б ще зручніше.
XTL

@XTL: Демони apci навколо, так що це можливо (ядро звітує через proc тощо). Це ж принаймні потенційно стосується гпіо на пі. Події HID є більш контекстуальними (наприклад, контекст є середовищем робочого столу графічного інтерфейсу), і те, що ви можете ввести "halt" (== shutdown -h nowв Linux), можливо, пом’якшує потребу в таких;)
goldilocks

Це ідеально, донгл - це єдине, що підключається до нашого Пі, і ми часто втрачаємо зв’язок, тому нам потрібно переміщати його, не псуючи його від втрати електроенергії.
noio

8

Ви можете видати таку команду для відключення:

sudo init 0

І перезавантажити:

sudo init 6

Це сильно залежить від рівнів запуску, що є концепцією, яку операційна система все ще використовує. Перехід на systemd робить це сьогодні менш придатним для використання.
Стівен Майкл Келлат

Виключаючи редагування з сьогоднішнього дня, можливо, ви помітили, що це досить стара відповідь. Питання також більше, ніж два роки.
Зареєстрований користувач

1
У цьому використанні вважається кращим використовувати sudo telinit #де # - це число між 0 і 6 - telinit - символічне посилання на init, яке визнає, що його не називають своїм основним іменем "init" (і що у нього немає PID 1!) Таким чином, він створює трубу до справжнього "init" процесу і повідомляє йому змінити поточний рівень запуску на нове значення, вказане як числовий аргумент . telinitє стисненням "Tell init new runlevel".
SlySven

7

Моїм кращим методом є використання sudo poweroff, яке є псевдонімом для команди відключення, яка також вбиває енергоспоживання.


7

Хоча на це питання вже відповіли належним чином; моє уподобання відрізняється від того, на що вже відповіли.

Як казали інші, уникайте просто тягнути владу. Мої вподобані команди (як кореневі, так і допоміжні sudo):

Для зупинки: halt(для Wheezy та перед цим команда також вимикає систему; для Jessie вона фактично не перетворюється на живлення, хоча можна витягнути штекер після закінчення) halt -p; shutdown now -hабо просто poweroffпотрібні Джессі ...

Щоб перезавантажити: reboot

Я віддаю перевагу цим командам, оскільки вони прямі вперед, легко запам’ятовуються і зрозуміли ...


Я не маю на увазі бажання, але я думаю, що це трохи суворо, що моя відповідь (починаючи з 8 місяців тому) була оскаржена, оскільки Debian (тобто вгору від Raspbian) змінив спосіб роботи їхніх команд (припускаючи, що тому я був проголосований) . Також моя відповідь (до редагування) все-таки відповідала на ОП (тобто якщо ви зупините систему, це безпечно витягнути вилку ...) FWIW Я оновив відповідь, так що зрозуміло, що це більше не працює як користувач може сподіваюсь ...
Джеремі Девіс

У вас не має звички використовувати haltабо poweroff, оскільки вони є лише псевдонімами для shutdown -h nowінструментів GNU, але в інших системах ви негайно вимкнете систему, знищивши всі ваші програми і, можливо, пошкодивши вашу файлову систему. Це сказав, що ви можете використовувати його на малиновому пі в більшості дистрибутивів Linux, але якщо ви використовуєте пі для навчання, ви можете зробити це "правильним способом".
Алло

@allo - Ви також можете скористатися застарілою ОС Linux та іншими нелінуксними версіями Unix, такими як ОС (наприклад, BSD). Але в останніх ОС Linux, які використовують SystemD (тобто більшість Linux сьогодні), це не так. halt, poweroff, rebootІ shutdownвсе символічні посилання на systemctl(з оригінальною командою також пройшли). Це запускає відповідну ціль SystemD: напр poweroff.target. FWIW poweroff.targetзапускає дзвінок ACPI для чистого відключення системи. Тож AFAIK в цей день і вік poweroff(або systemctl poweroff) "правильний шлях". :)
Джеремі Девіс

Як і у багатьох випадках з Linux, існує більше ніж один спосіб зробити це. Але вам слід врахувати, якщо ви не хочете вивчити це так, як це описано в стандарті, за яким також дотримуються інші системи Unix. Користь для вас, як користувач Linux, мала, але хто знає, коли ви спробуєте якусь іншу систему в майбутньому? не покладайтеся на зупинку і не покладайтеся на rm, щоб мати --no-preserve-rootпрапор. Не покладайтеся на / bin / sh being / bin / bash (це навіть не стосується систем на базі Debian). Часто корисно намагатися використовувати «правильний» спосіб, навіть якщо це в даний час буде працювати іншим способом.
Алло

1
@allo - Справедливі бали, і я думаю, що вам дійсно приголомшливо ділитися своїми знаннями про різні системи, і я погоджуюся, що, безумовно, варто відзначити відмінності між системами та відповідні обмеження. Хоча я не згоден з вашою думкою, що ваш шлях - це «правильний» шлях. Це може бути "сумісний з позицією" спосіб, але це не робить один спосіб "правильним", а інший - "неправильним". Наприклад, використання bash (і башизмів) є цілком законним IMO, хоча я згоден, що якщо вам потрібен / хочете bash, то ви повинні явно використовувати /bin/bash. FYI мій погляд дуже орієнтований на Debian ...
Джеремі Девіс

4

Просто для того, щоб кинути його, якщо ви додаєте трохи обладнання, ви можете написати невеликий демон, щоб опитувати шпильки GPIO і після затвердження певного штифта, перезавантажте (або вимкніть) Pi.

Крім того, всі команди, згадані тут, можуть працювати над SSH.


3

Я знаю, що минуло 3 роки після початкового питання. Але я щойно отримав свій Raspberry Pi, і у мене виникли проблеми з його вимкненням, якщо я забув підключити його до екрана монітора, і він не має жодного мережного підключення.

Я написав невеликий скрипт Python, щоб автоматично вимкнути його протягом 60 секунд, підключивши thumbdrive, що містить файл під назвою "pi_auto_shutdown".

Просто зателефонуйте до цього сценарію з rc.local.

Я сподіваюся, що це допомагає.

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()

Цікавий підхід.
Ерік Вілсон

1

Я SSH в мою скриньку RPI з допомогою команди

$ ssh rpi sudo poweroff

rpi - псевдонім для IP-адреси мого поля RPi і визначається у файлі ~ / .ssh / config .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.