backquotes?

PatrickBaer

Well-Known Member
Morgen zusammen, guckt mal:

Code:
for i in `ls -d /backup/data/*/current`
do
e=`file $i|awk -F\` '{ print $2 }'|sed -e "s/\'//"`
f=`echo $i|awk -F\/ '{ print $4 }'`
echo ln $e /backup/data/archive/current/$f
done

Bricht ständig ab mit

/backup/archive/current/update.sh: command substitution: line 3: unexpected EOF while looking for matching ``'
/backup/archive/current/update.sh: command substitution: line 4: syntax error: unexpected end of file

Ich meine jetzt ganz abgesehen davon, daß ich nicht verstehe wieso das erste Quote ein Backquote und das zweite ein Singlequote ist (plem plem?), sollte der Backslash doch das ` im ersten awk aus der Reihe rausnehmen oder? Denk ich da jetzt falsch?
 
Zeile 3 enthält 3 `. Entweder das zweite nochmal mit '' sichern oder $() statt der äußeren `` verwenden.
Desweiteren ist das ls in Zeile 1 nutzlos. Einfacher (und nicht fehleranfällig gegenüber Leerzeichen) ist "for i in /backup/data/*/current". Natürlich muss dann die Verwendung von $i auch noch mit "" umgeben werden.
 
Desweiteren ist das ls in Zeile 1 nutzlos. Einfacher (und nicht fehleranfällig gegenüber Leerzeichen) ist "for i in /backup/data/*/current". Natürlich muss dann die Verwendung von $i auch noch mit "" umgeben werden.

Stimmt, schlechte Angewohnheit, ich weiss.

Der Rest nützt mir aber nichts, das ist ja genau mein Problem, daß das dritte ` Probleme bereitet, OBWOHL der Backslash davor steht. quotes ändern daran übrigens nichts...

Kamikaze, sh oder bash, beides mit demselben Effekt
 
Code:
vader:/backup/data/current# e=`file $i|awk -F\` '{ print $2 }'|sed -e "s/\'//"`
-bash: command substitution: line 1: unexpected EOF while looking for matching ``'
-bash: command substitution: line 2: syntax error: unexpected end of file
vader:/backup/data/current# e=`file $i|awk -F"`" '{ print $2 }'|sed -e "s/\'//"`
>
vader:/backup/data/current# e=`file $i|awk -F"\`" '{ print $2 }'|sed -e "s/\'//"`
-bash: command substitution: line 1: unexpected EOF while looking for matching ``'
-bash: command substitution: line 2: syntax error: unexpected end of file
vader:/backup/data/current# e=`file $i|awk -F'`' '{ print $2 }'|sed -e "s/\'//"`
-bash: command substitution: line 1: unexpected EOF while looking for matching `''
-bash: command substitution: line 2: syntax error: unexpected end of file

Zweite ging jetzt.
 
Zuletzt bearbeitet:
Du hast viermal nicht das getan, was ich gesagt hatte. Das Erste ist unverändert. Das Zweite verwendet "" statt '' und streicht den \. Das Dritte verwendet "". Das Vierte streicht den \. Ich hingegen schrieb, dass der zweite ` nochmals mit '' gesichert werden muss, ergo '\`'.
 
Zeile 3 enthält 3 `. Entweder das zweite nochmal mit '' sichern oder $() statt der äußeren `` verwenden.

Interessant. Ich haette jetzt auch erstmal intuitiv vermutet, dass in

Code:
e=`awk -F\` '...'`

der zweite Backquote nicht von der Shell als Ende der command-substitution geparsed wird, schliesslich ist er ja schon per Backslash gequoted.

Und SUSv3 gibt bestaetigt meine Intuition:

Within the backquoted style of command substitution, backslash shall retain its literal meaning, except when followed by: '$', '`', or '\' (dollar sign, backquote, backslash). The search for the matching backquote shall be satisfied by the first backquote found without a preceding backslash; during this search, if a non-escaped backquote is encountered within a shell comment, a here-document, an embedded command substitution of the $( command) form, or a quoted string, undefined results occur. A single-quoted or double-quoted string that begins, but does not end, within the "`...`" sequence produces undefined results.

