Exécuter un script shell dans le shell actuel avec l’autorisation sudo

Pour exécuter un script shell dans le shell actuel, nous devons utiliser un point . ou une commande source . Mais pourquoi ne fonctionne-t-il pas avec une permission sudo?

J’ai un script avec une autorisation d’exécution appelé setup.sh . Quand j’utilise un point, j’obtiens ceci:

 $ sudo . ./setup.sh sudo: .: command not found 

La commande source génère également une erreur similaire. Est-ce que je manque quelque chose? Que dois-je faire pour exécuter le script avec l’autorisation sudo dans le même shell?

Merci d’avance..

Ce que vous essayez de faire est impossible; votre shell actuel s’exécute sous votre identifiant utilisateur habituel (c’est-à-dire sans root, l’access que sudo vous donnerait), et il n’y a aucun moyen de lui accorder un access root . Ce que sudo fait, c’est créer un nouveau processus * sub * qui s’exécute en tant que root. Le sous-processus pourrait être juste un programme normal (par exemple, sudo cp ... exécute le programme cp dans un processus root) ou il pourrait s’agir d’un sous-shell racine, mais il ne peut pas s’agir du shell actuel.

(En fait, c’est encore plus impossible que cela, car la commande sudo elle-même est exécutée comme un sous-processus du shell actuel – ce qui signifie que dans un sens, il est déjà trop tard pour faire quoi que ce soit dans le shell actuel. il s’exécute.)

Je ne sais pas si cela enfreint les règles mais

 sudo bash script.sh 

semble travailler pour moi.

Je pense que vous êtes confus au sujet de la différence entre le sourcing et l’exécution d’un script.

L’exécution d’un script implique la création d’un nouveau processus et l’exécution du programme. Le programme peut être un script shell ou tout autre type de programme. Comme il s’agit d’un sous-processus, les variables environnementales modifiées dans le programme n’affecteront pas le shell.

La recherche d’un script ne peut être utilisée qu’avec un script bash (si vous utilisez bash). Il tape efficacement les commandes comme si vous les aviez faites. Ceci est utile car il permet à un script de modifier les variables environnementales dans le shell.


Exécuter un script est simple, il vous suffit d’entrer le chemin du script. . est le répertoire en cours. Donc, ./script.sh exécutera le fichier script.sh dans le répertoire en cours. Si la commande est un fichier unique (par exemple, script.sh ), tous les dossiers de la variable PATH seront recherchés pour trouver le script. Notez que le répertoire en cours n’est pas dans PATH, vous ne pouvez donc pas exécuter un fichier script.sh dans le répertoire en cours en exécutant script.sh , vous devez exécuter ./script.sh (à moins que le répertoire en cours ne se trouve dans PATH , par exemple, vous pouvez lancer ls dans le /bin ).

La recherche d’un script n’utilise pas le PATH et recherche simplement le chemin. Notez que la source n’est pas un programme – sinon, il ne serait pas possible de modifier les variables d’environnement dans le shell actuel. C’est en fait une commande intégrée bash. Rechercher /bin et /usr/bin – vous ne trouverez pas de programme source cet endroit. Donc, pour script.sh un fichier script.sh dans le répertoire courant, il vous suffit d’utiliser source script.sh .


Comment sudo interagit-il avec cela? Eh bien, sudo prend un programme et l’exécute en tant que root. Par exemple, sudo ./script.sh exécute script.sh dans un sous-processus mais s’exécute en tant que root.

Que fait pourtant sudo source ./script.sh ? Rappelez-vous que la source n’est pas un programme (plutôt un shell intégré)? Sudo attend un nom de programme, donc il recherche un programme nommé source . Il n’en trouve pas, et échoue donc. Il n’est pas possible de générer un fichier s’exécutant en tant que root, sans créer de nouveau sous-processus, car vous ne pouvez pas modifier le programme d’exécution d’un programme (dans ce cas, bash) après son démarrage.

