我每天都在某个客户环境中工作,由5台AIX服务器组成,有时候我需要在所有5台服务器上发出相同的命令。
所以我在服务器之间设置了基于SSH密钥的身份验证,并启动了一个向所有服务器广播命令的ksh脚本:
#!/usr/bin/ksh
if [[ $# -eq 0 ]]; then
print "broadcast.ksh - broadcasts a command to the 5 XXXXXXXX environments and returns output for each"
print "usage: ./broadcast.ksh command_to_issue"
exit
fi
set -A CUST_HOSTS aaa bbb ccc ddd eee
for host in ${CUST_HOSTS[@]}; do
echo "============ $host ================"
if [[ `uname -n` = $host ]]; then
$*
continue
fi
ssh $host $*
done
echo "========================================="
echo "Finished"
现在,这很好用,直到我想在远程端使用通配符,例如:
./broadcast.ksh ls -l java*
因为'*'在本地系统上展开而不是遥控器。
现在,如果使用ssh远程命令,我可以通过使用单引号来解决这个问题:
ssh user@host ls -l java* <-- will _not_ work as expected, since asterisk will be interpreted locally
ssh user@host 'ls -l java*' <-- _will_ work as expected, since asterisk will be interpreted on the remote end
现在,我已经尝试将其合并到我的脚本中,并尝试创建一个由单引号括起来的$ *内容组成的$命令变量,但是已经淹没在逃避反斜杠和ksh中的连接尝试的海洋中,无济于事。
我确信这有一个简单的解决方案,但我找不到它,所以我想出来问问。
谢谢,
詹姆斯
答案 0 :(得分:1)
如您所见,将星号作为参数传递给您的脚本不起作用,因为shell会在处理参数之前展开它。尝试使用双引号$*
并在脚本调用中使用反斜杠转义星号/分号等,或单引号命令。
for host in ${CUST_HOSTS[@]}; do
echo "============ $host ================"
if [[ `uname -n` = $host ]]; then
"$*"
continue
fi
ssh $host "$*"
done
$ ./broadcast.ksh ls -l java\*
$ ./broadcast.ksh 'ls -l java*; ls -l *log'
答案 1 :(得分:1)
我想发表评论但仍然太低,但Josh的单引号建议应该有效。
root@jdsdrop1:~# cat foo.sh
#!/usr/bin/ksh
if [[ $# -eq 0 ]]; then
print "broadcast.ksh - broadcasts a command to the 5 XXXXXXXX environments and returns output for each"
print "usage: ./broadcast.ksh command_to_issue"
exit
fi
set -A CUST_HOSTS jdsdropfed1 jdsdropfed2-2
for host in ${CUST_HOSTS[@]}; do
echo "============ $host ================"
if [[ `uname -n` = $host ]]; then
$*
continue
fi
ssh $host $*
done
echo "========================================="
echo "Finished"
root@jdsdrop1:~# ./foo.sh 'ls /tmp/foo*'
============ jdsdropfed1 ================
/tmp/foo1
/tmp/foo2
============ jdsdropfed2-2 ================
/tmp/foo1
/tmp/foo2
=========================================
Finished
root@jdsdrop1:~# ssh jdsdropfed1 "ls /tmp/foo*"
/tmp/foo1
/tmp/foo2
root@jdsdrop1:~# ssh jdsdropfed2-2. "ls /tmp/foo*"
/tmp/foo1
/tmp/foo2