web-dev-qa-db-fra.com

Pourquoi "Sudo su" dans un script Shell n'exécute-t-il pas le reste du script en tant que root?

Un exemple de script peut être comme ci-dessous:

#!/bin/bash
Sudo su
ls /root

Lors de l'utilisation de ./test.sh en tant qu'utilisateur normal, exécutez plutôt ls en tant que super utilisateur et quittez, il passe en root; et quand je me déconnecte, il exécute ls /root en tant qu'utilisateur normal.

Quelqu'un peut-il me parler du mécanisme à ce sujet?

37
Hongxu Chen

Les commandes d'un script s'exécutent une par une, indépendamment. Le script lui-même en tant que parent de toutes les commandes du script, est un autre processus indépendant et la commande su ne le change pas et ne peut pas le transformer en root: la commande su crée un nouveau processus avec les privilèges root.

Une fois cette commande su terminée, le processus parent, toujours en cours d'exécution sous le même utilisateur, exécutera le reste du script.

Ce que vous voulez faire, c'est écrire un script wrapper. Les commandes privilégiées vont dans le script principal, par exemple ~/main.sh

#!/bin/sh
ls /root

Le script wrapper appelle le script principal avec des autorisations root, comme ceci

#!/bin/sh
su -c ~/main.sh root

Pour lancer ce processus, vous exécutez l'encapsuleur, qui à son tour lance le script principal après avoir basculé l'utilisateur vers l'utilisateur root.

Cette technique de wrapper peut être utilisée pour transformer le script en wrapper autour de lui. Fondamentalement, vérifiez s'il fonctionne en tant que root, sinon, utilisez "su" pour se relancer.

$ 0 est un moyen pratique de faire en sorte qu'un script se réfère à lui-même, et la commande whoami peut nous dire qui nous sommes (sommes-nous root?)

Ainsi, le script principal avec wrapper intégré devient

#!/bin/sh
[ `whoami` = root ] || exec su -c $0 root
ls /root

Notez l'utilisation d'exec. Cela signifie "remplacer ce programme par", ce qui termine effectivement son exécution et démarre le nouveau programme, lancé par su, avec root, pour s'exécuter à partir du haut. L'instance de remplacement est "root" donc elle n'exécute pas le côté droit de ||

50
Johan

Utilisez ce qui suit dans le script.

Sudo su <<HERE
ls /root
HERE

Le code entre le bloc ICI sera exécuté en tant que root.

20
Ankit

Sans autres arguments, su exécutera le shell de connexion pour root. C'est ce que fait réellement la première ligne de votre script. Lorsque vous quittez, le shell de connexion se ferme, su revient et votre script continue son exécution, c'est-à-dire avec la deuxième ligne: ls /root. Je pense que vous pouvez simplement Sudo ls /root pour faire ce que vous voulez.

6
Bananguin

Une fois que vous lancez Sudo su Un nouveau processus avec la userid (euid=EUID) effective du super utilisateur forké, nous avons donc un nouveau bash fonctionnant avec un identifiant de processus différent (pid=PID) Associé au même terminal (tname=TTY).

Explication

Supposons qu'après avoir tiré ps -A | grep bash, Vous avez 21460 pts/2 00:00:00 bash En sortie. Maintenant, lorsque vous exécutez ./test.sh, Les deux commandes Sudo su Et ls /root Seront mises en file d'attente dans PID 21460. Après l'exécution lorsque vous avez root en tant qu'utilisateur actif, appuyez à nouveau sur ps -A | grep bash, Vous remarquerez qu'un nouveau bash s'exécute sur PID say, 21570. Quitter root bash Tuera le bash nouvellement bifurqué revenant à user's bash Et exécutera donc la commande spoulée ls /root Avant de relâcher l'invite.

1
sundeep