Bash, ejecuta el comando después de invocar un nuevo shell

12

Estoy tratando de hacer un script como este:

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

Cuando lo ejecuto, obtengo un nuevo shell pero somethingse ejecuta solo cuando salgo del shell creado por sudo -s, no dentro de él.

¿Alguna ayuda?

Matteo
fuente

Respuestas:

7

El problema es que sudo -ssin ningún argumento se abrirá un shell interactivo para root.

Si solo quieres ejecutar un solo comando usando sudo -s, puedes hacer lo siguiente:

sudo -s command

Por ejemplo :

$ sudo -s whoami
root

O puede usar aquí cadenas:

$ sudo -s <<<'whoami'
root

Si tiene varios comandos, puede usar aquí doc:

$ sudo -s <<'EOF'
> whoami
> hostname
> EOF
root
something--
heemayl
fuente
1
No es bueno usarlo sudo -ssolo en caso de que el rootusuario tenga la idea (bastante pobre) de cambiar su shell. Esto debería ser realmente lo sudo shque establece explícitamente qué shell se va a utilizar.
Michael Le Barbier Grünewald
7

Otra forma sería pasar un comando (s) completo de bash a sudo:

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

Sin embargo, una mejor manera sería iniciar el script con sudo. No es una muy buena idea tener sudodentro del guión. Mucho mejor ejecutar todo el script con privilegios de root ( sudo script.sh). Si es necesario, puede usar sudopara soltar privilegios para comandos específicos. Por ejemplo:

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

Ejecutar el script anterior devuelve:

$ sudo ~/scripts/a.sh
root
/root
terdon
terdon
fuente
3

El shell Bourne tiene una -cbandera que puede usar para pasar un script arbitrario al shell, para que pueda escribir algo como

sudo sh -c 'something'

Sin embargo, esto solo es útil para los comandos más simples, porque es muy engorroso citar el script correctamente y el inconveniente es aún mayor si envía el comando a un servidor remoto a través de ssh porque el script de argumento se analizará dos veces, una vez al lado enviando el script y una vez al lado ejecutando el script.

Si somethinges un script complejo o necesita ser pasado por una línea ssh , es una práctica común escribir una función prepare_something_scriptcuyo trabajo es escribir el script 'algo' en stdout . En su forma más simple, esta función puede usar un documento aquí para generar su salida:

prepare_something_script()
{
  cat <<EOF
something
EOF
}

El script producido por prepare_something_scriptpuede ejecutarse localmente con los privilegios otorgados por sudo de la siguiente manera:

prepare_something_script | sudo sh

En el escenario donde el script debe ejecutarse de forma remota con los privilegios otorgados por sudo , es habitual codificar el script en la base 64 para evitar redirigir la entrada estándar de ssh , de esta manera:

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

Si usa ese código en una función, no olvide marcar la variable something64 como local . Algunas implementaciones de base64 ofrecen un -dindicador para decodificar, que es menos compatible que la --decodevariante detallada . Algunas implementaciones requieren agregar un -w 0comando de codificación para evitar saltos de línea espurios.

Michael Le Barbier Grünewald
fuente
0

Debe agregar el comando antes de sudo -s, en lugar de en la siguiente línea.

sudo -s something...
soumen
fuente