• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

Script mit Parametern remote ausführen

Calvin

Hacker
Hallo zusammen,

ich habe ein Script, dem ich mehrere Argumente der Form --p1 param1 --p2 param2 usw. mitgeben kann. Dieses führe ich sowohl lokal als auch über ssh auf einem anderen Rechner aus.

Grundsätzlich funktioniert das auch, aber es scheint Probleme zu geben, wenn der erste Parameter mit -- beginnt. Ich erhalte dann (sinngemäß) die Meldung "bash: Unknown parameter"

Kennt jemand die Ursache? Wie kann man das umgehen? Die genaue Fehlermeldung kann ich leider erst morgen nachreichen. Heute abend habe ich kein Remote-System zur Verfügung. Aber vielleicht findet sich ja schon jemand, der helfen kann :)

Hier die beiden Scripte. Ausgeführt wird main.sh, welches dann testscript.sh lokal und über ssh ausführt

Code:
#/bin/bash
# main.sh

param1=abc
param2=def

# Lokal funktioniert es
./testscript.sh --p1 $param1 --p2 $param2

# Mit dummy-Argument geht es auch über ssh
ssh user@hostname 'bash -s' < ./testscript.sh dummy --p1 $param1 --p2 $param2

# Ohne dummy-Argument geht es über ssh nicht
ssh user@hostname 'bash -s' < ./testscript.sh --p1 $param1 --p2 $param2

Code:
#!/bin/bash
# testscript.sh

var1=""
var2=""

while [ $# -gt 0 ]; do
  arg=$1
  shift
  case $arg in
      --p1)
              var1=$1
              shift
              ;;
       --p2)
              var2=$1
              shift
              ;;
  esac
done

echo var1: $var1
echo var2: $var2
 
OP
C

Calvin

Hacker
Der Vollständigkeit halber hier noch die Fehlermeldung:

Code:
bash: --: Ungültige Option
Benutzung:      bash [Lange GNU Option] [Option] ...
                bash [Lange GNU Option] [Option] Script-Datei ...
Lange GNU Optionen:
        --debug
        --debugger
        --dump-po-strings
        --dump-strings
        --help
        --init-file
        --login
        --noediting
        --noprofile
        --norc
        --posix
        --protected
        --rcfile
        --rpm-requires
        --restricted
        --verbose
        --version
Shell-Optionen:
        -irsD oder -c Kommando          (Nur Aufruf)
        -abefhkmnptuvxBCHP oder Option -o
 

spoensche

Moderator
Teammitglied
Die Befehlskette
Code:
ssh user@hostname 'bash -s' < ./testscript.sh --p1 $param1 --p2 $param2
bedeutet:

Das ssh Kommando bekommt über STDIN (Std. Eingabe) Daten die von STDOUT (Std. Ausgabe) des Scriptes stammt überträgt diese auf den anderen Rechner und reicht sie dort als Parameter an den Befehl bash weiter.

Da du in deinem Script lediglich die Übergabeparameter (also --p1 und --p2) ausgibst und die Bash auf dem anderen Rechner die Parameter nicht kennt, kann die Bash nur mit einer Fehlermeldung reagieren.
 
OP
C

Calvin

Hacker
Es tut mir leid, aber ich verstehe nicht, was du mir mit dem zweiten Satz sagen willst. Was genau meinst du mit "lediglich die Übergabeparameter ausgibst"? Meinst du die Ausgabe, die durch Ausführen von testscript.sh entsteht?

Wo ist der Unterschied zum Aufruf mit dem dummy-Argument? Da erfolgt das Ausführen des Scripts wie gewünscht auf dem Remote-System. Wenn ich noch die Zeile echo $(ls ~) in testscreipt.sh einfüge, kann ich das nachvollziehen.
 

spoensche

Moderator
Teammitglied
Calvin schrieb:
Es tut mir leid, aber ich verstehe nicht, was du mir mit dem zweiten Satz sagen willst.

Kein Problem. Ich hab mich wie so oft zu kompliziert ausgedrückt.

Calvin schrieb:
Was genau meinst du mit "lediglich die Übergabeparameter ausgibst"? Meinst du die Ausgabe, die durch Ausführen von testscript.sh entsteht?Wo ist der Unterschied zum Aufruf mit dem dummy-Argument?

Ja ich meine die Ausgabe von testscript.sh. Mit "<" sagst du dem ssh das seine Eingabe aus einer Datei kommt, in deinem Fall testscript.sh. Das hat zur Folge das die Parameter --p1 und --p2 nicht von testscripts.sh verwendet werden, sondern an den ssh Befehl weitergeleitet werden. Auf dem Server bekommt die Bash dann die Parameter --p1 ..., die ja eigentlich von testscript.sh verwendet werden sollen.

Vor dem dummy ist kein --.

Du kannst das ganz einfach ausprobieren, in dem du mal folgendes ausführst:

Code:
echo < ./testscript.sh --p1 param --p2 param

