在脚本中执行ssh命令
我尝试制作一个脚本来自动执行我的实验。
我的目的是从一个shell脚本,在服务器上运行另一个脚本运行如下命令:
在脚本中执行ssh命令
ssh [email protected] 'sh ControlIperfServer.sh start'
即使文件ControlIperfServer.sh已经放置在服务器的/ root目录。 COM但是从端子的输出是:
bash: sh ControlIperfServer.sh start: command not found
虽然我能够当我在终端键入以运行该命令。从脚本执行它时,它只能执行。我的意思是:
当我在终端键入命令。有用。
[[email protected] ~]# ssh [email protected] 'sh ControlIperfServer.sh start'
Running IPERF SERVER
[[email protected] ~]#
当我将该命令放入脚本并执行脚本时。这是行不通的。
[[email protected] ~]# ./Runtest.sh
bash: sh ControlIperfServer.sh start: command not found
[[email protected] ~]#
我使用的详细-v选项以跟踪
debug1: Next authentication method: publickey
debug1: Trying private key: /root/.ssh/identity
debug1: Offering public key: /root/.ssh/id_rsa
debug1: Server accepts key: pkalg ssh-rsa blen 277
debug1: read PEM private key done: type RSA
debug1: Authentication succeeded (publickey).
debug1: channel 0: new [client-session]
debug1: Requesting [email protected]
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env LANG = en_US.UTF-8
debug1: Sending env LC_CTYPE = UTF-8
debug1: Sending command: 'sh ControlIperfServer.sh start;'
bash: sh ControlIperfServer.sh start;: command not found
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: client_input_channel_req: channel 0 rtype [email protected] reply 0
debug1: channel 0: free: client-session, nchannels 1
Transferred: sent 2352, received 2360 bytes, in 0.2 seconds
Bytes per second: sent 10829.0, received 10865.9
debug1: Exit status 127
非常感谢你非常非常多的帮助。
添加我Runtest.sh的代码:
#!/bin/sh
# A script to run test automatically, need modify when using
# Usage:
# ./RunTest.sh <number of test> [threads]
# [threads]: when there is threads, use -P option of Iperf
# Otherwise, run multiple instances of Iperf
# <number of test>: Defaut is 1
# Number of Threads/Processes
# Number of time capture traffic
RUN_IPERF_SERVER="sh ControlIperfServer.sh start"
STOP_IPERF_SERVER="sh ControlIperfServer.sh stop"
RUN_TCPDUMP="sh ControlTCPdump.sh start"
STOP_TCPDUMP="sh ControlTCPdump.sh stop"
RUN_CLIENT="iperf -c"
TARGET_SERVER="10.10.10.253"
REMOTE_SERVER="server.com"
DIRECTORY="CaptureTraffic"
TCP_DURATION="60"
if [ "$1" = "" ]; then
MAX_TEST=1;
else
MAX_TEST=$1;
fi
# Run server daemon on remote server
CMD="ssh -v [email protected]$REMOTE_SERVER \"$RUN_IPERF_SERVER\""
echo Running $CMD
$CMD # Run iperf server remotely
sleep 5 # Waiting for server to run
CMD="ssh -v $REMOTE_SERVER 'mkdir $DIRECTORY && echo ok'"
DIROK="$($CMD)"
if [ "$DIROK" = ok ]; then
mkdir $DIRECTORY
else
echo Cannot create directory\! Please be careful\!
fi
for INCR in $(seq 1 $MAX_TEST)
do
echo Running Test $INCR
#Prepare TCP to capture traffic (run on host)
echo Setting-up TCPdump for capture traffic
FILENAME="$DIRECTORY/CapturedTraffic$INCR.dmp"
ssh $REMOTE_SERVER \'$RUN_TCPDUMP $FILENAME\'
sleep 5
# Running the client (running locally)
if [ "$2" = threads ]; then
echo "Running Iperf Client as threads model"
$RUN_CLIENT $TARGET_SERVER -t $TCP_DURATION -P $INCR
else
echo "Running Iperf Client as processes model"
sh parallel.sh -j $INCR \"$RUN_CLIENT $TARGET_SERVER -t $TCP_DURATION\"
fi
#Stop TCPdump (run on host)
ssh $REMOTE_SERVER '$STOP_TCPDUMP'
sleep 5 #Wait for TCPdump write file to harddrive
done
#Stop Iperf Deamon
ssh $REMOTE_SERVER '$STOP_IPERF_SERVER'
sleep 3
我已经放在一个名为“server.com”主机上的所有脚本文件。
这
CMD="ssh -v [email protected]$REMOTE_SERVER \"$RUN_IPERF_SERVER\""
是一个坏主意。嵌入在CMD
中的引号被视为文字引号;它们不仅仅用于保护RUN_IPERF_SERVER
中的空格。把一个命令的名字放在一个变量中是可以的,但它的参数应该保持分开。如果您正在使用bash
(或支持数组一些其他的壳),我建议
CMD=ssh
CMD_OPTIONS=(-v [email protected]_SERVER "$RUN_IPERF_SERVER")
$CMD "${CMD_OPTIONS[@]}"
如果你不能使用数组,你可能回落到使用eval
:
CMD="ssh -v [email protected]$REMOTE_SERVER \"$RUN_IPERF_SERVER\""
eval "$CMD"
,但我会推荐这
CMD=ssh
CMD_OPTIONS="-v [email protected]_SERVER" # Note no whitespace to protect
$CMD $CMD_OPTIONS "$REMOTE_IPERF_SERVER"
它像一个魅力。非常感谢@chepner! – 2013-03-21 08:27:44
我还有一个问题。每次我通过ssh发送命令时,是否需要发送“退出”命令?谢谢你回答我! – 2013-03-21 09:05:45
否;如果你发送一个明确的命令,一旦该命令完成,'ssh'就会终止。实际上,即使你不指定命令也是如此;一个交互式shell就会启动,一旦该shell完成(即注销),'ssh'就会终止。 – chepner 2013-03-21 12:30:09
看起来像是认为'sh ControlIperfServer.sh start'是一个命令。一个文件。不是带参数的文件。 尝试像\'逃脱'来解决。
也使用./ControlIperfServer.sh或/root/ControlIperfServer.sh。 根的外壳不应该有“。”。在出于安全原因的道路上,所以不要指望它在那里。
给/ bin/sh试一下,而不是sh。如果您从脚本调用ssh,则可能不会加载别名。
Runtest.sh是什么样的?这听起来像你可能在某处过分引用了命令名。当我做一个测试命令时,我看到'debug1:发送命令:echo foo'(注意缺少引号)。 – chepner 2013-03-20 16:52:02
@chepner:你应该提供这个答案。这很可能是这种情况。 – Dolda2000 2013-03-20 17:06:56
这是原因,但我不知道足够的细节来指定真正的解决方案。 – chepner 2013-03-20 17:08:28