ubuntuusers.de

Bash: read Kommando

Status: Gelöst | Ubuntu-Version: Ubuntu GNOME 16.04 (Xenial Xerus)
Antworten |

KeyzerSoze

Anmeldungsdatum:
28. September 2014

Beiträge: 120

Hallo ubuntuusers!

Das ist ein Beispielprogramm für das read Kommando:

$ nano hallo.sh


#!/bin/bash
#Begrüßung

read -p "Geben sie ihren Namen ein: " name
echo Hallo: $name

Ich habe folgende Frage: Kann ich dieses Programm mittels ./hallo.sh und eventuell (falls nötig) einigen zusätzlichen Optionen so ausführen, dass ich die Variablen (in diesem Fall $name) schon beim Aufruf eingebe und später nicht mehr dannach gefragt werde? Wie würde das bsw. für 2 Variablen aussehen?

Z.B.:

./hallo.sh --option:$name=ubuntuuser

sodass das Programm straight forward:

Hallo: ubuntuuser

liefert.

Ps. Geht das auch für andere Programmiersprachen (C, Fortran)?

Danke im Voraus && viele Grüße

ChickenLipsRfun2eat Team-Icon

Anmeldungsdatum:
6. Dezember 2009

Beiträge: 12067

Hallo!

Du könntest mal nach getops fahnden für größere Beispiele. Am einfachsten ist es die Variablen direkt abzufragen:

#!/bin/bash
echo $1
echo $2

Würde dann so

./meinProgramm bla blub
bla
blub

ausgeben.

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

KeyzerSoze schrieb:

... mittels ./hallo.sh und eventuell (falls nötig) einigen zusätzlichen Optionen so ausführen, ...

... Variablen (in diesem Fall $name) schon beim Aufruf eingebe ...

./hallo.sh --option:$name=ubuntuuser

Du verwechselst hier grundsätzlich 2 Dinge:

  1. Variablenzuweisungen der Shell (z.B. name=Schnuffel → Variablenzuweisungen stehen immer allein in der Zeile oder vor einem Befehl !) und

  2. Optionen eines Programmaufrufs (→ alles was nach dem Programmnamen kommt, sind Optionen !)

Ganz praktisch kannst Du ja mal gucken, was Dein Befehl genau macht:

track@track:~$ set -x
track@track:~$ ./hallo.sh --option:$name=ubuntuuser
+ ./hallo.sh --option:=ubuntuuser                                # die leere Variable wird konkret durch "nichts" ersetzt
bash: ./hallo.sh: Datei oder Verzeichnis nicht gefunden
track@track:~$ name=Schnuffel                                    # hier kommt die Variablenzuweisung
+ name=Schnuffel
track@track:~$ ./hallo.sh --option:$name=ubuntuuser
+ ./hallo.sh --option:Schnuffel=ubuntuuser                       # die Variable wird jetzt durch ihren Inhalt ersetzt
bash: ./hallo.sh: Datei oder Verzeichnis nicht gefunden          #   (was hier natürlich auch keinen Sinn macht) 

Bitte lies im Bash-Manual die genauen Zusammenhänge der Variablen-Expansion und den Shell-Parametern (= Optionen !) nach. Dann wirst Du besser verstehen.

LG,

track

KeyzerSoze

(Themenstarter)

Anmeldungsdatum:
28. September 2014

Beiträge: 120

track:

Bitte lies im Bash-Manual die genauen Zusammenhänge der Variablen-Expansion und den Shell-Parametern (= Optionen !) nach. Dann wirst Du besser verstehen.

Habe ich gemacht ☺

Du verwechselst hier grundsätzlich 2 Dinge: Variablenzuweisungen der Shell (z.B. name=Schnuffel → Variablenzuweisungen stehen immer allein in der Zeile oder vor einem >Befehl !) und Optionen eines Programmaufrufs (→ alles was nach dem Programmnamen kommt, sind Optionen !)

Ja okay, lassen wir die Optionen einfach weg (die haben hier nichts zu suchen). Wenn ich vor Aufrufen meiner Datei hallo.sh die Variable name zuweise, so passiert nichts, weil der read-Befehl im Programm dennoch ausgeführt wird und die Variable überschrieben wird. Ich möchte den read-Befehl aber gänzlich unterdrücken und die vorhin zugewiesene Variable anstelle dessen verwenden.

Mein Endziel wäre es, den read-Befehl zu unterdrücken, die Variable(n) zuzuweisen ohne dass ich den Namen der Variable(n) kenne, ich weiß nur, der wievielte read-Befehl es ist. (als Beispiel könnte ein .sh-Programm dienen, bei dem ich keine Lese- und Schreibe, sondern nur Ausführrechte besitze)

Viele Grüße

lionlizard

Avatar von lionlizard

Anmeldungsdatum:
20. September 2012

Beiträge: 6244

Wohnort: Berlin

Meinst Du das so:

user@rechner:~$ /home/user/hallo André
hallo André
user@rechner:~$ /home/user/hallo Lilo
hallo Lilo
user@rechner:~$ cat /home/user/hallo
#! /bin/bash

name=$1
echo "hallo $name"

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

KeyzerSoze schrieb:

Ja okay, lassen wir die Optionen einfach weg (die haben hier nichts zu suchen).

Da bin ich mir noch gar nicht sicher !

