Como posso executar o script local na máquina remota e incluir argumentos?

116

Eu escrevi um script que funciona bem quando executado localmente:

./sysMole -time Aug 18 18

Os argumentos "-time" , "Aug" , "18" e "18" são transmitidos com êxito para o script.

Agora, esse script foi projetado para ser executado em uma máquina remota, mas a partir de um diretório local na máquina local. Exemplo:

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

Isso também funciona bem. Mas o problema surge quando tento incluir os argumentos acima mencionados (em 18 de agosto de 18) , por exemplo:

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

Depois de executar esse script, recebo o seguinte erro:

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

Por favor, diga-me o que estou fazendo de errado, isso é muito frustrante.

AllenD
fonte
1
"Bash -s" é uma das maneiras de executar um script a partir da entrada padrão (ou seja, um arquivo).
precisa saber é o seguinte

Respostas:

160

Você estava bem próximo do seu exemplo. Funciona muito bem quando você o usa com argumentos como esses.

Exemplo de script:

$ more ex.bash 
#!/bin/bash

echo $1 $2

Exemplo que funciona:

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

Mas falha nesses tipos de argumentos:

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

O que está acontecendo?

O problema que você está enfrentando é que o argumento, -timeou --timeno meu exemplo, está sendo interpretado como uma opção para bash -s. Você pode pacificar bashencerrando-o de usar qualquer um dos argumentos restantes da linha de comando usando o --argumento

Como isso:

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

Exemplos

# 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: Apenas para deixar claro que onde quer que o redirecionamento apareça na linha de comando não faça diferença, porque sshchama um shell remoto com a concatenação de seus argumentos de qualquer maneira, a citação não faz muita diferença, exceto quando você precisa citar no shell remoto como no exemplo 4:

$ ssh  < ./ex.bash serverA "bash -s -- '<--time bye>' '<end>'"
<--time bye> <end>
slm
fonte
4
você é um gênio! O que tenho que fazer para chegar ao seu nível? Eu tenho muito trabalho cortado. Muito obrigado.
precisa saber é o seguinte
14
@ AllenD - continue fazendo perguntas e tente participar do site o máximo que puder. Eu sempre tento aprender algo novo a cada dia. Antes da sua pergunta, eu também não sabia como fazer isso. 8-). Obrigado pela sua pergunta!
slm
5
observe que o redirecionamento pode aparecer em qualquer ponto do comando: por exemplo bash -s -- --time bye < ./ex.bashou mesmo < ./ex.bash bash -s -- --time bye. isso ocorre porque o shell primeiro pega a instrução de redirecionamento (independentemente de onde esteja no comando), depois configura o redirecionamento e depois executa o restante da linha de comando com o redirecionamento no lugar.
Lesmana
@ sim Estou tentando fazer exatamente a mesma coisa, mas de dentro de um script, não da linha de comando. Alguma idéia de como fazer isso? Por alguma razão, incluir sua resposta exata nos backticks não funciona de todo. -Lo em vez executa o script especificado localmente, ea saída é enviado como um comando para a festa sobre ssh
krb686
@ krb686 - Eu pediria como um novo Q.
slm
5

Como lidar com argumentos arbitrários

Se você estiver realmente usando apenas uma única string, por exemplo. -time Aug 18 18, você pode simplesmente codificá-lo, e as respostas existentes mostram como fazer isso adequadamente. Por outro lado, se você precisar passar argumentos desconhecidos (como uma mensagem a ser exibida no outro sistema ou o nome de um arquivo criado onde os usuários finais poderiam controlar seu nome), serão necessários mais cuidados.


Com bashou kshcomo/bin/sh

Se o seu controle remoto /bin/shfor fornecido por bash ou ksh, você poderá fazer o seguinte com segurança com uma lista de argumentos não confiáveis, de modo que até nomes maliciosos (como $(rm -rf $HOME).txt) possam ser transmitidos como argumentos com segurança:

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"
}

Com qualquer compatível com POSIX /bin/sh

Para estar seguro contra dados de argumento suficientemente mal-intencionados (tentando tirar proveito da citação não compatível com POSIX usada por printf %qno bash quando caracteres não imprimíveis estão presentes na cadeia que está sendo escapada) mesmo com um /bin/shque seja POSIX de linha de base (como dashou ash), ele fica um pouco mais interessante:

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 qualquer um dos itens acima)

As funções fornecidas acima podem ser chamadas como:

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

...ou...

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

diga aa é um arquivo local que contém ls

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

mude 127.0.0.1 para o seu ip remoto

esses dois transmitem uma mensagem sobre alocação de pseudo-tty mas eles funcionam.

$ cat a.a | ssh 127.0.0.1

$ ssh 127.0.0.1 <a.a

Ou

$ cat a.a | ssh 127.0.0.1 bash or

$ ssh 127.0.0.1 bash < a.a

barlop
fonte
2
Estou lutando para ver até que ponto isso responde à pergunta.
ChrisWue
A qualidade e a formatação são duvidosas. Também não vejo nenhuma informação útil nova que não esteja presente na resposta aceita.
Julie Pelletier
@JuliePelletier Dei alguns exemplos de 'gatos' que não estão na resposta aceita. É bom conhecer maneiras alternativas de fazer as coisas.
barlop 8/09/16
Isso não é uma coisa boa; seus gatos são inúteis.
Scott
2
Ó meu Deus. Deixei de fora o link para o uso inútil de gato, porque supus que todo mundo já tinha ouvido falar dessa frase; aparentemente essa foi uma suposição ruim da minha parte.
Scott