Я нахожу это очень аккуратным, но я недостаточно вовлечен, чтобы понять, что происходит.
Кто-нибудь знает, почему такое поведение существует в zsh или что zsh пытается сделать, что вызывает segfault?
➜ ~ (echo "hi"(); echo "hi"; echo "hi")
[1] 65962 segmentation fault ( echo "hi" () { ... }; echo "hi"; )
➜ ~ (ls(); ls; ls)
[1] 66073 segmentation fault ( ls -G () { ... }; ls -G; )
Я помещаю его в подпроцесс, чтобы он распечатывал, что происходит; иначе, если вы, например, запустите ls()
, затем заполните function>
с помощью ls
, затем снова запустите ls, он крашит терминал.
Это происходит только тогда, когда вы пытаетесь переопределить функции сами с собой, например, echo str1(); echo str2
, но не ls(); echo str
. Это работает не со всеми возможными входными данными, а только из-за разбора синтаксиса, например, хотя:
➜ ~ (^A(); ^A; ^A)
[1] 66154 segmentation fault ( ^A () { ... }; ^A; )
это не работает по причинам синтаксиса, если вы запускаете его построчно:
➜ ~ ^A()
zsh: substitution failed
Как ни странно, такое поведение происходит:
➜ ~ a()
function> 7
➜ ~ a
a:cd:3: no such entry in dir stack
➜ ~ 8()
function> b
➜ ~ 8
cd:7: command not found: b
➜ ~ 9()
function> 13
➜ ~ 9
cd:6: command not found: 13
НО
➜ ~ 9()
function> 5
➜ ~ (9)
[1] 66979 segmentation fault ( cd -9; )
что привело бы к сбою терминала, если бы не в подпроцессе, а это означает, что вы можете определить однозначное число как функцию, которая ведет к двузначному числу, но не к однозначному! Это эквивалентно буквам (c(); a
— это ошибка сегментации, c(); bh
— «команда не найдена»). 71(); 81; 71;
тоже не вызывает segfault.
Мне очень любопытно, что происходит под капотом! Это обеспечивает неприятный способ возиться с людьми, так как положить
echo $JAVA_HOME()
echo "hi"
in .zshrc
приведет к сбою терминала, даже если кто-то попытается использовать $JAVA_HOME только, скажем, в назначении переменной, это вызовет segfault, например,
➜ ~ ($JAVA_HOME)
[1] 66745 segmentation fault ( $JAVA_HOME; )
➜ ~ (X= $JAVA_HOME)
[1] 66737 segmentation fault ( X= $JAVA_HOME; )
Возможно, это также требует исправления в будущем, так как я могу представить, что это может быть использовано в грубых целях. Это известная проблема?
Это не работает в bash из-за того, как bash анализирует определения функций.
(echo hi(); echo hi; echo hi)
может быть ошибкой, но насчет однозначных и двузначных чисел: вероятно, все ваши однозначные числа имеют псевдонимcd +$digit
(илиcd -$digit
). Проверьтеalias 1
,alias 2
, ...,alias 9
, и вы поймете, что это уловка вашей конфигурации (в Prezto этоdirectory
). Тем не менее мне неясно, почему это может привести к segfault; наверное тоже баг. Сообщите об этом по адресу [email protected]. - person 4ae1e1   schedule 11.11.2015