2017-02-12 10 views
0

У меня проблема с строкой кода в моем Makefile, который хорошо работает в /bin/bash. Я знаю, что Make работает в /bin/sh, поэтому у меня есть solved that problem with this guide, объявив, что я хочу, чтобы он запускался в Bash. Однако, несмотря на то, что я запускаю Make in Bash, я все еще не могу заставить эту строку работать, даже жестко она работает в Bash просто отлично.Почему не будет поддержки bash! (...) при выполнении через make (w/SHELL: =/bin/bash)?

Почему Bash выдает ошибку при запуске rm -f !(2).txt в Makefile, но не при выполнении в своей оболочке?

EDIT: Я ищу, чтобы удалить все файлы с определенным расширением файла, за исключением одного из этих файлов. Команда rm -f !(2).txtdoes just that в моем терминале bash, но не в Make.

EDIT: При запуске rm -f !(2).txt «нормально» в терминале с Баш (терминал возвращается bash при выдаче команды echo "$0") он работает просто отлично, но сывороточный я бегу /bin/bash -c 'rm -f !(2).txt' я получаю ту же ошибку, что и в Makefile.

Makefile

all: clean 

clean: SHELL:=/bin/bash 
clean: 
    rm -f !(2).txt 

Запуск команды в Bash

$ ls 
1.txt 2.txt 3.txt 4.txt Makefile # Directory has all text files 
$ rm -f !(2).txt      # Remove all text files but 2.txt 
$ ls 
2.txt Makefile       # Only 2.txt is not removed 

Запуск команды в Bash через Makefile

$ ls         # Directory has all text files 
1.txt 2.txt 3.txt 4.txt Makefile 
$ make clean       # Running make 
rm -f !(2).txt 
/bin/bash: -c: line 0: syntax error near unexpected token `(' 
/bin/bash: -c: line 0: `rm -f !(2).txt' 
make: *** [clean] Error 1 
+2

Вам также нужно «shopt -s extglob». – choroba

+0

Если я запускаю вашу команду из оболочки, она терпит неудачу так же, как при вызове из make: '/ bin/bash -c 'echo! (2).txt'' -> '/ bin/bash: -c: строка 0: синтаксическая ошибка около неожиданного токена '('' – MadScientist

+0

@MadScientist Weird. Запуск так, как вы закончили с той же ошибкой. Однако запуск его только в моем терминал возвращает мне ожидаемый результат. Мой терминал возвращает 'bash', когда я запускаю' echo '$ 0 "', так что может быть hickup? –

ответ

2

Вам необходимо включить опцию extglob оболочки для того, чтобы сделать он работает. В GNU сделать, это может быть достигнуто за счет

SHELL := /bin/bash 
.SHELLFLAGS := -O extglob -c 

Edit на вопрос автора

пример с двумя рядами выше код не работает для меня, но, как this fellow found out, кажется, быть другим решением в зависимости от версий.

Хм. По какой-то причине .SHELLFLAGS не работал для меня, но помещал флаги непосредственно в SHELL=/bin/bash -O extglob -c. [...] - Timothy Jones

Пример @choroba использует работы в Make 4.0, но не работает для меня, так как у меня есть Make 3.81. Однако, вот мое решение:

all: clean 

clean: SHELL=/bin/bash -O extglob -c 
clean: 
    rm -f !(2).txt 
+0

Хорошо, но я все еще получаю сообщение об ошибке. ... 'чистый: SHELL: =/бен/Баш чистые: .SHELLFLAGS: = -O extglob -c чистый: \t гт -f (2) .txt' ... и я! та же ошибка –

+0

@PetterKarkea: Это работает для меня. Какую версию Make и bash вы используете? – choroba

+0

Bash 4.3.11 (1) -release, GNU M ake 3.81 –

0

Марка не имеет представления о том, что означает, что если вы действительно должны использовать эту конструкцию, а затем использовать функцию $ (оболочки) "(2) .txt!":

%(shell rm -f !(2).txt) 

Лично я бы изменил схему имен файлов или создал имена файлов, которые вы хотите удалить, в переменной make.

+1

'! (2) .txt' не означает что-либо для bash по умолчанию, поэтому он не будет работать в '% (shell ...)' без подготовки, описанной в ответе Хоробы. –