2016-07-05 6 views
2

Ich versuche, read Built in bash zu verwenden, um ein Zeichen zu einer Zeit zu lesen. Das funktioniert tatsächlich einwandfrei, wenn ich das -N 1 Argument zu read verwende, aber ich hatte einige OSX Benutzer berichten mir, dass ihre Bash diese Option nicht hat.Bash lesen Mysterium: `Read -d '' -s -n 1 'isst Bindestriche

So, jetzt bin ich mit etwas entlang der Linien von:

$ while IFS= read -r -d'' -s -n 1 char; do echo -n "${char}"; done < filename 

dieses jedes Zeichen in filename einer nach dem anderen das Echo zurück außer, geheimnisvoll, Bindestriche (-). Z.B. wenn ich

$ cat blah 
uh-oh 

Das Ergebnis haben, ist:

$ while IFS= read -r -d'' -s -n 1 char; do echo -n "${char}"; done < blah 
uhoh 

Nichts in der Dokumentation sagt alles, was dies bedeuten würde. Wenn ich ${char} in echo durch ${#char} ersetze, druckt es 0, wo es den Bindestrich hätte lesen sollen. Es wird einfach komplett gegessen.

Wenn ich die -d'' fallen sie isst stattdessen neue Zeilen, aber tut nicht Bindestrich essen, so dass zumindest sinnvoll ist, da Newline die Standardtrennzeichen ist. Es scheint fast wie ein Fehler, behandelt Bindestrich als Trennzeichen.

FWIW Ich habe

$ bash --version 
GNU bash, version 4.3.42(4)-release (x86_64-unknown-cygwin) 

aber dies wurde zuerst von einem OSX Benutzer bei mir gemeldet.

+1

Verwenden 'printf% s "$ char"' statt (Nicht-Standard) 'echo -n "char $"' ... – anishsane

+0

Ist mit 'printf 'wirklich portabler als' echo -n'? – Iguananaut

+0

Ja. POSIX 'echo' spezifiziert keinen Standard für '-n'. – anishsane

Antwort

4

Sie haben die Delimiter Option zum Lesen nicht richtig eingestellt.

Beachten Sie den zusätzlichen Platz:

while IFS= read -r -d '' -s -n 1 char; do echo -n "${char}"; done < filename 

Dies funktioniert gut. In Ihrem Code der Begrenzer Zeichen, wo Satz -s

+0

Erstaunlich und subtil. Vielen Dank! (Ich denke, der Platzmangel war Gewohnheitsmacht von 'cut', deren Begrenzeroption kein Leerzeichen vor dem Begrenzer selbst benötigt). – Iguananaut

+0

Was weiter verwirrend ist, ist, dass die '-s' auch noch korrekt verarbeitet werden. – Iguananaut

+0

Eigentlich wird '-s' nicht verarbeitet. Die Option ist nur sinnvoll, wenn "stdin" ein Terminal ist. Da Sie die Umleitung verwendet haben, wird die Eingabe sowieso nicht wiederholt. –

Verwandte Themen