我有接下來的兩個腳本:
測驗.sh:
echo "start"
echo $@
echo "end"
運行.sh:
echo "parameters from user:"
echo $@
echo "start call test.sh:"
bash -c "./test.sh $@"
執行上面的run.sh:
$ ./run.sh 1 2
parameters from user:
1 2
start call test.sh:
start
1
end
您可以看到雖然我將 2 個引數傳遞給run.sh,但test.sh只接收第一個引數。
但是,如果我更改run.sh為 next 只是下降bash -c:
echo "parameters from user:"
echo $@
echo "start call test.sh:"
./test.sh $@
行為變成預期的,它test.sh接收 2 個引數:
$ ./run.sh 1 2
parameters from user:
1 2
start call test.sh:
start
1 2
end
題:
出于某種原因,我必須bash -c在我的完整場景中使用,那么你能告訴我這里有什么問題嗎?我怎么能解決這個問題?
uj5u.com熱心網友回復:
這是因為參考的論點是在錯誤的地方。當您在 中運行一系列命令時bash -c,請將其視為一個完整的 shell 腳本,并且需要相應地傳遞引數。來自 bash 手冊
如果 Bash 以該
-c選項啟動(請參閱呼叫 Bash),則$0設定為要執行的字串之后的第一個引數(如果存在)。否則,它被設定為用于呼叫 Bash 的檔案名,由引數零給出。
但是如果有人注意到你下面的命令,
bash -c "./test.sh $@"
當您的期望是將引數傳遞給test.sh, inside '..',但$@內部雙引號過早擴展,經歷分詞以僅生成第一個引數值,即值$1
但是即使您使用如下單引號修復了它,它仍然無法作業,因為請記住傳遞給的內容-c是在其自己的 shell 背景關系中計算的,并且需要顯式傳遞引數,
set -- 1 2
bash -c 'echo $@' # Both the cases still don't work, as the script
bash -c 'echo "$@"' # inside '-c' is still not passed any arguments
要解決上述問題,您需要顯式傳遞內部內容的引數-c,如下所示。的_(下劃線)字符表示殼的路徑名呼叫以執行腳本(在這種情況下的bash)。更多關于Bash 變數的手冊
set -- 1 2
bash -c 'printf "[%s]\n" "$@"' _ "$@"
[1]
[2]
因此,要修復您的腳本,在 中run.sh,將引數傳遞為
bash -c './test.sh "$@"' _ "$@"
uj5u.com熱心網友回復:
除了接受一個,現在找到另一個解決方案。如果-x在呼叫時添加run.sh,我可以看到下一個:
$ bash -x ./run.sh 1 2
echo 'parameters from user:'
parameters from user:
echo 1 2
1 2
echo 'start call test.sh:'
start call test.sh:
bash -c './test.sh 1' 2
start
1
end
所以,它看起來bash -c "./test.sh $@"被解釋為bash -c './test.sh 1' 2。
受此啟發,我嘗試使用$*替換$@,然后將所有引數作為單個引數傳遞,然后使用 next 也可以正常作業:
運行.sh:
echo "parameters from user:"
echo $*
echo "start call test.sh:"
bash -c "./test.sh $*"
執行:
$ bash -x ./run.sh 1 2
echo 'parameters from user:'
parameters from user:
echo 1 2
1 2
echo 'start call test.sh:'
start call test.sh:
bash -c './test.sh 1 2'
start
1 2
end
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/361170.html
