Unter Linux erstelle ich gerade ein Bash-File, welches mit zusätzlichen
Argumenten aufgerufen werden soll. Dieses File wird von einem anderen
Script gestartet, welches ich nicht mehr verändern kann. Mit dieser
beispielhaften Zeile kann ich mir nun in meinem Bash-File sämtliche
Argumente anzeigen lassen:
1
echo$@
Das ganze funktioniert an sich auch sehr gut.
Nun soll das neue Bash-File aber auch mit Sonderzeichen gestartet werden
können. Also z.B. so hier:
1
./meinBashFilemit\Argumentxy
Allerdings habe ich dann das Problem, dass das Sonderzeichen "\"
entfernt wird.
Durch mein Echo hätte ich nun also gerne so etwas oder ähnliches
gesehen: "mit\ Argument" "xy"
Klar, wenn ich nun zwei "\\"-Zeichen übergebe, oder das ganze in
Anführungszeichen setzte, dann funktioniert wieder alles. Wie gesagt
kann ich aber das Skript, welches mein neues Bash-File startet nicht
mehr ändern.
Hätte jemand eine Idee, wie ich das Sonderzeichen im Bash-File sehen
kann?
Hi, die Erklärung ist etwas konfus. Ich denke, sie wäre klarer, wenn du
etwas weniger "Beispiel Beispiel" sagen würdest und konkrete Namen,
Pfade und Strings nennen.
Aber falls ich sie richtig verstehe: nein, das Programm was dein Skript
aufruft, interpretiert die Argumente offenbar als Shell-String. Dein
Skript bekommt das \-Byte gar nicht mehr rein.
bash schrieb:> Nun soll das neue Bash-File aber auch mit Sonderzeichen gestartet werden> können. Also z.B. so hier:./meinBashFile mit\ Argument xy
Der Backslash wird bereits vor dem Aufruf von meinBashFile von deiner
interaktiven shell expandiert und in diesem Fall einfach entfernt, weil
Backslash-Leerzeichen kein valider Escapecode ist.
bash schrieb:> Wie gesagt> kann ich aber das Skript, welches mein neues Bash-File startet nicht> mehr ändern.
Kurze Korrektur zu meinem vorhergehenden Beitrag:
Da du es nicht interaktiv aufrufst, sondern aus einen anderen
Bash-Script, MUSST du dieses Script ändern.
Eine andere Möglichkeit gibt es nicht, weil der Fehler in dem
aufrufenden Script ist.
Ich habe die Erklärung jetzt nicht ganz verstanden....
Ist der Backslash oder ist das Leerzeichen das zu übergebende
Sonderzeichen?
Das übliche Vorgehen wäre es einfacher oder doppelte Anführungszeichen
um das Argument zu machen.
dave4 schrieb:> Ist der Backslash oder ist das Leerzeichen das zu übergebende> Sonderzeichen?
Der Backslash wird überhaupt nicht übergeben, sondern von der
aufrufenden Shell expandiert. Da Backslash-Leerzeichen keine
Escapesequenz ist, wird das in ein Leerzeichen expandiert.
Das heißt übergeben wird nur ein normales Leerzeichen.
MaWin schrieb:> Der Backslash wird überhaupt nicht übergeben, sondern von der> aufrufenden Shell expandiert.
Desshalb die Frage ob der Backslash hinterher für irgendwas in das
Script muss oder ob er das Leerzeichen escapen soll
dave4 schrieb:> Desshalb die Frage ob der Backslash hinterher für irgendwas in das> Script muss oder ob er das Leerzeichen escapen soll
Die Frage verstehe ich nicht.
Der Backslash wird im aufrufenden Script entfernt.
MaWin schrieb:> Der Backslash wird bereits vor dem Aufruf von meinBashFile von deiner> interaktiven shell expandiert und in diesem Fall einfach entfernt, weil> Backslash-Leerzeichen kein valider Escapecode ist.
Blödsinn. Das Escapen des slash ist an der stelle vollkommen i.o.
Bei der Expansion von $@ (und bei bash Arrays "${var[@]}") gibt es noch
Besonderheiten. Schau dir mal folgendes Beispiel an:
1
printargs(){
2
i=0
3
forargin"$@"
4
doecho"arg $i: $arg";i=$(expr$i+1);
5
done
6
}
7
8
ex1(){
9
printargs"$@"
10
}
11
12
ex2(){
13
printargs$@
14
}
15
16
echo"---- 1 ----"
17
printargs"a b"c
18
echo"---- 2 ----"
19
printargsa\bc
20
echo"---- 3 ----"
21
printargsabc
22
echo"---- 4 ----"
23
ex1"a b"c
24
echo"---- 5 ----"
25
ex2"a b"c
Man sieht da auch schön, dass der Slash nicht einfach nur entfernt wird,
sondern das der folgende Space als String, bzw. hier als teil des
Strings / Arguments behandelt wird, statt als Argument Trennzeichen
geparst zu werden.
Es gibt auch noch "$*", die verhält sich wie eine normale String
variable. Braucht man aber selten bis nie.
MaWin schrub:
> Der Backslash wird überhaupt nicht übergeben, sondern von der> aufrufenden Shell expandiert.
Ersteres stimmt, zweiters nicht, siehe Doku [0].
> Da Backslash-Leerzeichen keine Escapesequenz ist, [..]
Doch, ist sie, und gültig ist sie auch, siehe Doku [0].
> [..] wird das in ein Leerzeichen expandiert.
Nein, wird es nicht. Das Leerzeichen (als Metazeichen, siehe Doku [0])
bleibt erhalten, und dient nicht als Argumenttrennzeichen, siehe Doku
[0].
> Das heißt übergeben wird nur ein normales Leerzeichen.
Das wiederum stimmt, und zwar als "mit Argument" als ∗ein∗ Argument.
Dem TO bleibt nichts anderes übrig als mit aufgesplitteten Argumenten
umgehen zu können oder den Bug im aufrufende Skript zu reparieren.
HTH
[0] man bash
g457 schrieb:> Doch, ist sie, und gültig ist sie auch, siehe Doku [0].
Ja gut. Jetzt haben wir das auch geklärt.
Es bleibt dabei, dass das aufrufende Script defekt ist.
Vielleicht hilft das (habe OPs Problem nicht ganz verstanden).
Gezeigt wird der Unterschied zwischen double quotes (") und einfachen
quotes (') - der Inhalt von double quotes wird von der shell
interpretiert, also $variablen, aber auch file globs (*).
Als Zusatz noch die Auswirkung der Feldtrenner Variablen $IFS.
dave4 schrieb:> Das übliche Vorgehen wäre es einfacher oder doppelte Anführungszeichen> um das Argument zu machen.
Doppelte Anführungszeichen sind weiche.
Soll ein Inhalt nicht verändert werden, umschließt man es in harte ''.
Shellkommandos werden immer so eingeschlossen.
Mit einem Backslash macht er doch den Zeilensprung und erkennt es nicht
mehr als zusammenhöriges Argument.
Die bessere Frage ist, warum benötigt man ausgerechnet Backslashes? Die
haben eine Sonderstellung.
Wenn etwa ein Netzwerkpfad übergeben werden soll, kann man sich Gedanken
über die richtige Addressierung des Protokolls in Form
smb://server/share/file machen.
Mister A. schrieb:> Die bessere Frage ist, warum benötigt man ausgerechnet Backslashes?
Und dann auch noch ausgerechnet mit einem Leerzeichen dahinter.
Rolf M. schrieb:> Und dann auch noch ausgerechnet mit einem Leerzeichen dahinter.
Wir kennen die Anwendung nicht. Daher tippe ich auf einen Pfad.
root/webroot unter Windows oder so.
An sich stört das Leerzeichen nicht, wenn es nicht explizit zum Argument
gehört (daher der Vorschlag mit den harten Füsschen).
Das nächst höhere wären die Backticks ``. Dann ist aber Ende.
Wenn ich es recht in Erinnerung habe, sind backticks die Aufforderung
für eine Sub-shell. Das endet für ein Argument nicht gerade erfolgreich.
pnp schrieb:> Das schrieb der TO aber schon selbst (im allerersten Beitrag).
Ja.
Aber er ging davon aus, dass es im aufgerufenen Script lösbar ist.
Es ist definitiv nicht im aufgerufenen Script lösbar, weil das
aufrufende Script die Escape-Sequenz auflöst und den Backslash damit
entfernt.
> sieht definitiv nach subshell aus.
Erstzung, Command substitution: $(command) = `command` (alte Form)
Das commandkonstrukt wird ausgeführt und das Ergebnis an die Stelle
eingesetzt
das quoten ist doch gut beschrieben,
gibt halt eine Reihe Fälle
man bash
1
QUOTING
2
Quoting is used to remove the special meaning of certain characters or words to the shell. Quoting can be used to disable special treatment for special characters, to prevent reserved words from being recognized as such, and to prevent parameter expansion.
3
When the command history expansion facilities are being used, the history expansion character,usually !,must be quoted to prevent history expansion.
4
There are three quoting mechanisms: the escape character, single quotes, and double quotes.
5
A non-quoted backslash (\) is the escape character. It preserves the literal value of the next character that follows, with the exception of <newline>. If a \<newline> pair appears, and the backslash is not itself quoted, the \<newline> is treated as a line continuation (that is, it is removed from the input stream and effectively ignored).
6
Enclosing characters in single quotes preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.
7
Enclosing characters in double quotes preserves the literal value of all characters within the quotes, with the exception of $,`,\, and, when history expansion is enabled, !. The characters $ and ` retain their special meaning within double quotes. The backslash retains its special meaning only when followed by one of the following characters: $, `, ", \, or <newline>. A double quote may be quoted within double quotes by preceding it with a backslash. If enabled, history expansion will be performed unless an ! appearing in double quotes is escaped using a backslash. The backslash preceding the ! is not removed.
8
The special parameters * and @ have special meaning when in double quotes.
9
Words of the form $'string' are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard.
10
Backslash escape sequences, if present, are decoded as follows: