ubuntuusers.de

Leerstellen und Anführungsstriche

Status: Gelöst | Ubuntu-Version: Xubuntu 10.04 (Lucid Lynx)
Antworten |

Relationalist

Anmeldungsdatum:
17. Juni 2008

Beiträge: 1136

Hallo.

Ich übergebe hiermit:

1
2
3
4
5
6
7
8
#!/bin/bash
#clicompanion-umgebungsvariablen
echo "Hier die Variable 1 beschreiben, die es zu definieren gilt. "
echo -n "name: "
read var
read -p "wert: " val
echo $var >/tmp/var.value
echo $val >/tmp/val.value

Variablen an diese Definition:

1
export "$(cat /tmp/var.value)"="$(cat /tmp/val.value)"

Für "Wert" sollen ganze Bash-Befehle mit Argumenten eingesetzt werden können, also auch mit Leerstellen. Ich habe aber hier Shell/Bash-Skripting-Guide für Anfänger (Abschnitt „Variablen-belegen“) gelesen, daß man da Anführungszeichen beachten muß. Wo genau gehören die jetzt hin? In einem Testlauf ging es glatt durch:

echo $ab
1 2

danke! ☺

Keba Team-Icon

Ehemalige
Avatar von Keba

Anmeldungsdatum:
24. Juli 2007

Beiträge: 3802

Hallo,

Ich habe zwar nicht die geringste Ahnung was das Skript bringen soll, da es überhaupt keine Zeitersparnis liefert, vermute daher du hast das „nur so aus Interesse“ oder „zum Lernen“ geschrieben?

Relationalist schrieb:

Variablen an diese Definition:

export "$(cat /tmp/var.value)"="$(cat /tmp/val.value)"

Ich habe aber hier Shell/Bash-Skripting-Guide für Anfänger (Abschnitt „Variablen-belegen“) gelesen, daß man da Anführungszeichen beachten muß. Wo genau gehören die jetzt hin?

Du hast da doch bereits Anführungszeichen drin? Wobei die ersten überflüssig sind, wenn nicht gar falsch, das weiß ich nicht. An sich sollte man übrigens Leerzeichen in Dateinamen vermeiden, unter anderem aus solchen Gründen, aber das ist natürlich nicht das Thema.

In einem Testlauf ging es glatt durch:

Der Testlauf ist nicht nachvollziehbar, was hast du genau gemacht?

Grüße, Keba.

theinlein

Anmeldungsdatum:
29. Dezember 2007

Beiträge: 1279

Dein Script ist etwas verkünstelt. Ich vermute es löst dein Problem nicht.

Egal wie du was an 'export' übergibst, die Wirkung besteht solange, solange die Shell lebt, die es definiert. Die Definition ist sichtbar in dieser Umgebung (also im Prozess der dein Script ausführt und dessen Kindprozesse) Sobald dein Script, das export aufruft, beendet wird, ist das, was du darin mit export festgelegt hast, nicht mehr sichtbar, d.h. für andere nicht mehr greifbar (außer für die noch lebenden Kinder, denen die Werte in deren Umgebung geschrieben wurde)

Relationalist

(Themenstarter)

Anmeldungsdatum:
17. Juni 2008

Beiträge: 1136

Danke.

Nur weil Du gefragt hast: Der Sinn ist, bereits vor Start einer Befehlskette Umgebungsvariablen in ihr verändern zu können - in speziellen Skripten nur dafür - diese Skripte aber bei Bedarf auch erst in der Befehlskette ausfüllen zu können, - nur daß die dann gesetzten Variablen bestehen bleiben müssen und nicht mit Ende des Skriptes verschwinden dürfen, weil sie sonst für die Befehlskette futsch sind.

Der Test:

erst das skript:

name: ab

wert: 1 2  # hier ist das Leerzeichen

dann den unteren Befehl ... (da sieht man nichts)

dann die Variable ab ausgelesen.

echo $ab

Ausgabe: 1 2 

D.h. ab und "1 2" sind verknüpft, obwohl das Skript, in dem sie definiert wurden, weg ist. Somit ist keine Vererbung ("kindprozeß") nötig, um die Definition der Umgebungsvariable zu erhalten.

