LINUX.ORG.RU

[make] redirection & substitution

 


0

1

WTF? Make (или шелл?) не хочет делать подстановку при редиректе в мейкфайле.

Есть такой мейкфайл:

all:
        cat < a*

Не работает:

% rm a*
% echo test > a1
% make
cat < a*
/bin/sh: a*: No such file or directory
make: *** [all] Error 1

А с таким работает:

all:
        cat a*
% make
cat a*
test

Аналогично, нет подстановки при редиректе вывода:

all:
        echo test > a*

Создается файл a*:

% ls
a*  a1  Makefile
% cat a\*
test

Что характерно, данное поведение наблюдается и с gmake, и с mk. Это фича? Или баг, унаследованный из кода 30-летней давности? Кто-нибудь с таким сталкивался? Я чего-то не знаю?


Ответ на: комментарий от grusha

Мда.

Bourne-like шеллы не хотят раскрывать глобы в неинтерактивном режиме.

Из всех, которые я попробовал (bash, dash, pdksh, tcsh, zsh) данная фича не наблюдается только в zsh.

man bash о неинтерактивном режиме ничего не говорит в данном контексте:

«The word following the redirection operator in the following descriptions, unless otherwise noted, is subjected to brace expansion, tilde expansion, parameter expansion, command substitution, arithmetic expansion, quote removal, pathname expansion, and word splitting. If it expands to more than one word, bash reports an error.»

Однако POSIX говорит:

«If the redirection operator is »<<" or «<<-», the word that follows the redirection operator shall be subjected to quote removal; it is unspecified whether any of the other expansions occur. For the other redirection operators, the word that follows the redirection operator shall be subjected to tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal. Pathname expansion shall not be performed on the word by a non-interactive shell; an interactive shell may perform it, but shall do so only when the expansion would result in one word."

То есть это типа «фича». А в zsh, выходит, типа «баг», раз его поведение (по крайней мере, дефолтное) нестандартно, хоть и разумно.

grusha
() автор топика
Ответ на: комментарий от grusha

Вообще-то, фича опасная: в том же zsh (поцелуй злобного буратины)

:>|*

Ни к чему хорошему не приведет.

anonymous
()
Ответ на: комментарий от anonymous

Речь не о MULTIOS, а о полном запрете на pathname expansion в редиректе, в неинтерактивном режиме. Таки не вижу в этом смысла. От чего это защищает?

Bourne-шеллы вообще опасны. Надо юзать rc, там таких проблем не возникает.

% rc
; ls
a*  a1  Makefile
; cat a1
test1
; cat 'a*'
test2
; f='a*'
; cat < $f
test2

Сравни с:

% sh
sh-4.2$ ls
a*  a1  Makefile
sh-4.2$ cat a1
test1
sh-4.2$ cat 'a*'
test2
sh-4.2$ f='a*'
sh-4.2$ cat < $f
sh: $f: ambiguous redirect
sh-4.2$ f='a\*'
sh-4.2$ cat < $f
sh-4.2$ f='a\*'
sh-4.2$ cat < $f
sh: a\*: No such file or directory
sh-4.2$ f=«a*»
sh-4.2$ cat < $f
sh: $f: ambiguous redirect
sh-4.2$ f=«a\*»
sh-4.2$ cat < $f
sh: a\*: No such file or directory

Как с этим вообще жить можно?

grusha
() автор топика
Ответ на: комментарий от grusha

Или вот банальное:

% touch 'filename with spaces'
% for f in *; do ls -l $f; done
-rw-r--r-- 1 mitya users 6 Mar  3 17:23 a*
-rw-r--r-- 1 mitya users 6 Mar  3 17:23 a1
-rw-r--r-- 1 mitya users 6 Mar  3 17:23 a1
ls: cannot access filename: No such file or directory
ls: cannot access with: No such file or directory
ls: cannot access spaces: No such file or directory
-rw-r--r-- 1 mitya users 49 Mar  3 14:32 Makefile
% rc
; for (f in *) ls -l $f
-rw-r--r-- 1 mitya users 49 Mar  3 14:32 Makefile
-rw-r--r-- 1 mitya users 6 Mar  3 17:23 a*
-rw-r--r-- 1 mitya users 6 Mar  3 17:23 a1
-rw-r--r-- 1 mitya users 0 Mar  3 17:53 filename with spaces

А разгадка одна: в rc базовый (единственный) тип данных - не строка, как в sh, а список строк. Что вполне логично: шелл работает с командами, а команда - это нифига не строка, а список строк (список аргументов). Попытка трактовать ее как строку приводит к жутким несуразностям и костылям.

grusha
() автор топика
Ответ на: комментарий от grusha

От чего это защищает?

Для вывода есть tee, пример когда globbing нужен сходу придумать не могу, а при опечатке можно потереть все файлы в директории.

А для ввода можно и cat. Спорный, конечно, момент, но не такой уж принципиальный.

rc и создан был попозже, на тот момент небось и tcl был (там строки тоже гибче).

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.