Синтаксис цикла оболочки внутри make-файла if / else - PullRequest
0 голосов
/ 13 сентября 2018

у меня есть цикл, который мне нужно добавить к нему if else statment, если значение == app1 напечатать x, иначе вывести y

Я пробовал со следующим но когда я добавляю else, я получаю синтаксическую ошибку,

что я делаю не так?

runners:
    @for a in $(apps) ; do
       if (( a ==  "app1"));then
        echo first: $$v ;
       else
        echo second: $$v ;
        fi
     done

Ответы [ 4 ]

0 голосов
/ 25 сентября 2018

Будьте осторожны: приведенные выше решения работают только в последней версии "make" (вероятно,> 4). Например, OSX включает в себя Gnu make 3.81. Поэтому вам нужно будет установить более новую марку, используя Homebrew

brew reinstall make --with-default-names
0 голосов
/ 13 сентября 2018

Makefile:

apps=app1 app2

runners:
    @for a in $(apps) ; do \
        if [ $$a = "app1" ]; then \
            echo "first: $$a" ; \
        else \
            echo "second: $$a" ; \
        fi \
    done

который печатает

first: app1
второе: app2

0 голосов
/ 13 сентября 2018

1) Я предпочитаю использовать bash в качестве оболочки, потому что я к этому привык. Поэтому я использую SHELL:=/bin/bash в начале моих make-файлов. Но тогда весь ваш makefile не работает, когда система не предоставляет /bin/bash..

2) Если вы хотите использовать одну и ту же оболочку для всех строк в рецепте, вы можете использовать специальную цель .ONESHELL Это не позволяет вам использовать ;\ после каждой строки без пробелов позади (подвержен ошибкам). Но если вы используете .ONESHELL, то это верно для ВСЕХ рецептов в вашем make-файле (который я использую, но вы, возможно, не захотите).

3) Если runners не является файлом (и, похоже, это так, потому что вы не создаете файл в рецепте), я бы порекомендовал сделать его .PHONY. Это не позволяет make выполнить его, когда есть файл с именем runners.

4) Двойные скобки ((...)) используются для арифметического расширения. Он просто не может сравнивать строки. Используйте одинарные или двойные скобки. Смотрите этот великий пост .

5) Я также думаю, что вы хотели напечатать a и поэтому заменили $$v на $$a.

Итак, в целом, это работает отлично, если у вас есть / bin / bash:

SHELL:=/bin/bash
.ONESHELL:
.PHONY: runners
apps:=app2 app3 app1 app5
runners:
    @for a in $(apps) ; do  <<-- ; between commands as usual
      if [[ "$$a" ==  "app1" ]]; then
        echo first: $$a  <<-- no need for ; because of .ONESHELL
      else
        echo second: $$a
      fi
    done

Вывод:

second: app2
second: app3
first: app1
second: app5
0 голосов
/ 13 сентября 2018

Вы используете просто неправильный синтаксис для sh if / else. И вы должны добавить \ на каждом конце команды, так как все, что выполняется как отдельная команда в оболочке, запускается командой make. Внимание: без пробела после \!

Это должно быть что-то вроде:

runners:
    @for a in $(apps) ; do \
        if [ $$a = "app1" ]; then\
        echo first: $$a ; \
        else \
        echo second: $$a ; \
        fi \
    done

Кстати: вы действительно хотите напечатать $v? Я ожидал бы $a вместо;)

...