He visto las preguntas y respuestas sobre la necesidad de hacer doble escape de los argumentos a los comandos ssh remotos. Mi pregunta es:¿exactamente dónde y cuándo se realiza el segundo análisis?
Si ejecuto lo siguiente:
$ ssh otherhost pstree -a -p
Veo lo siguiente en la salida:
|-sshd,3736
| `-sshd,1102
| `-sshd,1109
| `-pstree,1112 -a -p
El proceso padre para el comando remoto (pstree
) es sshd
, no parece haber ningún shell allí que estaría analizando los argumentos de la línea de comando para el comando remoto, por lo que no parece que sean necesarias las comillas dobles o el escape (pero definitivamente lo es). Si, en cambio, hago ssh allí primero y obtengo un shell de inicio de sesión, y luego ejecuto pstree -a -p
Veo lo siguiente en la salida:
├─sshd,3736
│ └─sshd,3733
│ └─sshd,3735
│ └─bash,3737
│ └─pstree,4130 -a -p
Así que claramente hay un bash
shell allí que haría un análisis de línea de comandos en ese caso. Pero en el caso en que uso un comando remoto directamente, no parece haber un shell, entonces, ¿por qué son necesarias las comillas dobles?
Respuesta aceptada:
Siempre hay un shell remoto. En el protocolo SSH, el cliente envía al servidor una cadena para ejecutar. El cliente de línea de comandos SSH toma sus argumentos de línea de comandos y los concatena con un espacio entre los argumentos. El servidor toma esa cadena, ejecuta el shell de inicio de sesión del usuario y le pasa esa cadena. (Más precisamente:el servidor ejecuta el programa que está registrado como shell del usuario en la base de datos del usuario, pasándole dos argumentos de línea de comando:-c
y la cadena enviada por el cliente. El shell no se invoca como un shell de inicio de sesión:el servidor no establece el argumento cero en una cadena que comienza con -
.)
Es imposible pasar por alto el shell remoto. El protocolo no tiene nada como enviar una serie de cadenas que podrían analizarse como una matriz argv en el servidor. Y el servidor SSH no omitirá el shell remoto porque eso podría ser una restricción de seguridad:usar un programa restringido como shell del usuario es una forma de proporcionar una cuenta restringida que solo puede ejecutar ciertos comandos (por ejemplo, una cuenta de solo rsync o una cuenta solo de git).
Es posible que no vea el shell en pstree
porque puede que ya se haya ido. Muchos shells tienen una optimización en la que, si detectan que están a punto de hacer "ejecutar este comando externo, esperar a que se complete y salir con el estado del comando", entonces el shell ejecuta "execve
de este comando externo” en su lugar. Esto es lo que está sucediendo en su primer ejemplo. Contrasta los siguientes tres comandos:
ssh otherhost pstree -a -p
ssh otherhost 'pstree -a -p'
ssh otherhost 'pstree -a -p; true'
Los dos primeros son idénticos:el cliente envía exactamente los mismos datos al servidor. El tercero envía un comando de shell que anula la optimización ejecutiva del shell.
Relacionado:¿Cuál es la diferencia entre bloqueos giratorios y semáforos?