Eu já vi as perguntas e respostas sobre a necessidade de escape duplo dos argumentos para os comandos ssh remotos. Minha pergunta é: exatamente onde e quando é feita a segunda análise?
Se eu executar o seguinte:
$ ssh otherhost pstree -a -p
Vejo o seguinte na saída:
|-sshd,3736
| `-sshd,1102
| `-sshd,1109
| `-pstree,1112 -a -p
O processo pai do comando remoto ( pstree
) é sshd
que não parece haver nenhum shell que analise os argumentos da linha de comando no comando remoto, portanto, não parece que seja necessário aspas duplas ou escape ( mas definitivamente é). Se, em vez disso, eu colocar o ssh lá primeiro e obter um shell de login e, em seguida, execute pstree -a -p
, vejo o seguinte na saída:
├─sshd,3736
│ └─sshd,3733
│ └─sshd,3735
│ └─bash,3737
│ └─pstree,4130 -a -p
Então, claramente, existe um bash
shell que faria a análise da linha de comando nesse caso. Mas no caso em que eu uso diretamente um comando remoto, não parece haver um shell, então por que é necessário citar duas vezes?
Eu acho que descobri:
Os argumentos para
pstree
são: mostrar argumentos da linha de comando, mostrar pids e mostrar apenas os processos pai do pid especificado. A'$$'
é uma variável de shell especial que o bash substituirá por seu próprio pid quando o bash avaliar os argumentos da linha de comando. É citado uma vez para impedir que seja interpretado pelo meu shell local. Mas não é duplamente citado ou escapado para permitir que ele seja interpretado pelo shell remoto.Como podemos ver, é substituído
12001
por esse é o pid do shell. Também podemos ver pela saída:pstree,12001
que o processo com um pid de 12001 é o próprio pstree. Entãopstree
é a concha?O que eu entendo está acontecendo lá é que
bash
está sendo invocado e está analisando os argumentos da linha de comando, mas depois ele invocaexec
para substituir a si próprio pelo comando que está sendo executado.Parece que só faz isso no caso de um único comando remoto:
Nesse caso, estou solicitando a execução de dois comandos:
pstree
seguido porecho
. E podemos ver aqui quebash
, de fato, aparece na árvore de processos como pai depstree
.fonte
Apoiando o que as outras respostas disseram, procurei o código que chama comandos no controle remoto, https://github.com/openssh/openssh-portable/blob/4f29309c4cb19bcb1774931db84cacc414f17d29/session.c#L1660 ...
... que, como você pode ver, invoca incondicionalmente
shell
com o primeiro argumento-c
e o segundo argumentocommand
. Anteriormente, ashell
variável foi definida como o shell de login do usuário, conforme registrado em/etc/passwd
.command
é um argumento para essa função e, em última análise, é definido como uma string lida literalmente fora do fio (consultesession_exec_req
o mesmo arquivo ). Portanto, o servidor não interpreta o comando, mas um shell é sempre chamado no controle remoto.No entanto, a parte relevante da especificação do protocolo SSH é que não parecem exigir esse comportamento; apenas diz
Provavelmente, porque nem todos os sistemas operacionais têm o conceito de shell de linha de comando. Por exemplo, não seria uma loucura para um servidor ssh Classic MacOS alimentar cadeias de comando "exec" para o intérprete AppleScript .
fonte