在 Linux Alpine 3.11 上找不到 $PATH 中的 SH 腳本
我使用 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
(這是一個以 開頭的 shell 腳本#!/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
問題(在這種情況下不是)。其他 shell 有更多資訊豐富的錯誤消息(bash
並zsh
說“錯誤的解釋器:沒有這樣的文件或目錄”,還告訴你它試圖執行的解釋器)。由於該文件是 DOS 文本文件,
#!
-line 指示 shell 執行腳本/bin/sh\r
,其中\r
是輸入符的常見表示,它是 DOS 文本文件中行終止的一部分。在 Unix 系統上,輸入是一個“普通字元”,而不是行終止的所有部分,這意味著它嘗試開始/bin/sh\r
執行您的腳本,然後由於該文件不存在而失敗。因此,“未找到”的是解釋器,而不是腳本本身。使用顯式解釋器執行腳本總是會繞過
#!
-line,這就是為什麼這樣做時不會出現錯誤的原因。但是,腳本中的每一行仍然會在它們的末尾有輸入符,這可能會導致腳本在某些情況下出現故障。只需將文件重新保存為 Unix 文本文件,或將其轉換為
dos2unix
,即可解決您的問題。