Wenn du allerdings den Aufruf in
Code:
./testscript.sh --p1 param --p2 -param | ssh user@hostname 'bash -s'

änderst sollte es funktionieren.
 
OP
C

Calvin

Hacker
Das hat zur Folge das die Parameter --p1 und --p2 nicht von testscripts.sh verwendet werden, sondern an den ssh Befehl weitergeleitet werden. Auf dem Server bekommt die Bash dann die Parameter --p1 ..., die ja eigentlich von testscript.sh verwendet werden sollen.

Soweit klar und nachvollziehbar. Was ich aber immer noch nicht verstehe:

Vor dem dummy ist kein --.
Und das bewirkt, dass --p1 und --p2 nicht mehr als Parameter an die Bash gegeben und stattdessen vom Script genutzt werden? Wenn ja, dann reicht mir das als Workaround/Lösung. Schließlich funktioniert es ja so. Und in meinem Fall ist das Dummy-Argument sogar genutzt. Es sieht halt nur unschön aus bzw. muss kommentiert bleiben.

spoensche schrieb:
Wenn du allerdings den Aufruf in
Code:
./testscript.sh --p1 param --p2 -param | ssh user@hostname 'bash -s'

änderst sollte es funktionieren.

Nein, das funktioniert nicht

Code:
bash: Zeile 1: var1:: Kommando nicht gefunden.
bash: Zeile 2: var2:: Kommando nicht gefunden.

Wäre das nicht eigentlich auch was ganz anderes? In diesem Fall wird doch erst das testscript lokal ausgeführt und die Ausgabe dann an das Remote-System weitergeleitet, oder?
 

spoensche

Moderator
Teammitglied
Calvin schrieb:
Soweit klar und nachvollziehbar. Was ich aber immer noch nicht verstehe:

Vor dem dummy ist kein --.
Und das bewirkt, dass --p1 und --p2 nicht mehr als Parameter an die Bash gegeben und stattdessen vom Script genutzt werden? Wenn ja, dann reicht mir das als Workaround/Lösung. Schließlich funktioniert es ja so. Und in meinem Fall ist das Dummy-Argument sogar genutzt. Es sieht halt nur unschön aus bzw. muss kommentiert bleiben.

Die Bash interpretiert "dummy" als Script bzw. Kommando, das mit den Parametern --p1 und --p2 aufgerufen wird.

Calvin schrieb:
spoensche schrieb:
Wenn du allerdings den Aufruf in
Code:
./testscript.sh --p1 param --p2 -param | ssh user@hostname 'bash -s'

änderst sollte es funktionieren.

Nein, das funktioniert nicht

Code:
bash: Zeile 1: var1:: Kommando nicht gefunden.
bash: Zeile 2: var2:: Kommando nicht gefunden.

Die Std. Ausgabe von testscript.sh wird an die Std, Eingabe von ssh weitergeleitet und als Eingabe weiterverarbeitet.

Calvin schrieb:
Wäre das nicht eigentlich auch was ganz anderes? In diesem Fall wird doch erst das testscript lokal ausgeführt und die Ausgabe dann an das Remote-System weitergeleitet, oder?

Richtig. Wenn du das Script auf dem Server ausführen willst, dann kannst du das Script auf den Server kopieren und dann mit ssh username@hostname deinscript.sh' dasScript ausführen.
 
OP
C

Calvin

Hacker
Jetzt verwirrst du mich noch mehr ;) Deine Erklärungen klingen plausibel, aber...

spoensche schrieb:
Wenn du das Script auf dem Server ausführen willst, dann kannst du das Script auf den Server kopieren und dann mit ssh username@hostname deinscript.sh' dasScript ausführen.

Das klingt so, als würde das Script ohne vorheriges Hochladen gar nicht auf dem Server ausgeführt werden. Das tut es aber :???:

Hochladen war für mich eigentlich keine Option. Ich sehe da jetzt aber doch eine Möglichkeit. Eventuell schaue ich mir das nochmal in Ruhe an.
 

spoensche

Moderator
Teammitglied
Calvin schrieb:
Jetzt verwirrst du mich noch mehr ;)

