シバンラインがcr-lfで機能しない


10

次の基本スクリプトのシバン部分が機能しないのはなぜですか。

$ cat hello.sh
#! /bin/sh
echo Hello
$ ./hello.sh
bash: ./hello.sh: /bin/sh^M: bad interpreter: No such file or directory

$ cat hello.py
#! /usr/bin/env python3
print("Hello")
$ ./hello.py
: No such file or directory

一方、インタプリタを手動で呼び出すことは機能しています:

$ sh hello.sh
Hello
$ python3 hello.py
Hello

回答:


11

スクリプトにはおそらくDOSスタイルのCR-LF行末があり、UnixスタイルのLF行末ではありません。最初のケースでエラーメッセージに表示される^ Mは、0D文字がスクリプトインタープリター名の一部として解釈され、行末の一部として解釈されなかったことを示しています(予想通り)。システムに0D(^ M)の文字を含むパスを持つ実行可能ファイルがないため、システムはインタープリターを呼び出すことができません。インタプリタを手動で呼び出すと、スクリプトに存在する両方の種類の行末を処理できます。

UnixスタイルのLF行末を使用するようにスクリプトを変換すると、シバンが機能するはずです。イラストを読んでください。

以下のセッションでは、todosとfromdosは、行末規則をCR-LFからLFに変換するユーティリティ(Ubuntuでパッケージとして利用可能tofrodos)です。同等のユーティリティ(このunix.SEの質問を参照)は、デモンストレーションの目的で使用します。

次のセッショントランスクリプト(同じスクリプトファイルを使用して実行)は、状況を明確にするはずです。

$ fromdos hello.sh
$ ./hello.sh
Hello
$ todos hello.sh
$ ./hello.sh
bash: ./hello.sh: /bin/sh^M: bad interpreter: No such file or directory
$
$ fromdos hello.py
$ ./hello.py
Hello
$ todos hello.py
$ ./hello.py
: No such file or directory
$

そうです、それはシェバング行を読み込み、カーネルであること、そしてどうやらLinuxカーネルは、(少なくとも私のKubuntuの生意気システム上のバージョンのような)大会を終了するCR-LFラインの一部としてCRを認識しません。

スクリプトのシバンが機能していないように見える場合(つまり、スクリプトでインタプリタを手動で呼び出すことはできますが、ファイル名を使用してスクリプトを実行できませんchmod +x)、これは考えられる理由です。

注: コメントした他の人にも感謝します。より良い答えがあれば、私も聞いていただければ幸いです!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.