Почему два открытых аргумента в Perl, кажется, лишают строки?

Когда я вызываю Perl's Two-Arg open() с именем файла, содержащим завершающий символ новой строки, символ новой строки игнорируется. Однако версия с тремя аргументами сохраняет символ новой строки.

Почему поведение отличается? Почему новая строка якобы удалена?

- Файл "nl" не существует. Сделай это

 $ ls -1 nl; коснитесь nl; лс -1 нл
ls: nl: Нет такого файла или каталога
п 

- Попробуйте открыть в трех аргументах "nl \ n" → ENOENT

strace показывает поведение, которое я ожидаю, FWIW.

 $ perl -E 'открыть (F, "<", "nl \ n") или умереть $!'
Нет такого файла или каталога в строке -e 1.

$ strace -e trace = open perl -E 'открыть (F, "<", "nl \ n") или умереть $!' 2> & 1 | grep nl
open ("nl \ n", O_RDONLY | O_LARGEFILE) = -1 ENOENT (нет такого файла или каталога) 

- Теперь попробуйте открыть два аргумента "nl \ n" → success?

 $ perl -E 'открыть (F, "nl\n") или умереть $!' 

-- Какие? Почему это работает? Давайте посмотрим на Strace.

О, это игнорирование новой строки:

 $ strace -e trace = open perl -E 'открыть (F, "nl\n") или умереть $!' 2> & 1 | grep nl
open ("nl", O_RDONLY | O_LARGEFILE) = 3 

- "NL" по-прежнему единственный файл там

 $ ls 
п 

Фон:

 $ perl -v 

Это Perl 5, версия 16, Subversion 0 (v5.16.0), созданная для i686-linux-thread-multi.

2 ответа

Решение

http://perldoc.perl.org/perlopentut.html:

Другая важная вещь, на которую следует обратить внимание, это то, что, как и в оболочке, любые пробелы до или после имени файла игнорируются. Это хорошо, потому что вы не хотите, чтобы они делали разные вещи:

open INFO, "<datafile"
open INFO, "< datafile"
open INFO, "< datafile"

Это не ошибка, а особенность. Поскольку open имитирует оболочку в своем стиле использования стрелок перенаправления для указания способа открытия файла, он также делает это в отношении дополнительных пробелов вокруг самого имени файла. Для доступа к файлам с непослушными именами, см. Разгон Двемера.

Существует также версия open с тремя аргументами, которая позволяет помещать специальные символы перенаправления в их собственный аргумент:

...

В этом случае открываемое имя файла является фактической строкой в $datafileтак что вам не нужно беспокоиться о $datafile содержит символы, которые могут повлиять на режим открытия, или пробелы в начале имени файла, которые будут включены в версию с двумя аргументами. Кроме того, любое сокращение ненужной строковой интерполяции - это хорошо.

Это довольно просто: потому что 2-арг openСинтаксис аппроксимирует оболочку даже до точки разрешения каналов.

Другие вопросы по тегам