Das ist nicht in meinem Sinne. :(

Calvin schrieb:
spoensche schrieb:
Wenn du das Script auf dem Server ausführen willst, dann kannst du das Script auf den Server kopieren und dann mit ssh username@hostname deinscript.sh' dasScript ausführen.

Das klingt so, als würde das Script ohne vorheriges Hochladen gar nicht auf dem Server ausgeführt werden. Das tut es aber :???:

Richtig. Das Script wird bei dir lokal ausgeführt und nicht auf dem Server.
 
OP
C

Calvin

Hacker
OK, dann habe ich entweder noch einen grundsätzlichen Denkfehler oder wir reden vollkommen aneinander vorbei :???: Ich habe das Beispiel vom Anfang mal noch deutlich verkleinert:

Code:
#/bin/bash
# main.sh

# Lokal ausgeführt
./testscript.sh

# Auf remote-Rechner ausgeführt
ssh user@hostname 'bash -s' < ./testscript.sh

Code:
#!/bin/bash
# testscript.sh
echo $(ls)

Wenn testscript.sh in beiden Fällen lokal ausgeführt wird, dann würde ich zwei mal die gleiche Ausgabe erwarten. Zumindest interpretiere ich so deine Aussagen.

Tatsächlich kriege ich aber zwei unterschiedliche Ausgaben. Einmal die Ordner/Dateien im lokalen Arbeitsverzeichnis und einmal vom Remote-Rechner.

Oder meintest du mit "wird lokal ausgeführt" etwas ganz anderes?

Ich hatte den remote-Aufruf so verstanden, dass die Datei zeilenweise(?) eingelesen, an die remote-bash übergeben und dann dort ausgeführt wird.
 
A

Anonymous

Gast
Ich verstehe irgendwie nicht wo der Problem ist. funktioniert doch prächtig.
testscript.sh :
Code:
#!/bin/bash
if [ $1 = 'A' ]
        then echo $USER on $HOSTNAME
else
        echo 1. Argument ist nicht \"A\"
fi

if [ $2 = 'B' ]
        then  ls -l | head -5
else
        echo 2. Argument ist nicht \"B\"
fi

if [ $# -gt 3 ]
        then echo Argumente sind : "$@" 
else
        echo Anzahl der Argumente stimmt nicht
fi

Aufruf mit den 4 Argumenten A B C D über ssh ohne es vorher dorthin zu kopieren ( aus Mangels eines 2. laufenden Linuxes mal ein localer Test, aber der ssh-User könnte die Datei wegen Rechegründen weder lesen noch finden, also wenn das so funktioniet, dann auch über Rechnergrenzen hinweg)
Code:
linux-v7rz:~/bin # ssh tanja@localhost 'bash -s' < testscript.sh A B C D
Password: 
tanja on linux-v7rz
total 56
drwxr-xr-x 11 tanja users 12288 Nov  5  2012 Bilder
drwxr-xr-x  2 tanja users  4096 Jan 23  2012 Desktop
drwxr-xr-x  2 tanja users  4096 Aug 12 02:55 Dokumente
drwxr-xr-x  4 tanja users  4096 Oct 16 23:32 Downloads
Argumente sind : A B C D
linux-v7rz:~/bin #

robi
 
A

Anonymous

Gast
vor die Argumente oder noch besser vor das Umleitungszeichen ein -- setzen (bedeutet für die Bash hier sind ihre Argumente zu Ende die sie für sich interprtieren soll)
Script mal geändert das als erste Argumente -A und -B abgefragt werden
Code:
#!/bin/bash
if [ $1 = '-A' ]
        then echo $USER on $HOSTNAME
else
        echo 1. Argumen ist nicht \"A\"
fi

if [ $2 = '-B' ]
        then  ls -l | head -5
else
        echo 2. Argument ist nicht \"B\"
fi

if [ $# -gt 3 ]
        then echo Argumente sind : "$@" 
else
        echo Anzahl der Argumente stimmt nicht
fi
Aufruf dann wie folgt; …
Code:
linux-v7rz:~/bin # ssh tanja@localhost 'bash -s' < testscript.sh -- -A -B -C -D
Password: 
tanja on linux-v7rz
total 56
drwxr-xr-x 11 tanja users 12288 Nov  5  2012 Bilder
drwxr-xr-x  2 tanja users  4096 Jan 23  2012 Desktop
drwxr-xr-x  2 tanja users  4096 Aug 12 02:55 Dokumente
drwxr-xr-x  4 tanja users  4096 Oct 16 23:32 Downloads
Argumente sind : -A -B -C -D

oder
Code:
linux-v7rz:~/bin # ssh tanja@localhost 'bash -s' -- < testscript.sh  -A -B -C -D
Password: 
tanja on linux-v7rz
total 56
drwxr-xr-x 11 tanja users 12288 Nov  5  2012 Bilder
drwxr-xr-x  2 tanja users  4096 Jan 23  2012 Desktop
drwxr-xr-x  2 tanja users  4096 Aug 12 02:55 Dokumente
drwxr-xr-x  4 tanja users  4096 Oct 16 23:32 Downloads
Argumente sind : -A -B -C -D
robi
 
OP
C

Calvin

Hacker
Zunächst mal vielen Dank euch beiden für die Hilfe.

robi schrieb:
vor die Argumente oder noch besser vor das Umleitungszeichen ein -- setzen (bedeutet für die Bash hier sind ihre Argumente zu Ende die sie für sich interprtieren soll)

Diese Erklärung liefert mir endlich das entscheidende Verständnis.

Code:
linux-v7rz:~/bin # ssh tanja@localhost 'bash -s' -- < testscript.sh  -A -B -C -D


So werde ich es machen. Sieht am vernünftigsten aus.
 
Oben