2017-07-03 30 views
0

我試圖在Make目標中用冒號分隔值拆分字符串。拆分制定規則中的字符串

當我嘗試在使用for循環,eval,shell的目標配方中拆分字符串時,我得到空白值。在那時我使用shell命令將字符串拆分到目標結果之外是正面的。

任何人都可以幫助我修復目標配方。

下面是片段。

notebooks=new:e7e45d89-94cc-4783-86c5-2236d9904a24 test:2af1d689-98c3-48f2-984d-2ea21c5135dd 
j=new:e7e45d89-94cc-4783-86c5-2236d9904a24 
f1=$(shell echo $j | cut -d: -f 1) 
test1: 
    @for i in $(notebooks); \ 
    do \ 
     $(eval f=$(shell echo $i | cut -d: -f 1)) \ 
     $(eval fid=$(shell echo $i | cut -d: -f 2)) \ 
     echo $(f) $(fid) $(f1) ;\ 
    done 

輸出是

new 
new 

鑑於期望的輸出是

new e7e45d89-94cc-4783-86c5-2236d9904a24 new 
test 2af1d689-98c3-48f2-984d-2ea21c5135dd new 

回答

3

這是一個關於生成文件中最常見的混亂看來:所述配方之間的區別這是寫在殼語法和構造。

使作品的方式是全部使配方中的構造(變量和函數)首先由make評估,然後將生成的擴展字符串傳遞給shell並由shell執行。

在你的例子中,你正在嘗試使用一個包含make變量和函數的shell腳本循環:這不起作用(shell,它是一個新分叉的進程,要求重新擴展一些值基於一個shell變量)

化妝時要運行這個食譜:

@for i in $(notebooks); \ 
do \ 
    $(eval f=$(shell echo $i | cut -d: -f 1)) \ 
    $(eval fid=$(shell echo $i | cut -d: -f 2)) \ 
    echo $(f) $(fid) $(f1) ;\ 
done 

它首先展開所有makefile的變量和函數。記住它只是在這裏擴展一個字符串,它不運行一個shell,所以沒有shell命令被調用。前兩行擴大這樣的:

@for i in new:e7e45d89-94cc-4783-86c5-2236d9904a24 test:2af1d689-98c3-48f2-984d-2ea21c5135dd; \ 
do \ 

那麼接下來的擴展:

$(eval f=$(shell echo $i | cut -d: -f 1)) \ 

這裏$i只是一個make變量i,你從來沒有設置,因此它是空的。所以要運行這個shell命令:

echo | cut -d: -f 1 

這將產生什麼,所以$(eval f=)被擴大,使變量f設置爲空字符串。

同樣這一行:

$(eval fid=$(shell echo $i | cut -d: -f 2)) \ 

fid爲空字符串。

那麼這一行擴大

echo $(f) $(fid) $(f1) ;\ 

其擴展爲:

echo new ;\ 

因爲只有f1具有任何價值在這裏。最後的最後一行:

done 

所以,在這一切之後擴展,傳遞給要運行外殼的字符串是:

@for i in new:e7e45d89-94cc-4783-86c5-2236d9904a24 test:2af1d689-98c3-48f2-984d-2ea21c5135dd; \ 
do \ 
    echo new; \ 
done 

絕對沒有必要使用$(shell ...)的食譜;你已經在一個外殼,爲什麼你需要另一個?同樣,你不需要eval來設置make變量,你需要使用shell變量。

寫你的食譜是這樣的:

@for i in $(notebooks); \ 
do \ 
    f=`echo $$i | cut -d: -f 1`; \ 
    fid=`echo $$i | cut -d: -f 2`; \ 
    echo $$f $$fid $(f1) ;\ 
done 
+0

感謝@MadScientist的解釋。 – user3273016