Ausführen ssh-Befehl innerhalb eines Skripts
Ich versuche, ein Skript zu automatisieren meine Experimente.
Meine Absicht ist es, einen Befehl ausführen, wie diese von einem shell-Skript, welches auf ein anderes Skript ausführen lassen auf dem server:
ssh root@server.com 'sh ControlIperfServer.sh start'
Obwohl die Datei ControlIperfServer.sh war bereits im /root-Verzeichnis der server.com aber die Ausgabe vom terminal:
bash: sh ControlIperfServer.sh start: command not found
Während ich war in der Lage zu laufen, dass das Kommando geben, wenn ich es in terminal. Nur kann nicht ausgeführt werden bei der Ausführung aus einer Skript.
Was ich meine ist:
Wenn ich den Befehl im terminal. Es funktioniert.
[root@CentOSVanilla ~]# ssh root@server.com 'sh ControlIperfServer.sh start'
Running IPERF SERVER
[root@CentOSVanilla ~]#
Wenn ich den Befehl im Skript und das Skript ausführen. Es funktioniert nicht.
[root@CentOSVanilla ~]# ./Runtest.sh
bash: sh ControlIperfServer.sh start: command not found
[root@CentOSVanilla ~]#
Verwendet habe ich das verbose -v-option zu verfolgen
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 no-more-sessions@openssh.com
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 eow@openssh.com 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
Danke sehr sehr sehr für Eure Hilfe.
Füge ich den code von meinem 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
Ich schon alle script-Dateien auf dem host mit Namen "server.com".
- Was bedeutet
Runtest.sh
Aussehen? Es klingt wie Sie möglicherweise übermäßig zitiert Sie den Befehl name irgendwo. Wenn ich eine test-Befehl, ich sehedebug1: Sending command: echo foo
(beachten Sie das fehlen der Anführungszeichen). - Sollten Sie bieten, dass Sie als Antwort. Es ist wahrscheinlich der Fall.
- Es ist die Ursache, aber ich wusste nicht, genügend detailliert festzulegen, die eine wahre Lösung.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Diese
ist eine schlechte Idee. Die Zitate eingebettet in
CMD
behandelt werden als wörtliche Zitate; Sie dienen nicht nur dem Schutz von Leerzeichen inRUN_IPERF_SERVER
. Es ist OK, um den Namen eines Befehls in eine variable, aber seine Argumente getrennt werden sollten. Wenn Sie mitbash
(oder eine andere shell, unterstützt von arrays), ich empfehleWenn du keine arrays verwenden, könnten Sie zurückgreifen, um mit
eval
:aber ich würde empfehlen, diese
ssh
erlischt, sobald dieser Befehl abgeschlossen ist. Eigentlich, das gleiche gilt auch, wenn Sie nicht einen Befehl anzugeben; eine interaktive shell gestartet wird, undssh
endet, sobald die Schale vollständig ist (D. H., Sie "Abmelden".)Sieht aus wie es denkt 'sh ControlIperfServer.sh start" ist ein Befehl. Eine Datei. Nicht eine Datei mit Argumenten.
Versuchen Sie ' escapes wie \' zu beheben.
Verwenden auch entweder ./ControlIperfServer.sh oder /root/ControlIperfServer.sh.
Eine root-shell sollte nie haben "." im Pfad, aus Sicherheitsgründen, so zählen Sie nicht auf es gibt.
Geben, /bin/sh ein Versuch statt sh. Den alias kann nicht geladen werden, wenn Sie rufen Sie ssh-Skript.