2013-03-23 112 views
2

我可能很笨,但我不能在我的Makefile中做最基本的變量賦值。makefile將命令分配給

TEST = $(pwd); 

all: 
    echo $(TEST) 

了FreeBSD(9.1)當我運行 「讓所有」 從巴什(v4.2.42)我得到:

echo 

不知道我搞砸了。我也嘗試使用$(shell ...)分配變量,獲得相同的結果。

如果我使用back tick(`),那麼基本賦值工作,但它不存儲結果,它存儲命令。這打破了下面的例子中的Makefile:

SERVERIP = `ifconfig em0 | grep -E 'inet.[0-9]' | awk '{ print $$2}'` 

all: 
    echo $(SERVERIP) 
    sed -e 's/%LISTENIP%/${SERVERIP}/g' test.conf > work/test.conf.tmp 

結果是:

[[email protected]] ~/make 
echo `ifconfig em0 | grep -E 'inet.[0-9]' | awk '{ print $2}'` 
10.128.28.151 
sed -e 's/%LISTENIP%/`ifconfig em0 | grep -E 'inet.[0-9]' | awk '{ print $2}'`/g' test.conf > work/test.conf.tmp 
sed: 1: "s/%LISTENIP%/`ifconfig ...": unescaped newline inside substitute pattern 
*** [all] Error code 1 

你可以看到,基本的變量賦值似乎工作,但是當你插入的結果到sed的,它插入整命令而不是結果,這打破了!

任何想法?

皮特。

回答

4

生成文件包含:

TEST = $(pwd); 

all: 
    echo $(TEST) 

第一行分配在make可變pwd加上值分號make可變TEST。然後規則迴應。您忘記了,我認爲$(...)makeshell都是重要的。假設你要呼應pwd命令的輸出,然後用雙美元這樣make擴展了到一元:

TEST = $$(pwd) 

all: 
    echo $(TEST) 

爲了得到一個shell命令的輸出到一個make變量,你必須使用GNU make擴展。有兩種擴展名::=即時分配,用於在定義點評估SERVERIP的值,而不是在使用點;和$(shell ...cmd...),用於運行shell命令並捕獲其輸出。

SERVERIP := $(shell ifconfig em0 | grep -E 'inet.[0-9]' | awk '{ print $$2}') 

all: 
    echo ${SERVERIP} 
    sed -e 's/%LISTENIP%/${SERVERIP}/g' test.conf > work/test.conf.tmp 

這應該有效。原始錯誤,關於sed正則表達式中的換行符很奇怪; back-ticks應該已經從ifconfig管道的輸出中刪除了尾隨的換行符。但是,如果實際上有多行返回,那麼您仍然在裏面有一個換行符,證明sed的投訴是正確的。

這產生了抱怨:

SERVERIP = `printf "%s\n" a b c` 

all: 
    echo $(SERVERIP) 
    sed -e "s/%LISTENIP%/${SERVERIP}/g" test.conf > work/test.conf.tmp 

這工作:

SERVERIP = `printf "%s\n" c` 

all: 
    echo $(SERVERIP) 
    sed -e "s/%LISTENIP%/${SERVERIP}/g" test.conf > work/test.conf.tmp 

由於您使用FreeBSD的,它很可能是你沒有GNU make做。在這種情況下,您需要:

  1. 確保ifconfig命令管道只生成一行輸出。
  2. 使用make命令是這樣的:

    SERVERIP = `ifconfig em0 | grep -E 'inet.[0-9]' | awk '{ print $$2}'` 
    
    all: 
        echo ${SERVERIP} 
        sed -e "s/%LISTENIP%/${SERVERIP}/g" test.conf > work/test.conf.tmp 
    

    應與所提供的條件1被滿足的make任何版本。

+1

我在第二個例子(sed)上測試了它,但它實際上並沒有提供命令的值,而是命令本身,它打破了sed。即與上面相同的結果。 – Pete 2013-03-23 14:42:35

+0

謝謝你的配偶。我複製了:=例子,但不幸的是它回顯了一個空行,sed替換了LISTENIP標記。 – Pete 2013-03-23 15:26:37

+0

你在FreeBSD上?也許你沒有GNU'make'?我確實指出,解決方案是使用GNU'make'擴展到'make'。 – 2013-03-23 18:14:56

1

這是一個測試makefile,類似於你的。 ifconfig命令已放置在$(shell ...)命令中,結果存儲在SERVERIP中。

TOP:= $(shell pwd) 
SERVERIP:= $(shell ifconfig en1 | grep -E 'inet.[0-9]' | awk '{ print $$2}') 
LISTENIP:=240.12.4.63 

all: 
    echo $(SERVERIP) 
    sed -e 's/$(LISTENIP)/$(SERVERIP)/g' test.conf > work/test.conf.tmp 
+0

我將其完全複製到一個空白的Makefile中,但echo((SERVERIP))實際上並沒有產生任何輸出。如果我在shell中運行該命令,它會返回一個IP。這可能是我的服務器配置中的怪癖嗎? – Pete 2013-03-23 14:40:19

+0

哦,我認爲只是我的網絡接口名稱與您的不同。抱歉,我忘了將其更改回您的界面名稱。你的em0我en1。 – suspectus 2013-03-23 14:52:51

+0

是的,我改變了,但仍然沒有喜悅。運行下面的Makefile會返回一個空行(顯示echo命令本身之後): @SERVERIP = $$(ifconfig em0 | grep -E'inet。[0-9]'| awk'{print $$ 2}') 全部: echo $(SERVERIP) – Pete 2013-03-23 15:01:39

1

也許答案太晚了,但我希望我能幫助(別人)。

如果你不想安裝GNU的make可以使用!=

TEST!=pwd 
all: 
    echo ${TEST} 

會工作。解釋很簡單,請仔細閱讀FreeBSD's man make,尤其是「變量賦值修飾語」「變量賦值」裏面部分:

變量賦值修飾符

五大運營商可用於將值分配給變量 如下:...

!=展開值並將其傳遞給shell執行,並將結果賦給變量。結果 中的任何換行符都用空格替換。

+0

不錯!我不知道。晚得比從未好:)謝謝。 – Pete 2016-12-30 15:08:03

+0

不客氣:) – uzsolt 2016-12-30 17:29:23