Как отключить RPi при запуске без головы

33

Если я использую Pi без головы, есть ли команда, которую я могу использовать для безопасного выключения, или я должен просто отключить шнур питания?

Эрик Уилсон
источник
poweroff - лучший способ выключить его
RahulAN
poweroffвероятно символическая ссылка на halt...! 8-)
SlySven

Ответы:

40

Вы можете безопасно отключить пи с помощью

shutdown -h now

-H просто останавливает все процессы

Impulss
источник
7
Возможно, стоит узнать, что -r перезапустит (shutdown + reboot).
XTL
6
Не забывайте, что вы должны быть root, чтобы завершить работу или использовать sudo.
Кейки
1
В качестве альтернативыsudo poweroff
Берто
3
-hДелает остановить всю систему - без такой вариант shutdownбудет принимать initдля выполнения 1 -го уровня - то есть однопользовательский режим, ожидая входа в супер-пользователя (корень пароля). После входа в систему с правами администратора , а затем выхода из initзатем повторить материал , необходимый для приведения RPI в многопользовательском режиме - как это будет делать в оригинальной загрузки (после завершения всех вещей, то есть и fsckт.д., бегая /etc/rc.localчто это делает тогда). В этом контексте «выключение» означает «отключить систему для обычных пользователей» ...
SlySven
Да, но на shutdownсамом деле требуется некоторое время для выполнения, и отключает все клиенты SSH, пока он у него. Итак, как вы узнаете, когда, например, безопасно извлечь SD-карту?
Том Ожер
40

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

Как говорит Impluss, пользуйтесь shutdown. Недавно я наткнулся на совет о настройке udev для запуска или перезагрузки, когда конкретное USB-устройство отключено. Это полезно, если система перестала отвечать на запросы или потеряла соединение с сетью, и вы не можете или не будете беспокоиться о подключении к ней таких устройств, как клавиатура, как hid.

Хорошее, возможно, слегка устаревшее, но хорошо написанное введение в правила udev | здесь | , Основная идея заключается в том, что вы получаете некоторую информацию об устройстве lsusb, например:

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

Третье поле, помеченное как ID, представляет собой идентификатор поставщика и модели, разделенные двоеточием. Предполагая, что вы не подключили несколько идентичных устройств, эта комбинация должна быть уникальной.

Вы можете получить более подробную релевантную информацию через udevadm monitor --udev --property, которая будет сообщать стандарт, пока вы не убьете ее, например. когда я отсоединяю беспроводной ключ WiFi, он выплевывает:

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, и, собственно, справочную страницу для всех команд, упомянутых здесь;)

Златовласка
источник
3
Я не думаю, что это то, о чем спрашивал ОП. Но +1 за информацию.
Винсент П
Ухоженная! Разумеется, вы также должны иметь возможность удалить (или подключить) произвольное USB-устройство, чтобы вызвать это
Тобиас Кинцлер,
Это хорошее начало. Выключение, инициируемое кнопкой GPIO (любой способ получить что-то подобное для события ACPI или HID?) Или что-то еще, было бы еще удобнее.
XTL
@XTL: вокруг есть демоны apci, так что это возможно (ядро сообщает через proc и т. Д.). То же самое, по крайней мере, потенциально верно для gpio на пи. События 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является сокращением «скажи init новый уровень запуска».
SlySven
7

Мой предпочтительный метод заключается в использовании sudo poweroff, который является псевдонимом для команды выключения, которая также убивает энергопотребление.

sdenton4
источник
7

Пока на вопрос уже дан адекватный ответ; мои предпочтения отличаются от того, что уже было дано.

Как уже говорили другие, избегайте просто тянуть власть. Мои предпочтительные команды (либо с правами суперпользователя, либо с префиксом sudo)

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

Для перезагрузки: reboot

Я предпочитаю эти команды, так как они прямолинейны, легко запоминаются и самоочевидны ...

Джереми Дэвис
источник
Не хочу отрицать, но я думаю, что это немного грубо, что мой ответ (от 8 месяцев назад) был отвергнут, потому что Debian (т.е. выше по течению от Raspbian) изменил способ работы их команд (предполагая, что именно поэтому за меня проголосовали) , Кроме того, мой ответ (до редактирования) все еще отвечал на OP (то есть, если вы остановите систему, безопасно отключить штепсельную вилку ...) FWIW Я обновил ответ, так что ясно, что это больше не работает, как пользователь может надеюсь ...
Джереми Дэвис
У вас не должно быть привычки использовать haltили poweroff, поскольку они являются псевдонимами shutdown -h nowинструментов GNU, но в других системах вы немедленно выключите свою систему, убив все свои программы и, возможно, повредив вашу файловую систему. Тем не менее, вы можете использовать его на Raspberry Pi с большинством дистрибутивов Linux, но если вы используете Pi для обучения, вы можете сделать это "правильным образом".
Алло
@allo - Вы также можете быть правы для устаревших ОС Linux и других не Linux-подобных версий ОС (например, 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 является / bin / bash (это даже не относится к системам на основе Debian). Часто полезно попытаться использовать «правильный» способ, даже если в настоящее время он будет работать по-другому.
Алло
1
@allo - Справедливо, и я думаю, что это действительно здорово, что вы делитесь своими знаниями о различных системах, и я согласен, что, безусловно, стоит отметить различия между системами и соответствующие ограничения. Хотя я не согласен с вашим предположением, что ваш путь - это «правильный» путь. Это может быть «послеродовый» способ, но он не делает один путь «правильным», а другой «неправильным». Например, использование bash (и bashisms) является абсолютно законным IMO, хотя я согласен с тем, что если вам нужен / нужен bash, то вам следует явно использовать /bin/bash. К вашему сведению, моя перспектива очень ориентирована на Debian ...
Джереми Дэвис
4

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

Также все команды, упомянутые здесь, могут быть запущены через SSH.

Макстон Чан
источник
3

Я знаю, что это 3 года после первоначального вопроса. Но я только что получил свой Raspberry Pi, и у меня возникают проблемы с его выключением, если я забыл подключить его к экрану монитора, и у него нет сетевого подключения.

Я написал небольшой скрипт на Python, который автоматически выключал его в течение 60 секунд, подключив флэш-накопитель, содержащий файл с именем «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 .

ismartbuoy
источник