ssh falha apenas quando vários argumentos são armazenados em uma string

ssh falha apenas quando vários argumentos são armazenados em uma string

Estou escrevendo um script bash no Raspberry Pi OS (baseado no Debian 12 Bookworm). O script tenta fazer algo como

ssh "$args" "$user"@"$ip" 'command'

Pelo que li, esta é uma prática padrão. No entanto, descobri que quando $argscontém mais de um argumento, como

-v -i /path/to/keyfile -o StrictHostKeyChecking=yes

e então executando

ssh "$args" "$user"@"$ip" 'echo "Success in logging into $HOSTNAME"'

ssh retorna o seguinte com um status de saída de 255:

unknown option --
 usage: ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-B bind_interface] 
            [-b bind_address] [-c cipher_spec] [-D [bind_address:]port]
            [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11]
            [-i identity_file] [-J [user@]host[:port]] [-L address]
            [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
            [-Q query_option] [-R address] [-S ctl_path] [-W host:port]
            [-w local_tun[:remote_tun]] destination [command [argument ...]]

No entanto, executar o mesmo comando usando apenas o conteúdo de $argsem vez de usar $argsé bem-sucedido e sai com um status de 0:

ssh -v -i /path/to/keyfile -o StrictHostKeyChecking=yes "$user"@"$ip" 'echo "Success in logging into $HOSTNAME"'

Para reafirmar, using $argsfunciona perfeitamente bem quando há apenas um único argumento, como

-o StrictHostKeyChecking=yes

O que está acontecendo aqui? O que posso fazer para evitar isso? Pelo unknown option --que parece, algo está analisando $argse eliminando algumas coisas, porque só reclama disso quando há dois ou mais argumentos (duas incidências de -in $args)?

Responder1

(Eu provavelmente deveria fechar isso como uma duplicata, mas vamos tentar explicar o caso específico de qualquer maneira.)

A expansão citada "$args"produzumargumento, então na verdade você está executando ssh "-v -i /path/to/keyfile -o StrictHostKeyChecking=yes" .... Os espaços e travessões são considerados caracteres de opção, da mesma forma que as opções empilhadas funcionam nos casos mais úteis, como -abc. O traço não é uma opção válida, então você recebe uma reclamação.

Se ssh "$args"parece funcionar com args='-o StrictHostKeyChecking=yes', provavelmente é porque o analisador for -oignora os espaços em branco (da mesma forma que o espaço em branco ssh_configé ignorado). Tente o mesmo com args='-i /path/to/keyfile'e você provavelmente obterá um erro de arquivo não encontrado, já que acabou de incluir um espaço inicial no nome do arquivo. ( args='-i/path/to/keyfile'sem o espaço funcionaria, é claro.)

Ver:

informação relacionada