我尝试过很多种组合,但都没有奏效,现在我的想法已经用完了。
所以我的意图是从预定的 at-job 中获取时间,并在其前半小时进行另一次 AT-job。然后在多台计算机上循环运行该命令。
我已经走到这一步了,但是这使得 AT 作业在源 Linux 中,而不是在目标中:
ssh linuxserver atq | awk '{print ($3), $2}' | { read time; date -d "$time -30 min" "+%H:%M %F" ; } | { read time2; echo "yum upgrade -y" | at "$time2" ; }
然后我确信 for 循环会使引用更加困难,但在使前面的命令工作之前我无法测试它。然后我会像这样使用 for 循环:
for loop in $(cat /tmp/names)
do
ssh $loop atq | awk '{print ($3), $2}' | { read time; date -d "$time -30 min" "+%H:%M %F" ; } | { read time2; echo "yum upgrade -y" | at "$time2" ; }
done
有任何想法吗?
答案1
如果您有权访问,bash
您可以使用该printf '%q\n' "$command"
模式来获取有效命令。首先,制作一个有效的当地的命令如下:
atq | awk '{print ($3), $2}' | { read time; date -d "$time -30 min" "+%H:%M %F" ; } | { read time2; echo "yum upgrade -y" | at "$time2" ; }
现在将其放入变量中这样在回显时,您将获得完全相同的结果。最简单的方法是尽可能使用单引号,必要时使用双引号(仅有的用单引号括起来):
$ cat command.sh
atq | awk '{print ($3), $2}' | { read time; date -d "$time -30 min" "+%H:%M %F" ; } | { read time2; echo "yum upgrade -y" | at "$time2" ; }
$ command='atq | awk '"'"'{print ($3), $2}'"'"' | { read time; date -d "$time -30 min" "+%H:%M %F" ; } | { read time2; echo "yum upgrade -y" | at "$time2" ; }'
您可以使用以下命令验证这些是否相同diff
:
$ diff command.sh <(echo "$command")
$ echo $?
0
现在将其打印出来以便您可以将其放入ssh
命令中:
printf '%q\n' "$command"
atq\ \|\ awk\ \'\{print\ \(\$3\)\,\ \$2\}\'\ \|\ \{\ read\ time\;\ date\ -d\ \"\$time\ -30\ min\"\ \"+%H:%M\ %F\"\ \;\ \}\ \|\ \{\ read\ time2\;\ echo\ \"yum\ upgrade\ -y\"\ \|\ at\ \"\$time2\"\ \;\ \}
虽然丑陋,但确实有效。
答案2
使用您的命令仅atq
在远程机器中运行,您只需传递一个用单引号括起来的长命令行:
ssh linuxserver ' command1 'command2' command3 '
但是命令行中有单引号,因此您可以像这样将其转义:
ssh linuxserver $' command1 \'command2\' command3 '
因此结果将是:
ssh linuxserver $' atq | awk \'{print ($3), $2}\' | { read time; date -d "$time -30 min" "+%H:%M %F" ; } | { read time2; echo "yum upgrade -y" | at "$time2" ; } '
答案3
不要试图在语法上耍小聪明ssh hostname command arg1 arg2 ... argN
。在远程主机上创建一个 shell 脚本并让它完成工作,而不是用所有的引用来烦扰你的同事。例如:
$ ssh linuxserver /usr/local/bin/my_atq.sh