Diese Website existiert nur weil wir Werbung mit AdSense ausliefern.
Bitte den AdBlocker daher auf dieser Website ausschalten! Danke.

[solved] Bash: Skript mit Variablen-Problem

Alles rund um die verschiedenen Konsolen und shells sowie die Programmierung unter Linux

Moderator: Moderatoren

Antworten
Benutzeravatar
Ricardo
Newbie
Newbie
Beiträge: 20
Registriert: 17. Mär 2004, 10:26
Wohnort: Karlsruhe-Durlach
Kontaktdaten:

[solved] Bash: Skript mit Variablen-Problem

Beitrag von Ricardo »

hallo leute,

ich hab da ein riesen-problem mit einem skript bzw. mit der bash-syntax und zwar möchte ich als übergabeparameter ($1) eine variable angeben die im skript existiert und deren inhalt dann benutzt werden soll. das ganze besteht aus 2 teilen, einmal die serverliste und einmal das ausführungsskript. das skript sieht folgendermaßen aus:
# Server-Liste
source ~/serverlist

# Unterscheidung & Verbindungsteil
if [ ! $1 ]
then
echo "Unsupported Usage."
else
ssh $[$1]
fi

exit 0
die liste sieht so aus:
meinserver1='server1.domain.de'
meinserver2='server2.domain.de'
meinserver3='server3.domain.de'
wenn ich nun aber das skript aufrufe mit ./skriptname meinserver1, so kommt bei mir aber ständig die fehlermeldung:
server1.domain.de: expression recursion level exceeded (error token is "server1.domain.de")

kann mir da jemand weiterhelfen?

rgds,
ricardo
Benutzeravatar
Ricardo
Newbie
Newbie
Beiträge: 20
Registriert: 17. Mär 2004, 10:26
Wohnort: Karlsruhe-Durlach
Kontaktdaten:

Beitrag von Ricardo »

ich hab übrigens rausgefunden das ich mit $(($1)) die richtige ausgabe bekomme, nur dann erhalte ich wieder:

server1.domain.de: expression recursion level exceeded (error token is "server1.domain.de")

hilfe!
trooperle
Newbie
Newbie
Beiträge: 40
Registriert: 10. Mär 2004, 15:51
Wohnort: Bonn

Beitrag von trooperle »

Tach mal wieder,

erstmal führe das Skript mit
bash -x <skriptname> aus oder oben in der ersten Zeile
#!/bin/bash -x

damit erzeugst du debug-output, evtl hilft dir das schon weiter.

Zum anderen
[ ! $1 ] soll vermutlich bewirken, daß du prüfst ob ein Argument mit übergeben wurde. Versuch es besser mal mit

if [ -z "$1" ]
then
...

( zero-length, daher das z )
damit prüfst du, ob der String "$1" leer ist. ist dies der fall, wird der then zweig, sonst der else-zweig ausgeführt.
mit -n "$1" prüfst du, ob der String nicht leer ist ( non-zero length )

Dei Anführungsstriche sind wichtig, sind die nicht gesetzt, kommt es schonmal zu fehlern.

Hoffe Dir damit geholfen zu haben

Trooperle
P.S: Versuch's mal mit "man test" oder "man bash", da findet man viele nützliche vergleichsoperatoren etc. Du kannst den Befehl test oder einfach [ <ausdruck> ] verwenden, die sind äquivlent
Gast

Beitrag von Gast »

hm also das klappt leider nicht... bzw. es bringt keine verbesserung!

ich erhalte immernoch "skriptname: line 13: server1.domain.de: expression recursion level exceeded (error token is "server1.domain.de")

übrigens hatte ! $1 funktioniert, was mich als c++'ler sehr gefreut hat :P

hatte ich schon erwähnt das die bash-syntax die pure folter is? *G*

rgds,
ricardo
Benutzeravatar
Ricardo
Newbie
Newbie
Beiträge: 20
Registriert: 17. Mär 2004, 10:26
Wohnort: Karlsruhe-Durlach
Kontaktdaten:

Beitrag von Ricardo »

hmpf, sorry war nicht eingeloggt!

rgds,
ricardo
Das Produkt wird zur Zeit in unserem Quality Assurance Center auf Herz und Nieren geprüft.
zu deutsch:
Seit zwei Monaten haben wir keine Version mehr, der länger als fünf Minuten läuft ohne abzustürzen, und unser Oberguru hat gekündigt.
trooperle
Newbie
Newbie
Beiträge: 40
Registriert: 10. Mär 2004, 15:51
Wohnort: Bonn

Beitrag von trooperle »