Wenn ich vor Aufrufen meiner Datei hallo.sh die Variable name zuweise, so passiert nichts, weil der read-Befehl im Programm dennoch ausgeführt wird und die Variable überschrieben wird. Ich möchte den read-Befehl aber gänzlich unterdrücken und die vorhin zugewiesene Variable anstelle dessen verwenden.

Ok, dann musst Du das machen: z.B. indem Du die betreffende Variable in Deinem hallo-Skript vorher abfragst. ( if [ -z "$variable" ]; oder ähnlich)

Mein Endziel wäre es, den read-Befehl zu unterdrücken, die Variable(n) zuzuweisen ohne dass ich den Namen der Variable(n) kenne, ich weiß nur, der wievielte read-Befehl es ist.

Tja, dann musst Du nur verraten, woher das arme Programm wissen soll, welche Variable geschrieben werden soll ...
Oder anders ausgedrückt: irgendeine Schnittstelle musst Du ihm schon anbieten, sonst geht es nicht.

Und wenn halt die reads die unverrückbare Vorgabe sind, dann musst Du eben über eine Pipe oder notfalls sogar mit expect ihm die Tastaureingaben simulieren.

Wie gesagt: Du musst mal klar beschreiben, welches die Vorgaben sind, sonst reden wir hier noch monatelang um de Brei herum, und wissen nicht einmal, ob es den Brei überhaupt gibt .... 🐸

LG,

track

KeyzerSoze

(Themenstarter)

Anmeldungsdatum:
28. September 2014

Beiträge: 120

Hallo,

danke, das funktioniert schon mal: track

Ok, dann musst Du das machen: z.B. indem Du die betreffende Variable in Deinem hallo-Skript vorher abfragst. ( if [ -z "$variable" ]; oder ähnlich)

Bezüglich:

Mein Endziel wäre es, den read-Befehl zu unterdrücken, die Variable(n) zuzuweisen ohne dass ich den Namen der Variable(n) kenne, ich weiß nur, der wievielte read-Befehl es ist. (als Beispiel könnte ein .sh-Programm dienen, bei dem ich keine Lese- und Schreibe, sondern nur Ausführrechte besitze)

Tja, dann musst Du nur verraten, woher das arme Programm wissen soll, welche Variable geschrieben werden soll ... Oder anders ausgedrückt: irgendeine Schnittstelle musst Du ihm schon anbieten, sonst geht es nicht. Wie gesagt: Du musst mal klar beschreiben, welches die Vorgaben sind, sonst reden wir hier noch monatelang um de Brei herum, und wissen nicht einmal, ob es den Brei überhaupt gibt .... 🐸

Alles was ich weiß ist folgendes:

  • Ich führe ein Programm aus (auf dessen Quellcode ich keinen Zugriff habe).

  • Ich weiß, dass ich von dem Programm (Skript) insgesamt 2 Mal abgefragt werde, jedesmal wird eine Zahl gefragt

  • Ich möchte also folgendes bsw. eingeben: beim ersten Input "100000", beim zweiten "0"

  • Die Schnittstelle ist meiner Meinung die Reihenfolge des Inputkommandos (read), Eingabe 1 ist Variable 1, Eingabe 2 ist Variable 2

Also ich würde jetzt nicht das Programm (Skript) an sich ändern, sondern eher bei Ausführen des Skriptes einen automatischen Input der Zahlen "100000" bzw. "0" erzeugen. Aber expect sieht schon mal richtig gut aus ☺ Ich schaue mir das morgen genauer an ☺

Vielen Dank && viele Grüße

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

KeyzerSoze schrieb:

  • Ich führe ein Programm aus (auf dessen Quellcode ich keinen Zugriff habe).

  • Ich weiß, dass ich von dem Programm (Skript) insgesamt 2 Mal abgefragt werde, jedesmal wird eine Zahl gefragt

Wenn das Programm ein Skript ist, dann hast Du auch Zugriff auf den Quellcode: ein Skript ist sein Quellcode.
Also könntest Du dort auch einfach de beiden read Befehle durch feste Variablen-Zuweisungen ersetzen. Könntest ...

  • Ich möchte also folgendes bsw. eingeben: beim ersten Input "100000", beim zweiten "0"

  • Die Schnittstelle ist meiner Meinung die Reihenfolge des Inputkommandos (read), Eingabe 1 ist Variable 1, Eingabe 2 ist Variable 2

Solche Eingaben gehen praktisch immer über die Standard-Eingabe /dev/stdin (das ist die Grund-Schnittstelle im Terminal)

Also ich würde jetzt nicht das Programm (Skript) an sich ändern, sondern eher bei Ausführen des Skriptes einen automatischen Input der Zahlen "100000" bzw. "0" erzeugen.

Also mit Hilfe einer Pipe o.ä. einspeisen:

1
2
echo -e "100000\n0"  |  deins_kript                # oder alternativ, ohne Pipe:
dein_skript  < <( echo -e "100000\n0" )

Aber expect sieht schon mal richtig gut aus ☺ Ich schaue mir das morgen genauer an ☺

... wäre hier aber wahrscheinlich overkill. Es sei denn, Du müsstest auf eine bestimmte Ausgabe Deines Skripts speziell reagieren.

LG,

track

KeyzerSoze

(Themenstarter)

Anmeldungsdatum:
28. September 2014

Beiträge: 120

Hallo track,

super, vielen Dank, das ist genau das, was ich gesucht habe!

Schönen Abend noch ☺

Antworten |