[linux-l] Logik von "Syntax-Fehler" in Bash

Lutz Willek lutz.willek at belug.de
Fr Dez 27 17:11:52 CET 2013


hey

Am 2013-12-27 15:32, schrieb Hasko Bern:
> Also beide folgenden Ansätze funktionieren:
> 
> $ sudo bash -c 'for i in 1 2 3 4 5; do hdparm -tT /dev/sda; done'
> 
> Ebenso:
> 
> $ for i in 1 2 3 4 5; do sudo hdparm -tT /dev/sda; done

Natürlich.(^1) "Funktioniert wie beschrieben" wäre passend.

> Sprich:
> 
> - Der Befehl hdparm ist im Suchpfad eines "normalen" Benutzers

Das kommt auf die Distribution an und ist hier in dem Kontext auch 
völlig egal.

> - Anscheinend kann sudo mit Zeilenumbrüchen à la ';' umgehen, sonst 
> dürfte
> der zweite Ansatz nicht funktionieren.

Quatsch. Grusel!

> Hauke hat neben einer Erklärung, wieso meine Herangehensweise nicht
> erfolgreich war, AUCH eine Lösung geliefert - wollte ich nur anmerken.

Hauke hat Dir einen Fisch(^2) gegeben! Das Problem dahinter hast Du 
scheinbar nicht verstanden, und die Leute die das Problem erklären 
wollen leider auch nicht.
Ich könnte jetzt schreiben rtfm oder "man bash", aber das kneife ich mir 
mal, weil die manpage der bash wirklich übelst lange ist, und wenn man 
nicht weiß wonach man sucht ists duster. Obwohl, eins der ersten 
Postings hat sogar die richtigen Stichwörter zum nachschlagen geliefert. 
Übrigens: Deine ursprüngliche Fehlermeldung hat das auch... Hier noch 
einmal der Verweis auf (^1)

Ein "sudo for i in 1 2 3 4 5 ; do befehl ;done" funktioniert deshalb 
nicht, weil

sudo befehl1; befehl2; befehl3

nicht das ist was Du willst, aber Du es so geschrieben hast (und die 
shell entgegen anderslautender Meldungen nicht intelligent ist) Daher 
die Hinweise der Mailingliste zu dem ";", und sich mal zu überlegen, wie 
das ohne dem Semikolon ausschauen würde.

Die anderen Hinweise in Richtung "simple  command" sind auch 
goldrichtig: Das erklärte Dir jemand auf andere Art, warum Dein Befehl 
so nicht funktionierte: ...is  a sequence of optional variable 
assignments followed by blank-separated words and redirections, and 
terminated by a control operator. Mach Dir nix draus, den Wink hat 
scheinbar nicht mal Hauke verstanden ;) Schade eigentlich.

Mit nur ein wenig Doku lesen erklärt sich auch die Fehlermeldung, weil 
"do" schlicht ein reserviertes Wort ist, das so nicht an dieser Stelle 
stehen darf:

sudo befehl1;
do befehl
-bash: Syntaxfehler beim unerwarteten Wort `do'

Und ich glaube auch dieser Hinweis kam hier schon einmal.

Die ganze Schleife hat damit nix zu tun, sondern ganz schlicht und 
ergreifend die korrekte Trennung der einzelnen Befehle zueinander. 
Deshalb funktioniert sudo bash -c "irgendwas; irgendwasanderes", also 
der Fisch den Hauke Dir zugeworfen hat, auch so wunderbar.

Passend zum Absatz oben, auch zur Fehlersuche funktioniert hätte ein 
"man sudo", dort steht:
...sudo allows a permitted user to execute a command as the superuser or 
another user...

Mal extra hervorgehoben: ...to execute *a* command...

Deshalb funktioniert auch der zweite Dir zugeworfene Filetstückchen so 
gut, weil ausgeschrieben trivia:
"sudo befehl ; sudo befehl; sudo befehl ; sudo befehl sudo befehl"

genau das ist was Du wolltest.



> Allerdings weiß ich immer noch nicht, wie man ganz konkret 
> Zeilenumbrüche
> in der Shell umsetzt:
> 
> also
> for i in 1 2 3 4 5
> do sudo hdparm -tT /dev/sda
> done

Versuche es doch einfach einmal mit <ENTER>, also der dicksten Taste auf 
der Tastatur, oft eher rechts zu finden. Weil das Kommando nach for... 
noch nicht beendet ist, wirst Du mit einem Zeichen belohnt, weil die 
shell erkennt, dass Dein Befehl nicht zu Ende ist.
Ich rücke das jetzt bewusst in dieser Mail mit den Zeichen "## " ein, 
weil Dein Problem ist glaube ich, dass das "Mailzitat" und "Befehl geht 
in shell weiter" das gleiche Zeichen ist, und Du das schlicht nicht 
erkannt hast. Tip: Der Webmailer der Belug macht das besser als google. 
*hust*(^3) Denke Dir also bitte "##" weg, dann siehst Du genau das, was 
auf dem Bildschirm steht:

## ... export PS1="user at host:~$ "
## user at host:~$
## user at host:~$ for i in 1 2 3 4 5
## > do
## > echo befehl in Schleife $i
## > done
## befehl in Schleife 1
## befehl in Schleife 2
## befehl in Schleife 3
## befehl in Schleife 4
## befehl in Schleife 5
## user at host:~$

Das Zeichen ">" gehört hier zur shell, nicht zur Maildarstellung!

Lies Dich doch einfach mal ein wenig zu "Quoting, Maskieren Bash" ein, 
dann wird das alles viel klarer. Zum Schluss also doch wieder der 
Hinweis auf die Manpages, sorry. Hoffe die Mail hilft fischen lernen.

Quellen:
^1: Suche mal nach Konfuzius und Fisch
^2: http://www.aphorismen.de/zitat/121457
^3: schamlose Eigenwerbung

-- 
Mit freundlichen Grüßen

Lutz Willek



Mehr Informationen über die Mailingliste linux-l