J'ai écrit un script qui fonctionne bien lorsqu'il est exécuté localement:
./sysMole -time Aug 18 18
Les arguments "- time", "Aug", "18" et "18" sont passés avec succès sur le script.
Maintenant, ce script est conçu pour être exécuté sur une machine distante mais à partir d'un répertoire local sur la machine locale. Exemple:
ssh root@remoteServer "bash -s" < /var/www/html/ops1/sysMole
Cela fonctionne également très bien. Mais le problème se pose lorsque j'essaie d'inclure les arguments susmentionnés (- heure 18 août 18), par exemple:
ssh root@remoteServer "bash -s" < /var/www/html/ops1/sysMole -time Aug 18 18
Après avoir exécuté ce script, j'obtiens l'erreur suivante:
bash: cannot set terminal process group (-1): Invalid argument
bash: no job control in this Shell
S'il vous plaît, dites-moi ce que je fais mal, c'est très frustrant.
Vous étiez assez proche de votre exemple. Cela fonctionne très bien lorsque vous l'utilisez avec des arguments tels que ceux-ci.
Exemple de script:
$ more ex.bash
#!/bin/bash
echo $1 $2
Exemple qui fonctionne:
$ ssh serverA "bash -s" < ./ex.bash "hi" "bye"
hi bye
Mais il échoue pour ces types d'arguments:
$ ssh serverA "bash -s" < ./ex.bash "--time" "bye"
bash: --: invalid option
...
Le problème que vous rencontrez est que l'argument, -time
, ou --time
dans mon exemple, est interprété comme un basculement vers bash -s
. Vous pouvez pacifier bash
en l'empêchant de prendre pour lui-même l'un des arguments de ligne de commande restants à l'aide de --
argument.
Comme ça:
$ ssh root@remoteServer "bash -s" -- < /var/www/html/ops1/sysMole -time Aug 18 18
# 1:
$ ssh serverA "bash -s" -- < ./ex.bash "-time" "bye"
-time bye
# 2:
$ ssh serverA "bash -s" -- < ./ex.bash "--time" "bye"
--time bye
# 3:
$ ssh serverA "bash -s" -- < ./ex.bash --time "bye"
--time bye
# 4:
$ ssh < ./ex.bash serverA "bash -s -- --time bye"
--time bye
NOTE: Juste pour qu'il soit clair que partout où la redirection apparaît sur la ligne de commande ne fait aucune différence, car ssh
appelle un shell distant avec la concaténation de ses arguments de toute façon, la citation ne fait pas faire beaucoup de différence, sauf lorsque vous avez besoin de citer sur le shell distant comme dans l'exemple # 4:
$ ssh < ./ex.bash serverA "bash -s -- '<--time bye>' '<end>'"
<--time bye> <end>
Si vous n'utilisez vraiment qu'une seule chaîne, par exemple. -time Aug 18 18
, Alors vous pouvez simplement le coder en dur, et les réponses existantes vous indiquent comment procéder de manière adéquate. D'un autre côté, si vous devez passer des arguments inconnus (comme un message à afficher sur l'autre système ou le nom d'un fichier créé où les utilisateurs finaux pourraient contrôler son nom), alors plus de prudence est nécessaire.
bash
ou ksh
comme /bin/sh
Si votre /bin/sh
Distant est fourni par bash ou ksh, vous pouvez effectuer les opérations suivantes en toute sécurité avec une liste d'arguments non fiables, de sorte que même les noms malveillants (comme $(rm -rf $HOME).txt
) peuvent être passés en tant qu'arguments en toute sécurité:
runRemote() {
local args script
script=$1; shift
# generate eval-safe quoted version of current argument list
printf -v args '%q ' "$@"
# pass that through on the command line to bash -s
# note that $args is parsed remotely by /bin/sh, not by bash!
ssh user@remote-addr "bash -s -- $args" < "$script"
}
/bin/sh
Pour éviter les données d'arguments suffisamment malveillantes (tenter de tirer parti des citations non conformes à POSIX utilisées par printf %q
Dans bash lorsque des caractères non imprimables sont présents dans la chaîne échappée) même avec un /bin/sh
c'est baseline-POSIX (comme dash
ou ash
), ça devient un peu plus intéressant:
runRemote() {
local script=$1; shift
local args
printf -v args '%q ' "$@"
ssh user@remote-addr "bash -s" <<EOF
# pass quoted arguments through for parsing by remote bash
set -- $args
# substitute literal script text into heredoc
$(< "$script")
EOF
}
Les fonctions données ci-dessus peuvent alors être invoquées comme:
# if your time should be three arguments
runRemote /var/www/html/ops1/sysMole -time Aug 18 18
...ou...
# if your time should be one string
runRemote /var/www/html/ops1/sysMole -time "Aug 18 18"
Mettez les commandes entre guillemets comme suit:
ssh myserver "date +\"Date: %Y%m%d %H:%M\";printf \"Uptime: \";uptime;printf \"uname: \";uname -a"
Date: 20200409 20:02
Uptime: 20:02:29 up 66 days, 55 min, 2 users, load average: 0.06, 0.05, 0.08
uname: Linux zltcmtn23aecc1rx7322 4.4.0-116-generic #140-Ubuntu SMP Mon Feb 12 21:23:04 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
Connection to 105.31.182.217 closed.