IFS null ist nicht dasselbe wie nicht gesetztes IFS?

13

Ich habe hier eine großartige Frage mit dem Titel " IFS verstehen" gelesen . Ich war überrascht, weil die Antworten und Kommentare POSIX zitieren, das besagt, dass IFS = nicht dasselbe ist wie das Deaktivieren von IFS. Wenn Sie IFS deaktivieren, wird anscheinend der Standardwert verwendet. Wenn Sie stattdessen IFS null machen, gibt es keinen Splitter. Ich wusste, dass ich eine andere Einstellung dazu gesehen hatte, und ich fand dies in meinen Lesezeichen:

Bourne Shell Programmierung

$ IFS

Die allererste Aussage in Ihrem Skript sollte sein

IFS =

Dadurch wird das Eingabefeldtrennzeichen auf den Standardwert zurückgesetzt. Andernfalls erben Sie $ IFS vom Benutzer, der es möglicherweise auf einen bizarren Wert gesetzt hat, um Sh-Parse-Zeichenfolgen anders als erwartet zu erstellen und seltsames Verhalten hervorzurufen.

War das vor einiger Zeit wahr oder ist der Autor einfach falsch?

Prüfung
quelle

Antworten:

20

Die Antworten, die Sie bei Stack Exchange gefunden haben, sind richtig und dieses Tutorial ist falsch. Sie können selbst experimentieren oder im Standard nachschlagen . Ein IFSNicht-Set entspricht dem Festlegen des Standardwerts für Leerzeichen-Tabulator-Zeilenumbruch, während ein Leerzeichen die Feldaufteilung IFSeffektiv deaktiviert .

Auf der IFS-Seite von Sven Mascheck finden Sie Informationen zu historischen Implementierungen. Ein paar historische Shells mochten es nicht unset IFS, und eine sehr alte Version von ksh behandelte es wie eine leere, IFSaber alle modernen Shells und die meisten alten Shells behandeln ein nicht gesetztes IFSwie den Standardwert.

Sie sollten Ihr Skript nur dann starten, IFS=wenn Sie die Feldaufteilung deaktivieren möchten (was eine vernünftige Entscheidung sein kann. Beachten Sie jedoch, dass Sie Substitutionen immer noch in doppelte Anführungszeichen setzen müssen, um ein Globbing zu vermeiden, es sei denn, Sie deaktivieren dies auch mit set -f). Verwenden Sie zum Zurücksetzen des Standardwerts unset IFS. Es ist fraglich, ob dies am Anfang eines Skripts nützlich ist. Es gibt viele andere schlechte Dinge, wie zum Beispiel einen zwielichtigen PATH, den der Anrufer tun kann, damit Ihr Skript schief geht.

In diesem Tutorial wird auch zum Zurücksetzen empfohlen PATH. Dies ist normalerweise ein schlechter Rat. In den meisten Fällen können Sie den richtigen Suchpfad nicht vorhersagen, aber der Benutzer weiß es. Woher wissen Sie, ob fehlerbehaftete Versionen von Dienstprogrammen unter einem alten Unix enthalten sind /usr/local/binoder /home/bob/binenthalten, in denen die fehlerhaften Versionen fehlerhaft /usr/binsind? Möchten Sie wirklich die gesamte Logik einbetten, um herauszufinden, ob Sie /usr/xpg6/binvorziehen müssen /bin? An welcher Position möchten Sie /usr/gnu/bin? Setzen Sie PATH nur zurück, wenn Ihr Skript auf ein bestimmtes System abzielt.

Ich habe dieses Tutorial nicht gelesen, aber eines habe ich überprüft: Es sagt Ihnen nicht von Anfang an, dass Sie immer doppelte Anführungszeichen um Variablensubstitutionen und Befehlssubstitutionen setzen müssen. Daher halte ich dieses Tutorial nicht für gut.

Gilles 'SO - hör auf böse zu sein'
quelle
unset IFSsetzt IFS in bash nicht auf seinen Standardwert zurück, obwohl die Feldaufteilung zurückgesetzt wird.
Melab
@Melab unset IFSwird nicht IFSauf den Standardwert zurückgesetzt, sondern deaktiviert. Ein Nicht- Set IFShat jedoch den gleichen Effekt wie das IFSSetzen auf den Standardwert.
Gilles 'SO - hör auf böse zu sein'