С двойными кавычками вы позволяете оболочке сначала интерполировать переменные.
Как вы можете проверить, $_
и $a
не установлены в подоболочке, разветвленной для канала родительской оболочкой. См. Комментарий к $_
ниже.
Таким образом, версия с двойными кавычками эффективно
echo "puke|1|2|3|puke2" | perl -lne 'chomp;@a=split(/\|/);print [4];'
что печатает ссылку на массив [4]
.
Комментарий о последствиях воздействия $_
на Bash. Спасибо Бородину за то, что подняли этот вопрос.
$_
- одна из немногих специальной оболочки. параметры в Bash. Он содержит последний аргумент предыдущей команды или путь к тому, что вызвало оболочку или команды (через переменную среды _
). См. Ссылку для полного описания.
Однако здесь он интерпретируется в подоболочке, разветвленной для запуска первой команды perl
. Судя по всему, это даже не установлено, как видно с
echo hi; echo hi | echo $_
который печатает пустую строку (после первого hi
). Причина может заключаться в том, что переменная среды _
просто не установлена для подоболочки для канала, но я не понимаю, почему это так. Например,
echo hi; (echo $_)
печатает две строки с hi
, хотя ( )
запускает подоболочку.
В любом случае $_
в данном конвейере не задано.
Часть split
тогда split(/\|/)
, поэтому по умолчанию split(/\|/, $_)
- нечего разделять. С добавлением -w
это действительно выводит предупреждение об использовании неинициализированного $_
.
Обратите внимание, что это поведение зависит от оболочки. tcsh
вообще не запускает это с двойными кавычками. В ksh
и zsh
последняя часть конвейера выполняется в основной оболочке, а не в подоболочке, поэтому $_
присутствует.
person
zdim
schedule
11.05.2017
$_
, поэтому эта часть будет неточной. (Хотя в реальной проблеме, конечно, данные могут вообще не передаваться по конвейеру.) - person zdim   schedule 12.05.2017