Sicher das das funktioniert? Welche Zeile ist denn Zeile 13?
Wie gesagt, probier es mal mit bash -x <skriptname>
Der Output ist gewöhnungsbedürftig, aber als C++'ler solltest Du ja undurchsitigen Code und Debugging gewohnt sein :lol:

Trooperle
Benutzeravatar
Ricardo
Newbie
Newbie
Beiträge: 20
Registriert: 17. Mär 2004, 10:26
Wohnort: Karlsruhe-Durlach
Kontaktdaten:

Beitrag von Ricardo »

trooperle hat geschrieben:Sicher das das funktioniert? Welche Zeile ist denn Zeile 13?
Wie gesagt, probier es mal mit bash -x <skriptname>
Der Output ist gewöhnungsbedürftig, aber als C++'ler solltest Du ja undurchsitigen Code und Debugging gewohnt sein :lol:
;) könnte man sagen japp

bash -x skriptname führte ja zu eben dem output... ohne irgendwie hilfreich zu sein leider

das problem ist die var! eben ssh $[$1] bzw. ssh $(($1))... beides führt dazu das er wohl den zugewiesenen wert erkennt aber er kann ihn nicht benutzen oder versucht ihn auszuführen oder wat weiß der geier...

rgds,
ricardo
Das Produkt wird zur Zeit in unserem Quality Assurance Center auf Herz und Nieren geprüft.
zu deutsch:
Seit zwei Monaten haben wir keine Version mehr, der länger als fünf Minuten läuft ohne abzustürzen, und unser Oberguru hat gekündigt.
Benutzeravatar
nobbiew
Hacker
Hacker
Beiträge: 497
Registriert: 1. Mär 2004, 23:26

Beitrag von nobbiew »

Folgendes sollte gehen

Code: Alles auswählen

# Server-Liste 
source ~/serverlist 
 
# Unterscheidung & Verbindungsteil 
if [ ! $1 ] 
then 
 echo "Unsupported Usage." 
else 
eval ssh \$$1 
fi 
 
exit 0
Dein Problem liegt daran, dass die bash die Variablenevaluierung nur einmal macht. Mit eval bringst du ihn dazu, dass er nachdem er $1 evaluiert hat, das Ergebnis noch einmal evaluert. Du mit mit \$ jedoch verhindern, dass beim 1. mal das $$ als Prozessid interpretiert wird. Gilt übrigens für nahezu alle shell's.
Benutzeravatar
nobbiew
Hacker
Hacker
Beiträge: 497
Registriert: 1. Mär 2004, 23:26

Beitrag von nobbiew »

Da fällt mir noch was tückisches ein.

Falls du die Befehlszeile erweiterst und z.B. shell-variablen vom remote-Rechner verwenden willst, musst du ebenfalls darauf achten, dass die das $ mit \$ quotest, Sonst wird die variable lokal ausgewertet.
Benutzeravatar
Ricardo
Newbie
Newbie
Beiträge: 20
Registriert: 17. Mär 2004, 10:26
Wohnort: Karlsruhe-Durlach
Kontaktdaten:

Beitrag von Ricardo »

hmm, also wenn ich das 1-zu-1 übernehme klappt das nicht. ich hab auch verschiedene andere kombinationen probiert wie z.b.
eval `ssh \$$1`
oder
eval "ssh \$$1"
...

aber nix davon hat was gebracht. bei der 1-zu-1 kopie von deinem sourcecode hat sich sogar der ssh-interpreter mit der hilfeseite gemeldet die kommt wenn man einfach "ssh" eingibt an der shell...

rgds,
ricardo
Das Produkt wird zur Zeit in unserem Quality Assurance Center auf Herz und Nieren geprüft.
zu deutsch:
Seit zwei Monaten haben wir keine Version mehr, der länger als fünf Minuten läuft ohne abzustürzen, und unser Oberguru hat gekündigt.
Benutzeravatar
nobbiew
Hacker
Hacker
Beiträge: 497
Registriert: 1. Mär 2004, 23:26

Beitrag von nobbiew »

Versuchs mal damit

Code: Alles auswählen

#!/bin/bash

# Server-Liste 
 source ~/serverlist 
   
 # Unterscheidung & Verbindungsteil 
 if [ ! $1 ] 
 then 
  echo "Unsupported Usage." 
 else 
 eval ssh \$$1 
 fi 
   
 exit 0
#!/bin/bash muss in der 1. Zeile stehen u. dahinter dürfen keine anderen Zeichen, auch nicht Leerzeichen kommen
Benutzeravatar
Ricardo
Newbie
Newbie
Beiträge: 20
Registriert: 17. Mär 2004, 10:26
Wohnort: Karlsruhe-Durlach
Kontaktdaten:

Beitrag von Ricardo »

heureka! genau das wars! oh maaaaaann... das is echt traurig...

(und ich hab mich immer gewundert was der kommentar in der ersten zeile zu suchen hat :D )

rgds,
ricardo
Das Produkt wird zur Zeit in unserem Quality Assurance Center auf Herz und Nieren geprüft.
zu deutsch:
Seit zwei Monaten haben wir keine Version mehr, der länger als fünf Minuten läuft ohne abzustürzen, und unser Oberguru hat gekündigt.
Benutzeravatar
nobbiew
Hacker
Hacker
Beiträge: 497
Registriert: 1. Mär 2004, 23:26

Beitrag von nobbiew »

Das ist die sog. shebang-Zeile (leg mich nicht auf die schreibweise fest)
muss immer in der 1. Zeile stehen
beginnt immer mit #!Programm
Programm steht für die shell o. interpreter (z.B. /usr/bin/perl), das das folgende Skript auswerten soll. Danach dürfen noch parameter zum programmaufruf des Interpreters kommen, aber keine Kommentare mehr, da alles nach dem #! bis zum Zeilenende als Programmaufruf verstanden wird.

Häufige shebang-Zeilen:
#!/usr/bin/perl -w
#!/bin/bash
#!/bin/bash -x

Was immer wieder tückisch ist, sind Textdateien, die von Windows kommen, da die als Zeilenende CrLf und nicht Lf wie die Unix-Derivate verwenden. Somit erkennt Linux das Zeilenende nicht richtig und es geht ebenfalls schief. Hier hilft das Kommando dos2unix, das solche Dateien Unix-konform umwandelt
Benutzeravatar
Ricardo
Newbie
Newbie
Beiträge: 20
Registriert: 17. Mär 2004, 10:26
Wohnort: Karlsruhe-Durlach
Kontaktdaten:

Beitrag von Ricardo »

ha! tausend dank, genau sowas hab ich gebraucht... hab nun zwar schon meine workstation auf linux umgerüstet mit windows in ner vmware machine aber für alle kollegen wird das 100%ig interessant :)

rgds,
ricardo
Das Produkt wird zur Zeit in unserem Quality Assurance Center auf Herz und Nieren geprüft.
zu deutsch:
Seit zwei Monaten haben wir keine Version mehr, der länger als fünf Minuten läuft ohne abzustürzen, und unser Oberguru hat gekündigt.
Loci

Beitrag von Loci »

das shebang (jap, so wirds geschrieben @ nobbiew) brauch man nur, wenn das script mit einem anderen interpreter ausgeführt werden soll als man es aufruft, wenn man beispielsweise ein für bash geschriebenes script hat, das in der bash ausgeführt wird brauch man es nicht, schaden kanns aber auch nicht... wenn du aber einen interpreter angibst den es nicht gibt funzt in den meisten fällen gar nix...

#!/bin/sh funzt immer da sie bei einem "normalen" unix/linux immer da ist, allerdings ist der scriptstil anders und seeeehr gewöhnungsbedürftig, außer man kann c :D :D

mit set -x kannst du auch den debug anstellen.... dann brauchst du es später nur auskommentieren wenn du es nicht mehr brauchst...
Benutzeravatar
Ricardo
Newbie
Newbie
Beiträge: 20
Registriert: 17. Mär 2004, 10:26
Wohnort: Karlsruhe-Durlach
Kontaktdaten:

Beitrag von Ricardo »

also c ist nicht das problem, ist weniger umfangreich als c++ ;)
Das Produkt wird zur Zeit in unserem Quality Assurance Center auf Herz und Nieren geprüft.
zu deutsch:
Seit zwei Monaten haben wir keine Version mehr, der länger als fünf Minuten läuft ohne abzustürzen, und unser Oberguru hat gekündigt.
Benutzeravatar
nobbiew
Hacker
Hacker
Beiträge: 497
Registriert: 1. Mär 2004, 23:26

Beitrag von nobbiew »

Hallo Loci,
das mag im speziellen Fall bei aufruf unter einer Benutzerkennung so sein. Wenn du dann allerdings versuchst so ein Skript beim hochfahren laufen zu lassen, fällst du damit auf die Nase. Deshalb sollte man die Shebang-Zeile immer setzen. Die ist z.B. auch für den Apache wichtig, wenn du keinen speziellen Handler im Verzeichnis oder auf die Endung gesetzt hast.
Antworten