Die Leerzeichen sollen möglich sein, damit als "Variablen" an manchen Stellen Zeichenfolgen in einen bestehenden, gespeicherten Befehl reingedingst werden können, welche gleichlautend mit Bash-Befehlen sind und daher mit "eval" wieder zu Befehlen werden können:

name: ab

wert: sudo apt-get autoremove # irgendein Beispiel nur ...

Jetzt kommt's:

eval $ab

und "sudo apt-get autoremove" startet.

Damit soll innerhalb von Befehlen und Befehlsmustern (einzeiligen Skripten) in einem Archiv wie in einem Baukasten herumgebaut werden können. ...

tut mir leid, wenn ich mich unverständlich ausdrücken sollte, bin hierin Anfänger 😳

Relationalist

(Themenstarter)

Anmeldungsdatum:
17. Juni 2008

Beiträge: 1136

theinlein schrieb:

Sobald dein Script, das export aufruft, beendet wird,

Genau das tut es ja nicht. Der export-Teil steht woanders, nämlich im Befehl, und kommt erst, wenn das Skript schon tot ist.

so etwa (verkürzt):

codecodecode ... && sh wurschtelskript.sh && export "$(cat /tmp/var.value)"="$(cat /tmp/val.value)" && ... codecodecode

Danke. 😉

Keba Team-Icon

Ehemalige
Avatar von Keba

Anmeldungsdatum:
24. Juli 2007

Beiträge: 3802

Ahh, verstehe nun so halbwegs was du vorhast… Die Betonung liegt allerdings auf halbwegs.

Warum brauchst du dafür zwei Dateien, eine Datei mit deinem Einzeiler dürfte doch reichen?

Auf jeden Fall ist das eine sehr unschöne Methode, ja, es geht. Aber das geht unter Garantie schöner, z. B. im dem du deinen Einzeiler als Parameter übergibst. Um genaue Tipps geben zu können, musst du uns aber schon konkret verraten was du vorhast. Etwas weniger allgemein, bitte.

Grüße, Keba.

Relationalist

(Themenstarter)

Anmeldungsdatum:
17. Juni 2008

Beiträge: 1136

Danke für das Interesse.

Ich möchte damit ein Programm, welches es noch gar nicht richtg gibt, pervers 😈 😈 😈 über die Grenzen seiner vorgesehenen Möglichkeiten hinaus verwenden.

Guckstu hier: Baustelle/CLI Companion (Abschnitt „Umgebungsvariablen“)

riffraff

Avatar von riffraff

Anmeldungsdatum:
1. Oktober 2006

Beiträge: 486

Wohnort: Im kühlen Norden

So richtig verstehe ich den Ansatz zwar hier nicht... aber ich denke Du könntest ja auch Deine Variablen und deren Werte in die Datei schreiben und dann später einfach "sourcen". Dann sind sie ja gesetzt.

1
man source

Desweiteren könnte man zumindest eine Variable setzen indem man den cat-Befehl mit eval laufen läasst

1
eval $(cat /tmp/var.value)=VARIABLENWERT

Dann wäre der Inhalt der Datei als Variable selbst auf den Wert "VARIABLENWERT" gesetzt

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Relationalist schrieb:

... Anführungszeichen beachten ... Wo genau gehören die jetzt hin?

Hier:

#!/bin/bash
#clicompanion-umgebungsvariablen
echo "Hier die Variable 1 beschreiben, die es zu definieren gilt. "
echo -n "name: "
read var
read -p "wert: " val
echo "$var"  >  /tmp/var.value
echo "$val"  >  /tmp/val.value

Lies mal in der Orignalquelle: http://www.gnu.org/software/bash/manual/bash.html#Quoting und in Greg's Bash Practices
(beachte: ".." wenn Variablen eingesetzt werden sollen, '..' wenn nicht.)

Und Vorsicht mit eval ... frei eingegeben Variablen auszuführen ist eine der tückischsten Methoden um Hintertüren einzubauen. 😬

LG,

track

Relationalist

(Themenstarter)

Anmeldungsdatum:
17. Juni 2008

