Tengo un sistema en el que solo puedo iniciar sesión con mi nombre de usuario (myuser), pero necesito ejecutar comandos como otro usuario (scriptuser). Hasta ahora, se me ocurrió lo siguiente para ejecutar los comandos que necesito:
ssh -tq myuser@hostname "sudo -u scriptuser bash -c \"ls -al\""
Sin embargo, si trato de ejecutar un comando más complejo, como [[ -d "/tmp/Some directory" ]] && rm -rf "/tmp/Some directory"
rápidamente me meto en problemas con las citas. No estoy seguro de cómo podría pasar este comando complejo de ejemplo bash -c
, cuando \"
ya delimita los límites del comando que estoy pasando (por lo que no sé cómo citar / tmp / Some directorio, que incluye espacios).
¿Existe una solución general que me permita pasar algún comando sin importar cuán compleja / loca sea la cita, o es esta una especie de limitación que he alcanzado? ¿Hay otras soluciones posibles y quizás más legibles?
Respuestas:
Un truco que uso a veces es usar base64 para codificar los comandos y canalizarlo para bash en el otro sitio:
Esto codificará el script, con cualquier coma, barra diagonal inversa, comillas y variables dentro de una cadena segura, y lo enviará al otro servidor. (
-w0
se requiere para deshabilitar el ajuste de línea, que ocurre en la columna 76 de forma predeterminada). Por otro lado,$(base64 -d)
decodificará el script y lo alimentará a bash para que se ejecute.Nunca tuve ningún problema con eso, no importa cuán complejo fuera el script. Resuelve el problema de escapar, porque no necesita escapar de nada. No crea un archivo en el host remoto, y puede ejecutar scripts muy complicados con facilidad.
fuente
ssh user@remotehost "echo `base64 -w0 script.sh` | base64 -d | sudo bash"
base64 script | ssh remotehost 'base64 -d | sudo bash'
sería suficiente :)Ver la
-tt
opción? Lee elssh(1)
manual.Una cosa que hago a menudo es usar vim y usar el
:!cat % | ssh -tt somemachine
truco.fuente
:!cat % | (command)
se puede hacer como:w !(command)
o:!(command) < %
.ssh -tt
hace que mi ssh para no termina después de ciertos comandos se ejecutan (añadiendoexit
al final no ayuda)Creo que la solución más fácil radica en una modificación del comentario de @ thanasisk.
Cree un script
scp
para la máquina y luego ejecútelo.Tener el script en
rm
sí mismo al comienzo. El shell ha abierto el archivo, por lo que se ha cargado y luego se puede eliminar sin problemas.Al hacer las cosas en este orden (
rm
primero, otras cosas en segundo lugar), incluso se eliminará cuando falle en algún momento.fuente
Puede usar el
%q
especificador de formato conprintf
para encargarse del escape de variables por usted:printf -v
escribe el resultado en una variable (en este caso,$cmd_str
). Creo que esta es la forma más sencilla de hacerlo. No es necesario transferir ningún archivo o codificar la cadena de comandos (por mucho que me guste el truco).Aquí hay un ejemplo más complejo que muestra que funciona para cosas como corchetes y símbolos también:
No lo he probado
sudo
pero debería ser tan simple como:Si lo desea, puede omitir un paso y evitar crear la variable intermedia:
O incluso simplemente evite crear una variable por completo:
fuente
Aquí está la forma "correcta" (sintáctica) de ejecutar algo como esto en bash:
Para obtener una explicación detallada de cómo funciona esto, consulte https://stackoverflow.com/a/21761956/111948
fuente
¿Sabe que puede usarlo
sudo
para darle un shell donde puede ejecutar comandos como el usuario elegido?fuente
Puede definir el script en su máquina local y luego
cat
y canalizarlo a la máquina remota:fuente
sudo -u scriptuser
? ¿Se podría usar heredoc teniendo en cuenta que necesito tener variables en el script que estaría canalizando a la máquina?echo "sudo `cat fileForSsh.txt`" | ssh ...
pero sigo haciéndolosudo: sorry, you must have a tty to run sudo
./etc/sudoers
cambiar el archivossh -tq user@host "sudo bash -s" < test.sh
Simple y fácil.
fuente
Si usa un shell Bash lo suficientemente moderno, puede poner sus comandos en una función e imprimir esa función como una cadena usando
export -p -f function_name
. El resultado de esa cadena puede contener comandos arbitrarios que no necesariamente tienen que ejecutarse como root.Un ejemplo usando tuberías de mi respuesta en Unix.SE :
Un ejemplo que recupera guarda el archivo para el usuario de inicio de sesión e instala un programa como root:
Si desea ejecutar todo el comando usando
sudo
, puede usar esto:fuente
Aquí está mi (mal probada) solución horrible para esto:
No puedes hacer:
El siguiente paso es crear un
betterssh
script que ya haga esto:fuente
Para aquellos de ustedes que necesitan pasar parámetros al script, debe ser el siguiente:
fuente
Primero, cree un script local y luego ejecútelo de forma remota con el siguiente comando:
fuente