Comment arrêter RPi quand vous courez sans tête

33

Si je lance un Pi sans tête, puis-je utiliser une commande pour éteindre en toute sécurité ou dois-je simplement retirer le cordon d'alimentation?

Eric Wilson
la source
Power Off
poweroffest probablement un lien symbolique vers halt...! 8-)
SlySven le

Réponses:

40

Vous pouvez arrêter le pi en toute sécurité en utilisant

shutdown -h now

Le -h arrête tous les processus

Impulsion
la source
7
Cela vaut peut-être la peine d'apprendre en même temps que -r fera un redémarrage (shutdown + reboot).
XTL
6
N'oubliez pas que vous devez être root pour arrêter ou utiliser sudo.
keiki
1
Alternativementsudo poweroff
berto le
3
Le - -ht arrêter l'ensemble du système - sans cette option shutdownprendra initpour exécuter niveau 1 - à savoir, en mode utilisateur unique, en attente d'une connexion super-utilisateur (mot de passe root nécessaire). Une fois connecté en tant que root puis vous déconnecter initensuite refaire les choses nécessaires pour mettre l'IPD en mode multi-utilisateur - comme il le ferait au cours de la démarrage d' origine (après la fin de toutes les choses, par exemple , fscketc., en cours d' exécution /etc/rc.localque fait alors). Dans ce contexte, "l'arrêt" consiste à "mettre le système hors ligne pour les utilisateurs normaux" ...
SlySven
Oui, mais cela shutdownprend un peu de temps à exécuter et déconnecte tous les clients ssh tant qu’ils sont là. Comment savoir, par exemple, s'il est sûr de retirer la carte SD?
Tom Auger
40

Ne débranchez pas simplement le cordon, car cela pourrait occasionnellement (peut-être souvent) entraîner une corruption du système de fichiers.

Comme dit Impluss, utilisez shutdown. J'ai récemment rencontré un conseil sur la configuration d'udev pour déclencher l'arrêt ou le redémarrage lorsqu'un périphérique USB spécifique est débranché. Ceci est utile si le système ne répond plus ou a perdu une connexion réseau et que vous ne pouvez plus vous occuper de brancher des éléments cachés (périphérique à interface humaine) comme un clavier.

Il y a une bonne introduction, peut-être légèrement dépassée, mais bien écrite, aux règles d'udev | ici | . L’idée de base est que vous obtenez des informations sur le périphérique vialsusb , par exemple:

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

Le troisième champ intitulé ID correspond au fournisseur et à l'identifiant du modèle, séparés par deux points. En supposant que vous n'avez pas plusieurs appareils identiques branchés, cette combinaison doit être unique.

Vous pouvez obtenir des informations pertinentes plus détaillées via udevadm monitor --udev --property, qui feront rapport au standard jusqu'à ce que vous le détruisiez, par exemple lorsque je débranche le dongle wifi teenie weenie d'en haut, il crache:

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

Notez les champs ID_MODEL et ID_VENDOR. Ce sont ce que vous voulez utiliser dans votre règle udev. Certaines sources en ligne obsolètes ou incorrectes suggèrent d'utiliser des champs ATTR, mais il s'agit de champs ENV pour un événement "remove".

Créez un fichier dans /etc/udev/rules.d. C'est la même quelle que soit la distribution. Le fichier doit se terminer .ruleset tous les fichiers de ce répertoire sont traités lexicographiquement. Je crois que les règles déclarées précédemment ont la priorité. Par conséquent, si vous utilisez 00-my_pi.rulescette option, vous gardez cette option au premier plan (les chiffres sont classés avant les lettres). Ajoutez une ligne comme celle-ci:

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

Attention ==et pas =. Si vous utilisez ce dernier critère, le critère n'a pas de sens. Dans ce cas, vous pourriez vous retrouver avec une règle udev qui correspond à n’importe quel événement!

Assurez-vous que c'est chargé avec udevadm control --reload-rules. Maintenant, lorsque vous retirez le dongle wifi, le pi doit s'arrêter proprement ... laissez-lui une minute pour le faire et vous pourrez alors débrancher l'alimentation (essayez ceci avec un écran attaché la première fois). Vous pouvez également utiliser ceci pour redémarrer - voir man shutdownet, en fait, la page de manuel de toutes les commandes mentionnées ici;)

Boucles d'or
la source
3
Je ne pense pas que c'est ce que demandait le PO. Mais +1 pour l'info.
Vincent P
Soigné! Vous devriez bien sûr pouvoir également déclencher la suppression (ou le branchement) d'un périphérique USB arbitraire
Tobias Kienzler le
C'est un bon début. Obtenir l'arrêt déclenché par un bouton GPIO (un moyen d'obtenir quelque chose comme ça pour un événement ACPI ou HID?) Ou quelque chose qui serait encore plus pratique.
XTL
@XTL: Il y a des démons apci, c'est donc possible (les rapports du noyau via proc, etc.). La même chose est au moins potentiellement vraie pour gpio sur le pi. Les événements HID sont plus contextuels (un exemple de contexte étant un environnement de bureau à interface graphique) et le fait que vous puissiez taper "stop" (== shutdown -h nowsur linux) en atténue peut-être la nécessité;
goldilocks
C’est parfait, le dongle est la seule chose connectée à notre Pi, et nous perdons souvent la connexion. Nous devons donc le déplacer, sans le corrompre.
noio
8

Vous pouvez émettre la commande suivante à l’arrêt:

sudo init 0

Et pour redémarrer:

sudo init 6
Utilisateur enregistré
la source
Cela dépend fortement des niveaux d'exécution étant un concept que le système d'exploitation utilise toujours. Un passage à systemd rend cela moins utilisable de nos jours.
Stephen Michael Kellat
En excluant l’édition d’aujourd’hui, vous avez peut-être remarqué que cette réponse est plutôt ancienne. La question a également plus de deux ans.
Utilisateur enregistré
1
Dans cet usage, il est préférable d'utiliser sudo telinit ## où est un nombre compris entre 0 et 6 - telinit est un lien symbolique vers init qui reconnaît qu'il n'est pas appelé par son nom principal "init" (et qu'il n'a pas de PID de 1!), Il crée donc un canal vers le processus "init" réel et lui dit de modifier le niveau d'exécution actuel en fonction de la nouvelle valeur indiquée en tant qu'argument numérique . telinitest une contraction de "tell init the new runlevel".
SlySven
7

Ma méthode préférée consiste à utiliser sudo poweroff, qui est un alias pour une commande d'arrêt qui supprime également l'utilisation de l'alimentation.

sdenton4
la source
7

Bien que la question ait déjà reçu une réponse adéquate; Ma préférence est différente de ce qui a déjà été répondu.

Comme d’autres l’ont dit, évitez de tirer le courant. Mes commandes préférées (soit en tant que root, soit avecsudo ):

Pour arrêter: halt(pour Wheezy et avant, cette commande éteint également le système; pour Jessie, elle ne s’éteint pas, bien qu’il soit sécuritaire de débrancher la prise une fois terminé) halt -p; shutdown now -hou simplementpoweroff sont nécessaires pour Jessie ...

Redémarrer: reboot

Je préfère ces commandes car elles sont simples, faciles à retenir et évidentes ...

Jeremy Davis
la source
Je ne veux pas me plaindre mais je pense que c'est un peu dur que ma réponse (d'il y a 8 mois) ait été rejetée parce que Debian (c'est-à-dire en amont de Raspbian) a changé le mode de fonctionnement de leurs commandes (en supposant que c'est pour cette raison que j'ai été voté par le bas) . De plus, ma réponse (avant la modification) répondait toujours à l'OP (c.-à-d. Si vous arrêtez le système, vous pouvez débrancher la prise en toute sécurité ...) FWIW J'ai mis à jour la réponse, de sorte qu'il est clair que cela ne fonctionne plus comme un utilisateur pourrait espérons ...
Jeremy Davis
Vous ne devriez pas prendre l’habitude d’utiliser haltou poweroff, comme ce ne sont que des alias shutdown -h nowavec des outils GNU, mais sur d’autres systèmes, vous éteindrez immédiatement votre système, tuant tous vos programmes et éventuellement corrompant votre système de fichiers. Ceci dit, vous pouvez l’utiliser sur un pi framboise avec la plupart des distributions Linux, mais si vous utilisez pi pour l’apprentissage, vous voudrez peut-être le faire "de la bonne façon".
Allo
@allo - Vous pouvez également être correct pour les systèmes d'exploitation Linux hérités et d'autres variantes Unix non Linux comme les systèmes d'exploitation (BSD, par exemple). Mais dans les systèmes d’exploitation Linux plus récents qui utilisent SystemD (c’est-à-dire la plupart des systèmes Linux de nos jours), ce n’est pas le cas. halt, poweroff, rebootEt shutdownsont tous les liens symboliques à systemctl(avec la commande originale a également adopté). Cela déclenche ensuite la cible SystemD appropriée: par exemple poweroff.target. FWIW poweroff.targetdéclenche un appel ACPI pour arrêter le système proprement. Donc, autant que je sache à l’époque actuelle poweroff(ou systemctl poweroff) EST «la bonne façon». :)
Jeremy Davis
Comme dans beaucoup de cas avec Linux, il y a plus d'une façon de le faire. Mais vous devriez considérer si vous ne voulez pas l’apprendre comme cela est décrit dans le standard, suivi également par d’autres systèmes Unix. Il y a peu d'avantages pour vous en tant qu'utilisateur Linux, mais qui sait quand vous allez essayer un autre système à l'avenir? ne comptez pas sur halte et ne comptez pas sur rm pour avoir un --no-preserve-rootdrapeau. Ne comptez pas sur / bin / sh étant / bin / bash (ce n'est même plus vrai pour les systèmes basés sur Debian). Il est souvent utile d'essayer d'utiliser la "bonne" méthode, même si cela fonctionnerait actuellement d'une autre manière.
Allo
1
@allo - Bon point et je pense que c'est vraiment génial pour vous de partager votre connaissance des différents systèmes et je conviens qu'il vaut certainement la peine de noter les différences entre les systèmes et les limitations correspondantes. Bien que je ne sois pas d’accord avec votre suggestion que votre façon de faire est la "bonne" façon. C'est peut-être la méthode "conforme à la posix", mais cela ne fait pas d'une manière "bonne" et d'une autre "mauvaise". Par exemple, utiliser bash (et bashismes) est tout à fait légitime à l’OMI, bien que je convienne que si vous avez besoin de / voulez bash, vous devez l’utiliser explicitement /bin/bash. FYI, ma perspective est très centrée sur Debian ...
Jeremy Davis
4

Pour vous lancer, si vous souhaitez ajouter un peu de matériel, vous pouvez écrire un petit démon pour interroger les broches GPIO et lors de l’affirmation d’une certaine broche, redémarrez (ou éteignez) le Pi.

En outre, toutes les commandes mentionnées ici peuvent être exécutées sur SSH.

Maxthon Chan
la source
3

Je sais que c'est 3 ans après la question initiale. Mais je viens de recevoir mon Raspberry Pi et je ne parviens pas à l'éteindre si j'ai oublié de le connecter à un écran et qu'il ne dispose pas d'une connexion réseau.

J'ai écrit un petit script Python pour l'éteindre automatiquement dans les 60 secondes en insérant une clé USB contenant un fichier nommé "pi_auto_shutdown".

Appelez ce script à partir de rc.local.

J'espère que ça aide.

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
la source
Approche intéressante.
Eric Wilson
1

Je ssh dans ma boîte RPi en utilisant la commande

$ ssh rpi sudo poweroff

rpi est l'alias de l'adresse IP de ma boîte RPi et est défini dans le fichier ~ / .ssh / config .

ismartbuoy
la source