Passando vários argumentos com espaços em branco através de um script para ssh

3

Eu quero remover vários arquivos do servidor remoto. Eu tenho todos os arquivos em uma matriz em um script e chamo outro script que irá remover arquivos.

Deixe a saída de "$ {b [@]}":

/mnt/DataBK/BackupDropwizardLogs_2015-12-17_04-00-01.tar.gz
/mnt/DataBK/BackupDropwizardLogs_2015-12-17_04-30-01.tar.gz
/mnt/DataBK/BackupDropwizardLogs_2015-12-17_05-00-02.tar.gz
O script

que removerá o arquivo é:

#!/bin/bash  
file="$1"  
sshpass -p 'password' ssh [email protected] "echo "$file""

ao chamar bash /tmp/1.sh "'${b[@]}'" , recebo um erro

bash: -c: line 0: unexpected EOF while looking for matching '''  
bash: -c: line 1: syntax error: unexpected end of file

E enquanto chama bash /tmp/1.sh "${b[@]}" , ele atribui apenas um arquivo à variável de arquivo.
/mnt/DataBK/BackupDropwizardLogs_2015-12-17_04-00-01.tar.gz

Alguém por favor pode me dizer como atribuir um valor de matriz contendo espaços para a variável de arquivo no script acima.

UPDATE :: Funcionou definindo declare -a file=("$@") em outro script. Mas e se quiser enviar mais parâmetros em vez de apenas array?

    
por AVJ 18.12.2015 / 10:11

3 respostas

4

sshpass -p 'password' ssh [email protected] "some_cmd $(printf '%q ' "$@")"
sshpass -p 'password' ssh [email protected] "f() for i; do some_cmd "$i"; done; f $(printf '%q ' some_cmd "$@")"

De acordo com sshpass manpage,

sshpass [-ffilename|-dnum|-ppassword|-e] [options] command arguments

Portanto, você deve ser capaz de passar todo o "$@" para o comando ssh, como:

sshpass -p 'password' ssh [email protected] printf '%q\n' "$@"

Como seu comando de destino pode não ser capaz de lidar com esse processamento de argumentos, podemos alterar isso:

sshpass -p 'password' 'k(){ for i; do echo $i; done; }; k' "$@"

Vamos testar com alguns espaços em branco ...

set -- 'foo bar' $'lorem\nipsum\td'
# paste that two lines.. Since I don't have sshpass installed, just using ssh.

ssh aparentemente estragou tudo. Vamos encaixar alguns shell falsificados e ver o que aconteceu ..

#!/bin/bash
# /bin/mysh
# someone:x:1000:1000:FOo,,Bar,:/home/foo:/bin/mysh
printf '%q ' bash "$@"; echo;
exec bash -xv --norc "$@";

Hmm. Vamos tentar.

bash -c $'printf %q\n foo bar lorem\nipsum\td'
printf %q\n foo bar lorem
+ printf %qn foo bar lorem
ipsum   d
+ ipsum d
bash: line 1: ipsum: command not found

Então, aparentemente ssh simplesmente concatenou essas coisas com espaços. Não é legal.

Vamos pré-escapar do nosso lado com printf '%q ' , e você obterá o TL; DR resposta.  Agora você pode descobrir sobre o EOF e o -c também.

Nota: Não tenho certeza se o ssh faz a coisa -c diferentemente entre as versões. Você pode precisar tentar isso sozinho. Pelo menos isso é verdade para o OpenSSH 7.1 ( ssh.c: 955-969 ).

    
por 18.12.2015 / 18:13
1

Para responder ao título da sua pergunta:

Passing multiple of arguments with whitespaces through [a script] to ssh

Eu proponho escapar das citações:

  ssh  [email protected]  echo "\"arg   1\"    \"arg   2\""

... enviará "arg 1" como primeiro argumento e "arg 2" como segundo argumento, neste caso para o comando echo na máquina remota, produzindo assim a saída:

  arg   1 arg   2

NOTA: O comando echo produz os argumentos individuais com um único espaço em branco entre eles. No entanto, os (múltiplos) espaços em branco, que estão contidos nos argumentos individuais, são preservados. Tome isso como uma prova de que os espaços em branco são, na verdade, parte dos argumentos, o que foi solicitado no título da questão.

    
por 12.03.2018 / 12:31
0

O primeiro script deve ser algo como:

#!/bin/bash
password="mypassword"
filelist=("$@")

for file in "${filelist[@]}";
do 
    sshpass -p '$password' ssh [email protected] "echo \"$file\""
done

O loop for apresentará cada arquivo ao comando.

Quanto ao erro:

bash: -c: line 0: unexpected EOF while looking for matching '''

Suponho que tenha feito com o método pelo qual você chama o script. Você deveria estar chamando assim (uma linha):

$ ./1.sh "${b[@]}"
    
por 18.12.2015 / 10:31