¿Cómo puedo ejecutar un script local en una máquina remota e incluir argumentos?


116

He escrito un script que funciona bien cuando se ejecuta localmente:

./sysMole -time Aug 18 18

Los argumentos "-time" , "Aug" , "18" y "18" se pasan con éxito al script.

Ahora, este script está diseñado para ejecutarse en una máquina remota, pero desde un directorio local en la máquina local. Ejemplo:

ssh root@remoteServer "bash -s" < /var/www/html/ops1/sysMole

Eso también funciona bien. Pero el problema surge cuando trato de incluir esos argumentos antes mencionados (-tiempo 18-18 de agosto) , por ejemplo:

ssh root@remoteServer "bash -s" < /var/www/html/ops1/sysMole -time Aug 18 18

Después de ejecutar ese script me sale el siguiente error:

bash: cannot set terminal process group (-1): Invalid argument
bash: no job control in this shell

Por favor, dime qué estoy haciendo mal, esto es muy frustrante.


1
"Bash -s" es una de las formas en que puede ejecutar un script desde una entrada estándar (es decir, un archivo).
AllenD

Respuestas:


160

Estuviste bastante cerca con tu ejemplo. Funciona bien cuando lo usa con argumentos como estos.

Script de muestra:

$ more ex.bash 
#!/bin/bash

echo $1 $2

Ejemplo que funciona:

$ ssh serverA "bash -s" < ./ex.bash "hi" "bye"
hi bye

Pero falla para este tipo de argumentos:

$ ssh serverA "bash -s" < ./ex.bash "--time" "bye"
bash: --: invalid option
...

¿Que esta pasando?

El problema con el que te encuentras es que el argumento, -timeo --timeen mi ejemplo, se está interpretando como un cambio a bash -s. Puede apaciguarlo bashal terminar de tomar cualquiera de los argumentos restantes de la línea de comando para sí mismo utilizando el --argumento.

Me gusta esto:

$ ssh root@remoteServer "bash -s" -- < /var/www/html/ops1/sysMole -time Aug 18 18

Ejemplos

# 1:

$ ssh serverA "bash -s" -- < ./ex.bash "-time" "bye"
-time bye

# 2:

$ ssh serverA "bash -s" -- < ./ex.bash "--time" "bye"
--time bye

# 3:

$ ssh serverA "bash -s" -- < ./ex.bash --time "bye"
--time bye

# 4:

$ ssh  < ./ex.bash serverA "bash -s -- --time bye"
--time bye

NOTA: Solo para dejar en claro que donde sea que aparezca la redirección en la línea de comando no hay diferencia, porque de sshtodos modos llama a un shell remoto con la concatenación de sus argumentos, las citas no hacen mucha diferencia, excepto cuando necesita hacerlo en el shell remoto como en el ejemplo # 4:

$ ssh  < ./ex.bash serverA "bash -s -- '<--time bye>' '<end>'"
<--time bye> <end>

44
eres un genio! ¿Qué tengo que hacer para llegar a tu nivel? Tengo mucho trabajo cortado. Muchas gracias.
AllenD

14
@AllenD: solo sigue haciendo preguntas e intenta participar en el sitio tanto como puedas. Siempre trato de aprender algo nuevo cada día. Antes de su pregunta, tampoco sabía cómo hacer esto. 8-). Gracias por tu pregunta!
slm

55
tenga en cuenta que la redirección puede aparecer en cualquier punto del comando: por ejemplo bash -s -- --time bye < ./ex.basho incluso < ./ex.bash bash -s -- --time bye. Esto se debe a que el shell primero toma la instrucción de redireccionamiento (independientemente de dónde esté en el comando), luego configura la redirección, luego ejecuta el resto de la línea de comando con la redirección en su lugar.
lesmana

@sim Estoy tratando de hacer exactamente lo mismo, pero desde un script, no desde la línea de comandos. ¿Alguna idea de cómo hacer esto? Por alguna razón, encerrar su respuesta exacta entre comillas no funciona en absoluto. En su lugar, ejecuta el script especificado localmente, y la salida se envía como un comando al bash sobre ssh
krb686

@ krb686 - Lo pediría como una nueva Q.
slm

5

Sobre el manejo de argumentos arbitrarios

Si realmente solo usa una sola cadena, es decir -time Aug 18 18, entonces simplemente puede codificarlo, y las respuestas existentes le indican cómo hacerlo adecuadamente. Por otro lado, si necesita pasar argumentos desconocidos (como un mensaje que se mostrará en el otro sistema o el nombre de un archivo creado donde los usuarios finales podrían controlar su nombre), entonces se necesita más cuidado.


Con basho kshcomo/bin/sh

Si su control remoto /bin/shes proporcionado por bash o ksh, puede hacer lo siguiente de manera segura con una lista de argumentos no confiables, de modo que incluso los nombres maliciosos (como $(rm -rf $HOME).txt) se puedan pasar como argumentos de manera segura:

runRemote() {
  local args script

  script=$1; shift

  # generate eval-safe quoted version of current argument list
  printf -v args '%q ' "$@"

  # pass that through on the command line to bash -s
  # note that $args is parsed remotely by /bin/sh, not by bash!
  ssh user@remote-addr "bash -s -- $args" < "$script"
}

Con cualquier POSIX-obediente /bin/sh

Para estar a salvo de datos de argumentos suficientemente maliciosos (tratando de aprovechar la cita no compatible con POSIX utilizada por printf %qin bash cuando hay caracteres no imprimibles en la cadena que se escapa) incluso con un /bin/shBASIX-POSIX (como dasho ash), se pone un poco más interesante:

runRemote() {
  local script=$1; shift
  local args
  printf -v args '%q ' "$@"
  ssh user@remote-addr "bash -s" <<EOF

  # pass quoted arguments through for parsing by remote bash
  set -- $args

  # substitute literal script text into heredoc
  $(< "$script")

EOF
}

Uso (para cualquiera de los anteriores)

Las funciones dadas anteriormente se pueden invocar como:

# if your time should be three arguments
runRemote /var/www/html/ops1/sysMole -time Aug 18 18

...o...

# if your time should be one string
runRemote /var/www/html/ops1/sysMole -time "Aug 18 18"

-3

decir aa es un archivo local que contiene ls

$ssh servername "cat | bash" < a.a

cambie 127.0.0.1 a cualquiera que sea su ip remota

estos dos dan un mensaje sobre la asignación de pseudo tty pero funcionan.

$ cat a.a | ssh 127.0.0.1

$ ssh 127.0.0.1 <a.a

O

$ cat a.a | ssh 127.0.0.1 bash or

$ ssh 127.0.0.1 bash < a.a


2
Me cuesta ver hasta qué punto esto responde a la pregunta.
ChrisWue

La calidad y el formato son dudosos. Tampoco veo ninguna información útil nueva que no esté presente en la respuesta aceptada.
Julie Pelletier

@JuliePelletier Di algunos ejemplos de 'gatos' que no figuran en la respuesta aceptada. Es bueno conocer formas alternativas de hacer las cosas.
barlop

Eso no es algo bueno; Tus gatos son inútiles.
Scott

2
Oh Dios mío. Dejé el enlace a Uso inútil del gato porque asumí que todos al menos ya habían escuchado la frase; aparentemente esa fue una mala suposición de mi parte.
Scott
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.