Alpine Linux 3.11を新しいDockerコンテナーとして使用しています。
私はデフォルトの$PATH
変数を持っています。
echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
スクリプトを配置すると、wait-for
に#!/bin/sh
(/usr/local/bin
で始まるシェルスクリプト)が表示されます。
chmod +x wait-for
mv wait-for /usr/local/bin/wait-for
ls -l /usr/local/bin/wait-for
生成する:
-rwxr-xr-x 1 root root 1451 May 1 16:09 /usr/local/bin/wait-for
sh /usr/local/bin/wait-for
を使用して実行した場合にも実行されます。
ただし、/usr/src/
にいるときにwait-for
を実行しようとすると、sh: wait-for: not found
が表示されます
私の理解では、/usr/local/bin
ディレクトリは$PATH
にあるため、そのディレクトリ内のスクリプトはすべてグローバルに呼び出す必要があります。
私は何を誤解しましたか?
/usr/src/
を使用すればsh /usr/local/bin/wait-for
からファイルを実行できますが、/usr/local/bin/wait-for
(sh
接頭辞なし)を使用するとsh: /usr/local/bin/wait-for: not found
を返します。
/etc/fstab
の出力は次のとおりです。
/dev/cdrom /media/cdrom iso9660 noauto,ro 0 0
/dev/usbdisk /media/usb vfat noauto,ro 0 0
インタラクティブなシェルはdash
です(sh
になりすます)。 dash
シェルは言う
_sh: /usr/local/bin/wait-for: not found
_
見つからないインタープリターを指す障害のある_#!
_- lineを持つスクリプトを実行しようとしたとき。入力したコマンドが見つからない場合に発生するエラーとまったく同じが発生するため、_$PATH
_の問題であると考えるのは簡単です(この場合はありません)。他のシェルにはより有益なエラーメッセージがあります(bash
とzsh
は「不正なインタープリター:そのようなファイルまたはディレクトリはありません」と表示し、実行しようとしたインタープリターも通知します)。
ファイルはDOSテキストファイル なので、_#!
_-行は、シェルに_/bin/sh\r
_を使用してスクリプトを実行するように指示します。ここで、_\r
_は、キャリッジリターン文字。DOSテキストファイルの行末の一部です。 Unixシステムでは、キャリッジリターンは「通常の文字」であり、行の終端ではありません。つまり、_/bin/sh\r
_を開始してスクリプトを実行しようとし、そのファイルが存在しないために失敗します。 。したがって、スクリプト自体ではなく、「見つからない」のはインタプリタです。
explicitインタープリターを使用してスクリプトを実行すると、常に_#!
_- lineがバイパスされます。そのため、エラーが発生しません。ただし、スクリプトの各行の最後には改行が含まれているため、状況によってはスクリプトが誤動作する可能性があります。
ファイルをUnixテキストファイルとして再保存するか、_dos2unix
_で変換するだけで問題が解決します。
この質問を見つけた人にとって、私の特定の問題はどういうわけか私のwait-for
スクリプトがWindowsの行末に変換されていました。
UNIXの行末で再保存すると、この問題は解決しました。
誰かがWindowsの行末でファイルがsh /usr/local/bin/wait-for
ではなく/usr/local/bin/wait-for
またはwait-for
同意します。