Como escapar aspas no shell dentro do uso de ssh e sudo?

1

Em uma palavra:

pergunta e exemplo podem testar localmente:

sh -c "echo 'how to print single quote here'"

detalhes:

Eu tenho uma configuração assim:

upload_server = ('192.168.1.1', 10051)

agora eu preciso de um script de shell para substituir a configuração do servidor. Localmente eu posso fazer isso com sed:

sed -E 's/(    upload_server = ).*/\1('\"'$a'\"', 10051)/g' config.py

mas há uma quantidade enorme de máquinas que precisam alterar a configuração.

um plano adequado é usar ssh com for..in:

for i in 'cat hosts'; do ssh $i "cmd"; done

mas para alterar a configuração também precisa de um sudo , parece com isso:

for i in 'cat hosts'; do ssh $i "sudo -c \"cmd\""; done

e agora dentro do sed:

upload_server=123.123.123.123
upload_server_port=1000
cmd="sed -E 's/(    upload_server = ).*/\1('\"\"'\"'${upload_server}'\"'\"\"', ${upload_server_port})/g' config.py"
ssh $i "sudo -c \"${cmd}\""

o resultado da configuração:

upload_server = (123.123.123.123, 1000)

que deve ser assim:

upload_server = ('123.123.123.123', 1000)

Agora estou muito confuso no uso de citações. : (

    
por jixiang 17.01.2017 / 05:06

2 respostas

1

Nesse caso, você pode ignorar o problema de citação passando o script sed na entrada padrão. O SSH roteia a entrada padrão local para o processo remoto, o sudo apenas o deixa aberto e o sed pode ler seu script no stdin. Você pode passar conteúdo para stdin com um documento aqui .

for i in 'cat hosts'; do
  ssh "$i" 'sudo sed -f - …' <<'EOF'
s/(    upload_server = ).*/("$a", 10051)/g
EOF
done

Mais genericamente, você pode passar um trecho de código em stdin através de SSH sem se preocupar em citar, contanto que você não precise passar dados em stdin.

for i in 'cat hosts'; do
  ssh "$i" sudo sh <<'EOF'
sed 's/(    upload_server = ).*/("$a", 10051)/g' …
EOF
done

Não está claro, com base na sua pergunta, se você deseja inserir "$a" no arquivo de configuração ou "something" , em que o valor da variável a no shell local é something . Se você quiser se referir à variável local, use um documento aqui com interpolação e proteja $\' no documento here com barras invertidas. Observe que, devido à análise por sed e pelo shell remoto no segundo snippet, o valor da variável não deve conter nenhum dos caracteres \/' ou newline.

  ssh "$i" sudo sh <<EOF
sed 's/(    upload_server = ).*/\1("$a", 10051)/g' …
EOF
    
por 18.01.2017 / 01:18
0
$ ssh localhost sh -c \"echo \\'how to print single quotes here\\'\"
'how to print single quotes here'

$ ssh localhost echo \\'how to print single quotes here\\'
'how to print single quotes here'

Para entender as regras, lembre-se que um nível de citação é removido pelo shell local, então o SSH invoca um shell remoto que retira um segundo nível de citação.

    
por 17.01.2017 / 12:16