Beiträge: 1136

Danke Euch.

Greg's Bash Practices ist ja schön geschrieben! ...

Mir wurden noch andere Ideen genannt, einen Variablenwert zum Befehl zu machen, aber auch ich hab' mich für eval entschieden. Vielleicht auch nur, weil es so schön klingt und so einfach zu schreiben ist ... 😬

Gute Nacht allerseits!

Relationalist

(Themenstarter)

Anmeldungsdatum:
17. Juni 2008

Beiträge: 1136

Keba schrieb:

Aber das geht unter Garantie schöner, z. B. im dem du deinen Einzeiler als Parameter übergibst.

... so wie hier etwa?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!/bin/bash
#clicompanion-umgebungsvariablen
echo "Hier die Variable 1 beschreiben, die es zu definieren gilt"
echo -n "name: "
read var
# ==
read -p "wert: " val
# ==
defvar="$var=$val"
# ==
vardef="export $(echo $defvar)"
# ==
echo $vardef > /tmp/vardef.value

... und das gelingt nicht, weil export das Leerzeichen in val nicht versteht. 😲 ... und weil ich val oder defvar nicht wörtlich mit "" mitgeben kann, denn der Einzeiler ist selbst bereits wörtlich und gibt die Inhalte mitsamt "" einfach nur wörtlich wieder. 😲 😲

So viel mit Vorbehalt von einem, der nichts vom Programmieren versteht 😬

Danke trotzdem für die Anregung. Vielleicht mache ich's ja einfach nicht richtig ...

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Also, vergiss mal das export würde ich sagen.
(das brauchst Du, wenn Du eine selbstdefinierte Variable für Unterprogramme in Deinem Skript zugänglich machen willst, sonst nicht)

Aber die Sache mit dem Einzeiler hat schon was.
So ähnlich habe ich es mit einer Parameterdatei bei einigen größeren Skripten gemacht:

#!/bin/bash

if [ -e "meinscript.ini" ] ; then
        echo -n "Gib bitte die Variable ein:  "
          ## dies ist gefährlich, denn hier könnte der unbedarfte User sonstwas ausführen !!
          ## (man muss also bei einem "echten" Skript die Eingabe auf jeden Fall sorgfältig auf böse Fallen abprüfen)
          ##  ... ich tue es hier trotzdem mal ungeschützt:
        read -r var
        echo -n "Gib bitte den Wert dazu ein: "
        read -r val
        echo "$var=\"$val\""  >  meinscript.ini

        $var="$val"
else
        . meinscript.ini
fi

## jetzt ist in jedem Fall die Variable "$var" mit dem Wert "$val" gesetzt.

Das Geheimnis liegt in dem ". " - das führt nämlich den Inhalt der nachfolgenden Datei in der Originalshell des Skripts aus !
(ohne Shebang und ohne "execute"-Recht ! ... guckstu hier: http://www.gnu.org/software/bash/manual/bash.html#Bourne-Shell-Builtins )

LG,

track

Relationalist

(Themenstarter)

Anmeldungsdatum:
17. Juni 2008

Beiträge: 1136

Danke, interessant!

wenn auch bei weitem noch nicht von mir verstanden, macht nix.

## (man muss also bei einem "echten" Skript die Eingaben auf jeden Fall auf böse Fallen abprüfen)

## wie macht man sowas? Nur so'n Tip ...?

Danke vom Anfänger.

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Relationalist schrieb:

## wie macht man sowas? Nur so'n Tip ...?

Das wird im Grunde etwas Fleißarbeit. Ich würde unbedingt nur (positiv) die erlaubten Dinge erlauben, sonst findet bestimmt irgend eine "kreative" Seele doch noch eine Lücke. Wenn z.B. "$val" nur eine Datei sein darf die auch existiert, dann könnte man das vielleicht so abfangen:

if ! [ -f "$val" ] ; then
        echo "Die Datei gibt es nicht: $val"  >  /dev/stderr
        echo "meinskript: Abbruch."  >  /dev/stderr
        exit 1
fi

Und je nach dem, was "$val" nun werden soll, natürlich sinngemäß entsprechend.

track

Antworten |