Anwendungen
Portal
Forum
Wiki
Ikhaya
Planet
Mehr
Anmelden

Problem mit der ksh, if und fi

Hallo,

seit Tagen geister ich schon im Web rum, weil ich vr einen Problem stehe. Ich möchte in einem Script eine Variabel einbauen, die wie als Schalter für verschiedene Funktionen gilt. Also: Wenn Datei existiert und nicht leer ist, -> dann variable=inhalt der datei, wenn nicht -> variable=false. Da das ganze Skript in ksh geschrieben ist, würde ich gerne diesen Schnipsel auch in der ksh schreiben.

Soweit bin ich schon:

1
2
3
4
#!/bin/ksh
variable=`cat temp.lck`
temp=${variable:-"false"} 
echo $temp

funktioniert auch soweit, bis die Datei nicht mehr vorhanden ist. Das Problem wollte ich ganz einfach mit if, else, fi lösen

1
2
3
4
5
6
7
#!/bin/ksh
if [ -e temp.lck ]; then
    variable=`cat temp.lck`
    temp=${variable:-"false"}
else
    temp="false"
fi

Jetzt gibt er mir aber aus.

1
syntax error at line 7: `fi' unexpected

Hat irgendjemand ne Idee, worans liegen könnte???

Hi FabiUnne,

willkommen hier auf dem Forum !

Da ich im Moment keine ksh hatte, habe ich die Geschichte mal mit der dash ausprobiert, und selbst da geht sie:

track@lucid:~$ sh
$ var=`cat dienst211.txt`
$ var=${var:-false}; echo "$var"
Dienste 3/2011:
1.05.2011
$ var=`cat dienst211.xt`
cat: dienst211.xt: Datei oder Verzeichnis nicht gefunden
$ var=${var:-false}; echo "$var"
false 

Grundsätzlich ist da also nichts verkehrt.

Bei Dir habe ich 2 Fußangeln in Verdacht:
1. Wie rufst Du das Skript auf ? - hast Du es "ausführbar" gemacht, und gibst dann ./meinskript ein, oder womöglich anders ?
2. Hast Du womöglich das Skript mit Win...-Zeilenenden geschrieben ? (mit welchem Editor ?) - dann erkennt die Shell nämlich praktisch keinen Befehl mehr.

Sowas ähnliches hatten wir gestern gerade erst hier: http://forum.ubuntuusers.de/topic/bash-skript-syntaxfehler-bei-if-abfrage/

track

Servus,

ich hab’s mit der pdksh ausprobiert (einzige ksh, die ich schnell zur Hand hatte) und da funktioniert es auch. Mein ksh-Halbwissen sieht den Fehler auf dem Papier auch nicht.

Setz’ doch mal ein

set -x

ganz an den Anfang (sofern deine ksh das kennt – die pdksh tut es), vielleicht sieht man in der Debug-Ausgabe etwas. Sofern er so weit kommt.

Ein Schuss ins Dunkle: ich würde mal die Variable quoten in Zeile 4:

1
    temp="${variable:-"false"}"

Ciao

robert

Danke für die echt schnellen Antworten. Nach 2 Tagen Überlegung hatte ich dann doch endlich die Idee den Codeblock direkt im Termial mit nano zu schreiben, und siehe da: Es geht. Ich denke, dass mein Problem einfach war, dass Notepad++ (mein Windows-Editor) wahrscheinlich etwas falsch hinterlegt hatte. Auf jeden Fall funktioniert jetzt das, was ich erreichen wollte. Stellt sich doch die große Frage, was Notepad++ macht, was es nicht darf. Aber egal jetzt gehts auf jeden Fall.

Lösungsansatz war wirklich, den Käse direkt in der Shell zu programmieren.(Mit nano, oder vergleichbaren)

Wen's interessiert: Ich schreibe gerade ein Gameserverscript, in dem ich jetzt eine Auto-Aufsetzung programmieren will, also ich werde im Dialog alles abgefragt, und das Script baut mir ein Server. Ist ganz cool, doch irgendwie muss das Script nach einem Neustart wissen, wie jetzt noch gleich der aufgesetzte Server heißt. Das wollte ich mit dem Codebeispiel machen.

Trotzdem die Antworten auf eure Fragen/Anregungen: @track:

1. Wie rufst Du das Skript auf ? - hast Du es "ausführbar" gemacht, und gibst dann ./meinskript ein, oder womöglich anders ?

Ich kann das Script sowohl mit ./script.sh, als auch mit ksh script.sh ausführen, da ich als Interpreter "#!/bin/ksh" angegeben habe. Übern chmod stehen die Berechtigungen auf 777.

2. Hast Du womöglich das Skript mit Win...-Zeilenenden geschrieben ? (mit welchem Editor ?) - dann erkennt die Shell nämlich praktisch keinen Befehl mehr.

Geschrieben wie gesagt mit Notepad++. Hatte nie Probleme mit. Das mit dem "erkennt [...] keinen Befehl mehr" kann ich nur etwas nachvollziehen, da die Zeilen in der Debug richtig waren.

@rklm

1
temp="${variable:-"false"}"

Jo, das Problem ist dann nur, dass das Quoten vor false aufhört. Alles, was vielleicht geht, ist:

1
2
3
4
# ENDWEDER:
temp="${variable:-'false'}"
# ODER:
temp="${variable:-false}"
$ script.ksh
false
$ ls 
script.ksh  temp.lck.ver
$ mv temp.lck.ver temp.lck
$ script.ksh
dies ist der Inhalt dies ist der Inhalt
$ cat script.ksh temp.lck
#!/bin/ksh
if [ -e temp.lck ]; then
    variable=`cat temp.lck`
    temp=${variable:-false}
    echo $variable $temp
else
    temp="false"
    echo $variable $temp
fi

dies
ist 
der 
Inhalt
$ ksh --version
  version         sh (AT&T Research) 93t+ 2010-06-21

Ich tip auch auf Windowszeilenende.

FabiUnne schrieb:

Geschrieben wie gesagt mit Notepad++. Hatte nie Probleme mit. Das mit dem "erkennt [...] keinen Befehl mehr" kann ich nur etwas nachvollziehen, da die Zeilen in der Debug richtig waren.

Das Problem ist, dass Win...- Editoren den Zeilenwechsel immer mit \r\n (= x0D0A ) schreiben, aber *nix nur \n (= x0D) verwendet. Der Rücklauf ist dann ein ganz normaler Buchstabe, der zusätzlich am Ende jeder Zeile steht.
-> Guck mal in den oben von mir verlinkten Parallelthread, das war genau das selbe (und dort stehen auch noch mehr Lösungen für das Problem) !

LG,

track

FabiUnne schrieb:

Ich kann das Script sowohl mit ./script.sh, als auch mit ksh script.sh ausführen, da ich als Interpreter "#!/bin/ksh" angegeben habe. Übern chmod stehen die Berechtigungen auf 777.

JEDER darf die Datei ändern - willst Du das wirklich?

MfG

naja, mit JEDER beziehst du dich nur auf mich. Ich beschreibe im Moment mein Offline-Testserver, der auf meinem Netbook 3 Meter weiter läuft. Später kann natürlich nicht JEDER das Script ausfürhen. Aber hier machts ja keinen Unterschied :D

FabiUnne schrieb:

Jo, das Problem ist dann nur, dass das Quoten vor false aufhört.

Pardon, ich hatte vergessen, die inneren Quotes zu entfernen. Das sollte so aussehen, wie in Deinem letzten Beispiel:

1
temp="${variable:-false}"

Der String "false" muss ja nicht gequoted werden. Selbst, wenn dort eine Variable steht, muss man nicht nochmal quoten:

1
2
3
4
5
6
7
8
$ a='X}'
$ unset b
$ echo "<${b}>"
<>
$ echo "<${b:-$a}>"
<X}>
$ echo ${b:-$a}
X}

Deine ursprüngliche Logik würde ich aber anders bauen:

1
2
3
4
5
6
7
unset var

if [ -r temp.lck ] && var=$(<temp.lck) && [ -n "$var" ]; then
  echo "Wir machen was mit $var"
else
  echo "nuescht jefunden"
fi

Man kann in der bash "$(<datei)" statt cat verwenden, was einen Prozess spart.

Ciao

robert

rklm schrieb:

Pardon, ich hatte vergessen, die inneren Quotes zu entfernen. Das sollte so aussehen, wie in Deinem letzten Beispiel:

1
temp="${variable:-false}"

Überhaupt muss hier überhaupt nichts gequotet werden, wie ich hier oben schon nachgewiesen hatte ...!
Jedenfalls, solange in der Zeile kein Leerzeichen auftaucht.

Vielleicht hat user unknown hier ja doch Recht mit seiner pädagogischen Methode ?

Sonst bin ich ja auch eher für "praktische Gewohnheiten", aber hier verweigere ich mich der Urban Legend dann doch ...

LG,

track

da ich seit Jahren VB.net programmiere und seit einem Jahr Java, hab ich das Qouten einfach übernommen. Klar, ist es da nicht wichtig, gar unnötig, doch bin ich es irgendwie gewohnt, zu qouten. Deswegen werde ich es weiter machen. Ich qoute aber grundsätzlich nur, wenn ich irgendwo Strings, also Zeichenketten habe. Jeden dem seinen.

FabiUnne schrieb:

[...] Ich denke, dass mein Problem einfach war, dass Notepad++ (mein Windows-Editor) wahrscheinlich etwas falsch hinterlegt hatte.

Du kannst im Menü die Kodierung der Datei einstellen. Da solltest du UTF-8 auswählen. (Siehe Screenshot im Anhang)

kann ich nur halb teilen.

DOS: \r\n UNIX: \n

Stell einfach in deinen N++ Einstellungen unter Dateien -> Neu Datei/Format auf UNIX um. Mit der Kodierung hat das nicht zwangsläufig was zu tun.