Reputation: 176
I try to make a script to automate my experiments.
My purpose is to run a command like this from a shell script which to run another script on the server:
ssh [email protected] 'sh ControlIperfServer.sh start'
Even though the file ControlIperfServer.sh was already placed in /root directory of the server.com but the output from terminal is:
bash: sh ControlIperfServer.sh start: command not found
While I was able to run that command when I type it in terminal. It only can not be executed when executing it from a script.
What I mean is:
When I type the command in terminal. It works.
[root@CentOSVanilla ~]# ssh [email protected] 'sh ControlIperfServer.sh start'
Running IPERF SERVER
[root@CentOSVanilla ~]#
When I put the command in the script and execute the script. It does not work.
[root@CentOSVanilla ~]# ./Runtest.sh
bash: sh ControlIperfServer.sh start: command not found
[root@CentOSVanilla ~]#
I used the verbose -v option to track
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
Thank you very very very much for your help.
I add the code of my 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 root@$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
I already placed all the script files on the host named "server.com".
Upvotes: 0
Views: 5841
Reputation: 530902
This
CMD="ssh -v root@$REMOTE_SERVER \"$RUN_IPERF_SERVER\""
is a bad idea. The quotes embeded in CMD
are treated as literal quotes; they are not used simply to protect whitespace in RUN_IPERF_SERVER
. It's OK to put the name of a command in a variable, but its arguments should be kept separate. If you are using bash
(or some other shell that supports arrays), I recommend
CMD=ssh
CMD_OPTIONS=( -v root@REMOTE_SERVER "$RUN_IPERF_SERVER" )
$CMD "${CMD_OPTIONS[@]}"
If you cannot use arrays, you could fall back to using eval
:
CMD="ssh -v root@$REMOTE_SERVER \"$RUN_IPERF_SERVER\""
eval "$CMD"
but I would recommend this
CMD=ssh
CMD_OPTIONS="-v root@REMOTE_SERVER" # Note no whitespace to protect
$CMD $CMD_OPTIONS "$REMOTE_IPERF_SERVER"
Upvotes: 4
Reputation: 2145
Give /bin/sh a try instead of sh. Your aliases might not be loaded if you call ssh from the script.
Upvotes: -2
Reputation: 3340
Looks like it thinks 'sh ControlIperfServer.sh start' is a command. One file. Not a file with arguments. Try ' escapes like \' to fix.
Also use a either ./ControlIperfServer.sh or /root/ControlIperfServer.sh. A root's shell should never have "." in its path for security reasons, so don't count on it being there.
Upvotes: 0