Falls ich da jetzt was fehlinterpretiere, bitte ich um heftigen Protest. Ansonsten ist das ein astreiner Bug sowohl in der ksh (zumindest unter OpenBSD, wo ich den gleichen Fehler sehe) als auch in der bash.

Ciao,
-- Kili
 
Ja, deine Interpretation ist lückenhaft.
`command`
The shell expands the command substitution by executing command in a subshell environment and replacing the command substitution with the standard output of the command, removing sequences of one or more newlines at the end of the substitution.

Ein kleines Beispiel:
Code:
echo `echo \``
Das innerhalb der `` wird einer Subshell ausgeführt. Diese sieht folglich:
Code:
echo `
Und da fehlt eben ein zweites ` für eine korrekte Befehlsersetzung.
 
Du hast viermal nicht das getan, was ich gesagt hatte. Das Erste ist unverändert. Das Zweite verwendet "" statt '' und streicht den \. Das Dritte verwendet "". Das Vierte streicht den \. Ich hingegen schrieb, dass der zweite ` nochmals mit '' gesichert werden muss, ergo '\`'.

Langsam reiten Cowboy, ist ja hier keine Newsgroup...

Also ich in meinem, ja sicherlich absolut unzureichendem, Verständnis der Shell glaube in zigtausend Feldversuchen herausgefunden zu haben:

a) Wenn ich einen Backslash vor bestimmte Zeichen setze, dann werden diese eben NICHT von der Shell interpretiert, sondern ganz stinknormal als Zeichen gesehen. Beispiele wären ` " | usw.

echo \| gibt immer ein | aus.

b) Single quotes sind das absolute schlechthin. Text in single quotes wird NIE interpretiert.

echo 'test $test ""!$' gibt immer test $test ""$ aus.

Und jetzt kommst Du daher und sagst mir, daß weder a noch b gilt. Du verzeihst, wenn ich da den Hintergrund nicht verstehe oder? Schließlich schreibst Du ja auch selber:

echo \` gibt mir ein ` aus. Hast Du ja selbst unten auch so geschrieben.

Und Deine Subshelltheorie hakt hier auch etwas, denn die Zeile

e=`file $i|awk -F\` '{ print $2 }'|sed -e "s/\'//"`

Würde ja in der Subshell den Befehl file $i|awk -F\` '{ print $2 }'|sed -e "s/\'//" ausführen. Das Ergebnis wäre aber nichts mit einem Backquote, sondern der Teil HINTER dem Backquote, also ganz normaler Text. Die Zeile wäre dann also (nach der command substition):

e=/usr/local/sonstwas

Und daran finde ich jetzt nichts verwerfliches? Und genau deswegen vermag ich der Logik in '\`' nicht zu folgen.
 
Langsam reiten Cowboy, ist ja hier keine Newsgroup...
Du hast behauptet meine angegebene Lösung sei falsch. Damit nicht jemand anderes das irgendwann liest und danach inkorrekt verfährt, habe ich das richtig gestellt - mehr nicht.

Und jetzt kommst Du daher und sagst mir, daß weder a noch b gilt.
Das habe ich nicht gesagt.

echo \` gibt mir ein ` aus. Hast Du ja selbst unten auch so geschrieben.
Wo habe ich das gesagt?

Und Deine Subshelltheorie hakt hier auch etwas, denn die Zeile
Das ist nicht meine persönliche Theore. Das kannst du im Standard nachlesen.
 
Und Deine Subshelltheorie hakt hier auch etwas, denn die Zeile

e=`file $i|awk -F\` '{ print $2 }'|sed -e "s/\'//"`

Würde ja in der Subshell den Befehl file $i|awk -F\` '{ print $2 }'|sed -e "s/\'//" ausführen. Das Ergebnis wäre aber nichts mit einem Backquote, sondern der Teil HINTER dem Backquote, also ganz normaler Text. Die Zeile wäre dann also (nach der command substition):

e=/usr/local/sonstwas

Und daran finde ich jetzt nichts verwerfliches? Und genau deswegen vermag ich der Logik in '\`' nicht zu folgen.

so wie tron es erklärt hat, eben nicht. die subshell sieht den backslash vor dem backquote eben nicht, da nur der backquote weitergegeben wird. das stößt der subshell sauer auf.
 
Zurück
Oben