Bash, exécute la commande après avoir appelé un nouveau shell

12

J'essaie de faire un script comme celui-ci:

#!/bin/bash
sudo -s
something...

Lorsque je l'exécute, j'obtiens un nouveau shell mais somethingn'est exécuté que lorsque je quitte le shell créé par sudo -s, pas à l'intérieur.

De l'aide?

Matteo
la source

Réponses:

7

Le problème est sudo -ssans aucun argument ouvrira un shell interactif pour root.

Si vous souhaitez simplement exécuter une seule commande à l'aide de sudo -s, vous pouvez simplement faire:

sudo -s command

Par exemple :

$ sudo -s whoami
root

Ou vous pouvez utiliser ici des chaînes:

$ sudo -s <<<'whoami'
root

Si vous avez plusieurs commandes, vous pouvez utiliser ici doc:

$ sudo -s <<'EOF'
> whoami
> hostname
> EOF
root
something--
heemayl
la source
1
Il n'est pas bon de l'utiliser sudo -sau cas où l' rootutilisateur aurait eu l'idée (plutôt mauvaise) de changer de shell. Ce devrait vraiment être sudo shce qui indique explicitement quel shell doit être utilisé.
Michael Le Barbier Grünewald
7

Une autre façon serait de passer une ou des commandes bash complètes à sudo:

#!/bin/bash
sudo bash -c 'command1; command2; command3;'

Cependant, une meilleure façon serait de lancer le script avec à la sudoplace. Ce n'est pas une très bonne idée d'avoir sudoà l'intérieur du script. Il vaut bien mieux exécuter l'intégralité du script avec les privilèges root ( sudo script.sh). Si nécessaire, vous pouvez utiliser sudopour supprimer des privilèges pour des commandes spécifiques. Par exemple:

#!/usr/bin/env bash
whoami
echo $HOME
sudo -u terdon whoami  ## drop privileges for specific command.

L'exécution du script ci-dessus renvoie:

$ sudo ~/scripts/a.sh
root
/root
terdon
terdon
la source
3

Le shell Bourne a un -cdrapeau que vous pouvez utiliser pour passer un script arbitraire au shell, afin que vous puissiez écrire quelque chose comme

sudo sh -c 'something'

Ceci n'est cependant utile que pour les commandes les plus simples, car il est très lourd de citer correctement le script et l'inconvénient est encore plus élevé si vous envoyez la commande à un serveur distant via ssh car le script d'argument sera analysé deux fois, une fois sur le côté envoyer le script et une fois sur le côté exécutant le script.

S'il somethings'agit d'un script complexe ou doit être passé sur une ligne ssh , il est courant d'écrire une fonction prepare_something_scriptdont le travail consiste à écrire le script «quelque chose» sur stdout . Dans sa forme la plus simple, cette fonction peut utiliser un document ici pour générer sa sortie:

prepare_something_script()
{
  cat <<EOF
something
EOF
}

Le script produit par prepare_something_scriptpeut ensuite être exécuté localement avec les privilèges accordés par sudo comme suit:

prepare_something_script | sudo sh

Dans le scénario où le script doit être exécuté à distance avec les privilèges accordés par sudo, il est habituel de coder le script en base 64 pour éviter de rediriger l'entrée standard de ssh , comme ceci:

something64=$(prepare_something_script | base64)
ssh usesr@remote-host "echo ${something64} | base64 --decode | sudo sh"

Si vous utilisez ce code dans une fonction, n'oubliez pas de marquer la variable something64 comme locale . Certaines implémentations de base64 offrent un -dindicateur à décoder, qui est moins bien pris en charge que la --decodevariante détaillée . Certaines implémentations nécessitent d'ajouter un -w 0à la commande de codage pour éviter les sauts de ligne parasites.

Michael Le Barbier Grünewald
la source
0

Vous devez ajouter la commande avant sudo -s, au lieu de dans la ligne suivante.

sudo -s something...
soumen
la source