[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: zsh



Stanislav Maslovski -> debian-russian@lists.debian.org  @ Fri, 1 Aug 2008 20:06:05 +0400:

 >>  >>  SM> % rm TEST=\'\*\' 
 >>  >>  SM> [shota@stas:/tmp/a]
 >>  >>  SM> % eval `./test`
 >>  >>  SM> zsh: no matches found: TEST='*'
 >>  >>  SM> [shota@stas:/tmp/a]
 >>  >>  SM> % echo "$TEST"  
 >>  >> 
 >>  >>  SM> ================================================================
 >>  >> 
 >>  >>  SM> Ы?
 >>  >> 
 >>  >> man zshexpn
 >>  >> /^COMMAND SUBSTITUTION
 >>  >> последнее предложение
 >> 
 >>  SM> Это хорошо, но почему за паттерн берется целиком TEST='*'?
 >> 
 >> По той же причине, по которой, когда ты пишешь echo .xsession-*, за
 >> паттерн берется целиком .xsession-*.  А что?

 SM> Но ведь из примера видно, что шелл при _найденном_ совпадении вовсе не
 SM> пытается запустить файл "TEST='*'" (и совсем не это у шелла просят),
 SM> а твое объяснение подходит как раз под такую семантику.

При ненайденном совпадении он тоже не пытается его запустить.

 SM> Причем тут no matches found при отсутствии какого-то совершенно
 SM> не имеющего отношения к делу файла? Поясни.

Ты вообще прочел, что такое filename generation?  Судя по вопросу про
паттерн - прочел.

Итак.  Подробно.

man zshexpn
/^COMMAND SUBSTITUTION
Пред-предпоследнее предложение.

If the substitution is not enclosed in double quotes, the output is
broken into words using the IFS parameter.

В твоем случае вывод команды - TEST='*'.  Символов из IFS в нем нет,
поэтому слово получается одно.

Последнее предложение.

In either case, if the option GLOB_SUBST is set, the output is eligible
for filename generation.  

Он у тебя set. Т.е. весь наш вывод, состоящий из одного слова,
подвергается filename generation.

/^FILENAME GENERATION
If a word contains an unquoted instance of one of the characters ‘*’,
‘(’, ‘|’, ‘<’, ‘[’, or ‘?’, it is regarded as a pattern for
filename generation, unless the GLOB option is unset.

В данном случае звездочка unquoted, потому что квотинг работает раньше,
чем command substitution, и апострофы теперь - просто такие символы.
Поэтому слово TEST='*' рассматривается как паттерн, содержащий звездочку
(в командной строке его пришлось бы вводить как TEST=\'*\' - собственно,

zsh% echo TEST='*'
TEST=*
zsh% echo TEST=\'*\'
zsh: no matches found: TEST='*'

).

Читаем дальше.

The word is replaced with a list of sorted filenames that match the
pattern.  If no (тут явно пропущено слово files) matching pattern is
found, the shell gives an error message, ... or unless the NOMATCH
option is unset, in which case the word is left unchanged.

То бишь, если ты в оригинале сделашь не файл TEST='*' (с именем, в
точности соответствующим, так получилось, шаблону), а TEST='111' и
TEST='', то ты получишь два слова в выводе, и ни одно из них не будет
TEST='*'.

При отсутствии же матчащегося файла и установленной опции NOMATCH
(обрати внимание на два отрицания в мане) ты получишь дефолтное
поведение, т.е. error message.

Так понятно?

-- 
Artem Chuprina
RFC2822: <ran{}ran.pp.ru> Jabber: ran@jabber.ran.pp.ru

А еще следует потребовать, чтобы программисты, перед тем, как писать код,
внимательно прочли спецификацию: с сыром - это чизбургер.
	Игус в <Pine.LNX.4.44.0401231840020.15582-100000@moon>


Reply to: