1
votes

l'état de sortie ssh bash -c ne se propage pas


2 commentaires

En règle générale, ne comptez pas sur ssh pour assembler plusieurs arguments en une seule commande. Toujours transmettre un seul argument contenant la commande, à savoir ssh myserver 'bash -c "exit 34"' au lieu de ssh myserver bash -c "exit 34" < / code>.


Il n'est pas immédiatement évident que ces questions soient les mêmes, mais la cause profonde de celle-ci est (comme décrit en détail par Barmar) le problème explicitement abordé dans l'autre; ainsi, les réponses qui y sont données s'appliquent également ici.


3 Réponses :


0
votes

Essayez de mettre entre guillemets:

╰─➤  ssh server "bash -c 'exit 34' "; echo $?
34


0 commentaires

4
votes

Le problème est que la citation est perdue. ssh concatène simplement les arguments, il ne les requote pas, donc la commande que vous exécutez réellement sur le serveur est:

ssh myserver bash -c "'exit 34'"

Le -c L'option ne prend qu'un seul argument, pas tous les arguments restants, donc elle exécute simplement exit ; 34 est ignoré.

Vous pouvez voir un effet similaire si vous le faites:

ssh myserver "bash -c 'exit 34'"

Il fera juste écho à un vide ligne, pas foo .

Vous pouvez le corriger en donnant un seul argument à ssh:

ssh myserver bash -c 'echo foo'

ou en doublant les guillemets:

bash -c exit 34


0 commentaires

1
votes

Dans la mesure où votre question est de savoir comment exécuter une commande à distance tout en la passant sur la ligne de commande de ssh sans que cela n'entraîne un mangle qui déclenche le bogue en question, printf '% q' peut être utilisé pour demandez au shell d'effectuer des citations en votre nom, de créer une chaîne qui peut ensuite être transmise à ssh:

printf -v arg_str '%q ' arg1 arg2 ...
ssh "$host" "bash -s $arg_str" <<'EOF'
for arg; do
  if [[ ! -f "$arg" ]]; then
    exit 1
  fi
done
EOF

Cependant , cela n'est garanti que pour fonctionne correctement si le shell par défaut de l'utilisateur distant est également bash (ou, si vous avez utilisé localement printf% q de ksh, si le shell distant est ksh). Il est beaucoup plus sûr de passer le texte de votre script hors bande, comme sur stdin:

printf -v cmd_str '%q ' bash -c '
    for arg ; do
        if [[ ! -f "$arg" ]] ; then
            exit 1
        fi
    done
' arg1 arg2 ...
ssh "$host" "$cmd_str"

... où nous dépendons toujours de printf% q code > pour générer une sortie correcte, mais uniquement pour les arguments, pas pour le script lui-même.


0 commentaires