2016-08-13 80 views
0

我試圖通過exec將參數傳遞給shell腳本,在另一個shell腳本中。但是,我得到一個錯誤,該腳本不存在於路徑中 - 但事實並非如此。將參數傳遞給由exec調用的腳本產生不良結果

$ ./run_script.sh 
$ blob has just been executed. 
$ ./run_script.sh: line 8: /home/s37syed/blob.sh test: No such file or directory 

出於某種原因,它是將整個執行作爲腳本一個整體絕對路徑 - 它不讀字符串作爲blob.sh參數。

這是正在執行的腳本。

#!/bin/bash 
#run_script.sh 
blobPID="$(pgrep "blob.sh")" 
if [[ -z "$blobPID" ]] 
then 
    echo "blob has just been executed." 
    #execs as absolute path - carg not read at all 
    (exec "/home/s37syed/blob.sh test") 
    #this works fine, as exepcted 
    #(exec "/home/s37syed/blob.sh") 
else 
    echo "blob is currently running with pid $blobPID" 
    ps $blobPID 
fi 

和腳本通過run_script.sh被調用,而不是做多,只是模擬一個漫長的過程/任務:

#!/bin/bash 
#blob.sh 
i=0 
carg="$1" 
if [[ -z "$carg" ]] 
then 
    echo "nothing entered" 
else 
    echo "command line arg entered: $carg" 
fi 
while [ $i -lt 100000 ]; 
    do 
    echo "blob is currently running" >> test.txt 
    let i=i+1 
done 

下面是我使用的Bash版本:

$ bash --version 
GNU bash, version 4.2.37(1)-release (x86_64-pc-linux-gnu)  

任何意見/意見/幫助爲什麼發生這種情況將不勝感激!

由於提前,

s37syed

+2

它看起來像你是'exec'與'eval'混淆。 – chepner

+0

*爲什麼*你在這裏使用'exec'或'eval'?我沒有看到任何一個合法的目的。 –

回答

2

除了引用問題,賽勒斯指出,我敢肯定你不想使用execexec的作用是用正在執行的命令替換當前shell(而不是將該命令作爲子進程運行,因爲它沒有exec)。放置括號可以使其在子shell中執行該部分,從而有效地抵消exec的影響。

正如chepner所說,你可能想到eval命令,該命令在執行命令之前執行額外的解析過程。但eval是一個巨大的臭蟲磁鐵。以不安全的方式使用eval非常容易(請參閱BashFAQ #48)。如果您需要構建命令,請參閱BashFAQ #50以獲取更好的方法。

+0

我有意使用exec這種方式 - 我需要找出正在運行的進程的PID,並確保在它已經運行時不啓動blob.sh。我實際上想出了一個替代解決方案,我開始這個過程並使用$!保存新進程的PID,並確保進程沒有運行(如果文件中的PID不存在)。 感謝您的解釋,我會進一步閱讀BashFAQ。 – s37syed

3

替換

exec "/home/s37syed/blob.sh test" 

(其試圖執行名爲 「/home/s37syed/blob.sh試驗」 不帶參數的命令)

by

exec /home/s37syed/blob.sh test 

(使用一個參數「test」執行「/home/s37/syed/blob.sh」)。

+0

這確實在驗證後才起作用。我假設我無法檢索「子」腳本的PID,因此我在一個子shell中執行了該命令。我很感謝賽勒斯的幫助! – s37syed