2017-01-03 159 views
0

我有一個有趣的問題,我似乎無法找到答案。我正在創建一個簡單的應用程序,它將幫助我的開發部門使用NginX和配置文件自動啓動Docker容器。我的問題是,出於某種原因,我無法讓bash腳本存儲文件夾的名稱,同時掃描目錄。下面是我在談論的一個非常簡單的例子....將函數輸出保存到參數中命名的變量

#!/bin/bash 

getFolder() { 
    local __myResultFolder=$1 
    local folder 
    for d in */ ; do 
     $folder=$d 
    done 
    __myResultFolder=$folder 
    return $folder 
} 

getFolder FOLDER 

echo "Using folder: $FOLDER" 

我那麼簡單的腳本保存爲folder_test.sh並把它放在一個文件夾中,其中只有一個文件夾,將所有者更改爲我,並給它正確的權限。然而,當我運行該腳本我不斷收到錯誤...

./folder_test.sh: 8 ./folder_test.sh: =test_folder/: not found 

我試圖把$folder=$d部分在不同類型的報價,但沒有任何工程。我試過$folder="'"$d"'"$folder=`$d`$folder="$d"但它都不起作用。讓我瘋狂,任何幫助將不勝感激。謝謝。

+4

http://shellcheck.net/會自動捕捉這個給你。 –

+0

順便說一句,如果你不標記'local d',你就會將它泄露到函數的外部範圍中。 –

+0

Hrm。仔細閱讀,你的目標是執行間接任務?對不起 - 我不應該關閉它。 –

回答

1

罪魁禍首是行

$folder=$d 
一個正在處理的文件夾名稱與 =標誌存儲前,並試圖擴大其在該名稱即從字面上把名字 =test_folder/爲可執行下運行

shell但沒有找到該名稱的文件。將其更改爲

folder=$d 

此外,bash功能的返回值只限於整數類型,你不能發送一個字符串到調用函數。如果你想送一個非零返回代碼調用函數上$folder是空的,你可以添加一行

if [ -z "$folder" ]; then return 1; else return 0; fi 

(或)如果你想返回從函數的字符串值,不要使用return ,只是做了名的echo和使用命令替換與函數名稱,即

getFolder() { 
    local __myResultFolder=$1 
    local folder 
    for d in */ ; do 
     folder=$d 
    done 
    __myResultFolder=$folder 
    echo "$folder" 
} 

folderName=$(getFolder FOLDER) 
echo "$folderName" 
+0

「只是不做間接任務」的方法有一些優點 - 特別是在可移植性和簡單性方面 - 但有時候還存在性能,範圍和變量持久性方面的限制(考慮你想維護一個緩存的情況臨時查找 - 在函數退出時緩存在子外殼中的任何內容都會丟失)使其無法工作。 –

2

如果你想你的結果保存到一個指定的變量,你在做什麼叫做「間接轉讓」;它涵蓋在BashFAQ #6

的一種方法如下:

#!/bin/bash 
#  ^^^^ not /bin/sh; bash is needed for printf -v 

getFolder() { 
    local __myResultFolder=$1 
    local folder d 
    for d in */ ; do 
    folder=$d 
    done 
    printf -v "$__myResultFolder" %s "$folder" 
} 

getFolder folderName 
echo "$folderName" 

其它方法包括:

  • 使用read

    IFS= read -r -d '' "$__myResultFolder" < <(printf '%s\0' "$folder") 
    
  • 使用eval(非常,非常仔細地):

    # note \$folder -- we're only trusting the destination variable name 
    # ...not trusting the content. 
    eval "$__myResultFolder=\$folder" 
    
  • 使用namevar秒(僅在使用bash的新版本):

    getFolder() { 
        local -n __myResultFolder=$1 
        # ...your other logic here... 
        __myResultFolder=$folder 
    }