Je ne suis pas sûr de ce que vous vouliez réellement, mais j’espère que cela vous aidera.


Voici un exemple concret. Rendez le fichier script.sh dans votre répertoire actuel avec le contenu:

 #!/bin/bash export NEW_VAR="hello" whoami echo "Some text" 

Rendez-le exécutable avec chmod +x script.sh .

Maintenant, observez ce qui se passe avec bash:

 > ./script.sh david Some text > echo $NEW_VAR > sudo ./script.sh root Some text > echo $NEW_VAR > source script.sh david Some text > echo $NEW_VAR hello > sudo source script.sh sudo: source: command not found 

Fondamentalement, sudo attend, un exécutable (commande) à suivre et vous fournissez avec un .

D’où l’erreur.

Essayez de cette façon $ sudo setup.sh


Si vous voulez vraiment exécuter un script shell dans le shell actuel avec l’autorisation de sudo, vous pouvez utiliser exec pour …

remplacer le shell par un programme donné (en l’exécutant, pas en tant que nouveau processus)

J’insiste pour remplacer “execute” par “call” car le premier a un sens qui inclut la création d’un nouveau processus et d’un nouvel identifiant, ce dernier étant ambigu et laissant place à la créativité, dont je suis plein.

Considérez ce cas de test et regardez attentivement le pid 1337

 # Don't worry, the content of this script is cat'ed below $ ./test.sh -o foo -p bar User ubuntu is running... PID TT USER COMMAND 775 pts/1 ubuntu -bash 1408 pts/1 ubuntu \_ bash ./test.sh -o foo -p bar 1411 pts/1 ubuntu \_ ps -t /dev/pts/1 -fo pid,tty,user,args User root is running... PID TT USER COMMAND 775 pts/1 ubuntu -bash 1337 pts/1 root \_ sudo ./test.sh -o foo -p bar 1412 pts/1 root \_ bash ./test.sh -o foo -p bar 1415 pts/1 root \_ ps -t /dev/pts/1 -fo pid,tty,user,args Take 'exec' out of the command and this script would get cat-ed twice. (Try it.) #!/usr/bin/env bash echo; echo "User $(whoami) is running..." ps -t $(tty) -fo pid,tty,user,args if [[ $EUID > 0 ]]; then # exec replaces the current process effectively ending execution so no exit is needed. exec sudo "$0" "$@" fi echo; echo "Take 'exec' out of the command and this script would get cat-ed twice. (Try it.)"; echo cat $0 

Voici un autre test utilisant sudo -s

 $ ps -fo pid,tty,user,args; ./test2.sh PID TT USER COMMAND 10775 pts/1 ubuntu -bash 11496 pts/1 ubuntu \_ ps -fo pid,tty,user,args User ubuntu is running... PID TT USER COMMAND 10775 pts/1 ubuntu -bash 11497 pts/1 ubuntu \_ bash ./test2.sh 11500 pts/1 ubuntu \_ ps -fo pid,tty,user,args User root is running... PID TT USER COMMAND 11497 pts/1 root sudo -s 11501 pts/1 root \_ /bin/bash 11503 pts/1 root \_ ps -fo pid,tty,user,args $ cat test2.src echo; echo "User $(whoami) is running..." ps -fo pid,tty,user,args $ cat test2.sh #!/usr/bin/env bash source test2.src exec sudo -s < test2.src 

Et un test plus simple utilisant sudo -s

 $ ./exec.sh bash's PID:25194 user ID:7809 systemd(1)───bash(23064)───bash(25194)───pstree(25196) Finally... bash's PID:25199 user ID:0 systemd(1)───bash(23064)───sudo(25194)───bash(25199)───pstree(25201) $ cat exec.sh #!/usr/bin/env bash pid=$$ id=$(id -u) echo "bash's PID:$pid user ID:$id" pstree -ps $pid # the quoted EOF is important to prevent shell expansion of the $... exec sudo -s < 

La méthode la plus simple est de taper:

  • sudo /bin/sh example.sh