web-dev-qa-db-ja.com

$ PATHのSHスクリプトがLinux Alpine 3.11で見つかりません

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-forsh接頭辞なし)を使用すると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  
5
alias51

インタラクティブなシェルはdashです(shになりすます)。 dashシェルは言う

_sh: /usr/local/bin/wait-for: not found
_

見つからないインタープリターを指す障害のある_#!_- lineを持つスクリプトを実行しようとしたとき。入力したコマンドが見つからない場合に発生するエラーとまったく同じが発生するため、_$PATH_の問題であると考えるのは簡単です(この場合はありません)。他のシェルにはより有益なエラーメッセージがあります(bashzshは「不正なインタープリター:そのようなファイルまたはディレクトリはありません」と表示し、実行しようとしたインタープリターも通知します)。

ファイルはDOSテキストファイル なので、_#!_-行は、シェルに_/bin/sh\r_を使用してスクリプトを実行するように指示します。ここで、_\r_は、キャリッジリターン文字。DOSテキストファイルの行末の一部です。 Unixシステムでは、キャリッジリターンは「通常の文字」であり、行の終端ではありません。つまり、_/bin/sh\r_を開始してスクリプトを実行しようとし、そのファイルが存在しないために失敗します。 。したがって、スクリプト自体ではなく、「見つからない」のはインタプリタです。

explicitインタープリターを使用してスクリプトを実行すると、常に_#!_- lineがバイパスされます。そのため、エラーが発生しません。ただし、スクリプトの各行の最後には改行が含まれているため、状況によってはスクリプトが誤動作する可能性があります。

ファイルをUnixテキストファイルとして再保存するか、_dos2unix_で変換するだけで問題が解決します。

14
Kusalananda

この質問を見つけた人にとって、私の特定の問題はどういうわけか私のwait-forスクリプトがWindowsの行末に変換されていました。

UNIXの行末で再保存すると、この問題は解決しました。

誰かがWindowsの行末でファイルがsh /usr/local/bin/wait-forではなく/usr/local/bin/wait-forまたはwait-for同意します。

1
alias51