Als persönliches Projekt versuche ich, ein Skript zu schreiben, um einige der fremden Dateien zu bereinigen, die im Lieferumfang von Windows 10 enthalten sind, das unter Cygwin ausgeführt wird. Ich möchte, dass das Skript kopiert und eingefügt werden kann, was erfordert, dass es gegenüber verschiedenen Arten von Zeilenumbrüchen robust ist. Gibt es sh
ähnliche Muscheln, die die Fähigkeit zur Behandlung \r
als Leerzeichen offenlegen, möglicherweise wenn eine Option festgelegt ist?
Es ist eine seltsame Sache. Die Antwort könnte sich auf "Ja, das ist eine seltsame Sache und es gibt keine Möglichkeit, es zu tun" beschränken.
dos2unix
oder einfach altsed
?python
undperl
diese sind zeilenend unempfindlich.bash
kann es nicht so konfiguriert werden, dass es\r
anders verarbeitet wird.Antworten:
Dies ist im Allgemeinen für ein tatsächliches Skript nicht möglich.
Ein eigenständiges ausführbares Skript verfügt über eine Shebang-Zeile, die den zu verwendenden Interpreter identifiziert:
Das Problem ist, dass unabhängig vom Interpreter die Shebang-Zeile selbst vor dem Ende ein Wagenrücklaufzeichen enthält, was bedeutet, dass der Interpreter nicht gefunden wird (abgesehen von dem unwahrscheinlichen ausführbaren Namen wörtlich
$'sh\r'
- was unter Windows meiner Meinung nach illegal ist). .Die andere Art von ausführbarem Skript ist eine Nur-Text-Datei mit gesetztem Ausführungsbit, die POSIX als Skript in der POSIX-Shell-Befehlssprache interpretieren muss (wenn sie von einer kompatiblen Shell selbst aufgerufen wird). Wie Sie jedoch festgestellt haben, behandelt diese Shell-Sprache Wagenrückläufe als Datenbytes, sodass Sie das von Ihnen identifizierte Problem haben.
Sie haben einige Möglichkeiten. Eine besteht darin, direkt auf ein tatsächlich ausführbares Skript zu verzichten und einfach zuerst einen Interpreter für eine andere Sprache aufzurufen. Sie haben Perl und Python identifiziert, und tatsächlich sind die meisten Skriptsprachen mit jedem modernen Zeilenendformat zufrieden. Das Aufrufen des Skripts als
perl cleanup.pl
ist kein Problem.Viele Verwaltungsaufgaben sind in einer herkömmlichen Shell-Sprache jedoch viel einfacher, und es gibt noch einen Trick: Beenden Sie jede Zeile mit einem Kommentar.
Der
#
Charakter fügt in allen Standard-Shells (in nicht interaktiven Kontexten) einen Kommentar am Ende der Zeile ein. Der Kommentar enthält das Wagenrücklaufbyte, das ein feines Element eines Kommentars ist, und endet unmittelbar danach mit dem abschließenden Zeilenvorschubbyte.Es ist wichtig, dass vor dem Hash ein Leerzeichen steht: Ein
#
Inneres eines Wortes beginnt nicht mit einem Kommentar, sondern ist Teil des Wortes .Sie können dieses Skript direkt mit einer Shell ausführen:
Wenn Sie es jedoch durch Eingabe eines Befehls aus einer vorhandenen Shell-Sitzung starten möchten, funktionieren auch die oben genannten POSIX-Skripte: Machen Sie die Datei einfach ausführbar, und dann
führt es mit dem aus, was Ihre Shell für ein POSIX-Skript für richtig hält .
Da dies wie ein Einzelstück klingt, lohnt es sich wahrscheinlich nicht, es ausführbar zu machen, und
sh cleanup.sh
scheint mir daher nur angemessen zu sein.Mein ehrlicher Vorschlag für diese Situation ist wahrscheinlich Powershell (oder Batch auf Knopfdruck), aber ich verstehe, dass es nicht das ist, was Sie wollen. WSL ist eine weitere Option: Sie verarbeitet Wagenrückläufe in der Shebang-Zeile automatisch, und für den Rest können Sie Kommentare verwenden.
quelle
\r
? wie#!/bin/sh -b
(Bashs-b
" Melde den Status von abgebrochenen Hintergrundjobs sofort und nicht vor der nächsten primären Eingabeaufforderung ", daher ist es für den nicht interaktiven Gebrauch ziemlich harmlos.) Ich habe es nur unter Linux mit-b^M
versucht und Bash sagt: invalid option
, also leider nicht. Vielleicht gibt es eine Option, die einen Charakter als Argument verbrauchen kann, ohne zu brechen, wenn er nicht da ist?\r
vor der Verarbeitung ein nachfolgendes (falls vorhanden) von einer Shebang-Zeile entfernt, möglicherweise einfacher, als einen benutzerdefinierten Linux-Kernel zu kompilieren, der dasselbe tut . Und Sie müssen den Windows-Kernel nicht ändern (gut, weil er Closed Source ist).\r\n
die übliche Linie endet, soll nicht eine Hash - Bang Linie#!/bin/sh\r\n
sucht ,/bin/sh
ohne die CR? Dann brauchen Sie nur noch eine richtig fixierte Shell/bin/sh\r
. Was unter Unixen funktionieren sollte (solange das Skript nicht versucht, Argumente in der Hashbang-Zeile zu übergeben), obwohl es schrecklich hässlich wäre.