使用 bash 命令執行時等待它的腳本超時(沒有這樣的文件或目錄)
嘗試使用 bash 命令在沒有 +x 執行權限的情況下執行wait-for-it.sh腳本。
bash wait-for-it.sh google.com:80
超時:無法執行命令’wait-for-it.sh’:沒有這樣的文件或目錄
wait-for-it.sh:google.com:80 等待 15 秒後發生超時
(錯誤資訊,第 2 行來自腳本內部,與上述情況相同,即使已授予執行權限)
但它在給定 +x 的情況下直接執行時有效。
./wait-for-it.sh google.com:80
wait-for-it.sh:等待 15 秒等待 google.com:80
wait-for-it.sh:google.com:80 1 秒後可用
有什麼方法可以在不授予執行權限的情況下使用腳本或調試問題?
如果您檢查wait-for-it.sh腳本。您可以看到以下功能:
wait_for_wrapper() { # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692 if [[ $WAITFORIT_QUIET -eq 1 ]]; then timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & else timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & fi WAITFORIT_PID=$! trap "kill -INT -$WAITFORIT_PID" INT wait $WAITFORIT_PID WAITFORIT_RESULT=$? if [[ $WAITFORIT_RESULT -ne 0 ]]; then echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" fi return $WAITFORIT_RESULT }
如果你看這一行:
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet ...
現在如果你執行
bash wait-for-it.sh google.com:80
它會失敗,原因有兩個:
- 如果該文件未在環境變數中
wait-for-it.sh
定義,則無法辨識該文件。$PATH
- 該文件
wait-for-it.sh
沒有執行權限:嘗試在沒有 +x 執行權限的情況下執行 wait-for-it.sh 腳本
現在,如果你看到這個函式,這個函式正在傳遞 的值
$0
,其中$0
是文件名 (wait-for-it.sh
)。所以
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0
基本上是使用以下timeout
命令“執行自身”(但帶有一些參數):timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT wait-for-it.sh --quiet ...
wait-for-it.sh
使用bash執行時,解決方案是使用絕對路徑或相對路徑。您還需要為該文件分配執行權限。#Using relative path: bash ./wait-for-it.sh google.com:80 #Using absolute path: bash /path/to/wait-for-it.sh google.com:80 #e.g. bash /home/user/wait-for-it.sh google.com:80
為什麼“bash wait-for-it.sh google.com:80”會失敗?
您可以像這樣編輯函式
wait_for_wrapper
:wait_for_wrapper() { echo Running "$0" echo Whereis "$0": $(whereis "$0") $0 echo Exit... exit #to avoid running the following code # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692 if [[ $WAITFORIT_QUIET -eq 1 ]]; then timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & else timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & fi WAITFORIT_PID=$! trap "kill -INT -$WAITFORIT_PID" INT wait $WAITFORIT_PID WAITFORIT_RESULT=$? if [[ $WAITFORIT_RESULT -ne 0 ]]; then echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" fi return $WAITFORIT_RESULT }
如果您執行
bash wait-for-it.sh google.com:80
(使用執行權限),您將收到此錯誤:Running wait-for.sh at /home/user/... Whereis wait-for.sh: wait-for.sh: wait-for.sh: line 56: wait-for.sh: command not found Exit...
正如我之前所說,該行
$0
正在嘗試執行wait-for.sh
,但該行不在$PATH
env 變數的任何目錄中。現在我將文件名更改
wait-for.sh
為ls
. ls 命令將被辨識,因為 my$PATH
包含通常所在/usr/bin/
的目錄。ls
所以,如果你執行:bash ls google.com:80
你會得到:
Running ls at /home/user/... Whereis ls ls: /usr/bin/ls /usr/share/man/man1p/ls.1p.gz /usr/share/man/man1/ls.1.gz #This output is of my $HOME directory: Postman Templates projects bin go ls Public Videos Documents Downloads Pictures temp Exit...