Подмена процесса с помощью Perl-скрипта

Sep 30 2020

У меня есть сценарий Perl, для которого требуются следующие аргументы:

count.pl OUTPUT_FILE INPUT_FILE

Я хочу использовать замену процесса вместо явного указания INPUT_FILE, например:

count.pl count.txt <(cat test.txt)

Однако похоже, что сценарий не получает никаких входных данных от подстановки процесса.

Что я делаю не так?

Ответы

7 StéphaneChazelas Sep 30 2020 at 18:31

Сценарий использует,-T the-source-file чтобы определить, содержит ли файл текст .

Этот -Tоператор считывает начало файла и использует эвристику, чтобы определить, выглядит он как текст или нет. Но если файл представляет собой конвейер, как в <(...)случае, то прочитанное не может быть прочитано снова.

Вы можете воспроизводить с помощью:

$ perl -e '$file = shift; -T $file; open F, "<", $file; print while <F>' <(seq 1867)

1861
1862
1863
1864
1865
1866
1867

Посмотрите, как -Tизрасходовано 8 КБ, из seqкоторых больше нет данных для while <F>чтения цикла.

Здесь вы можете использовать zsh и его =(...)форму замещения процесса, которая использует временный файл вместо канала. Или (... | psub -f)в fishоболочке. Или удалите этот вызов -Tиз этого сценария. Или перепишите этот сценарий, чтобы он работал с <<>>/ <>(чтобы он также работал на стандартном вводе, если не передавался какой-либо аргумент файла) и выводил на стандартный вывод. Я действительно не вижу смысла использовать имена файлов в качестве аргументов, поскольку он обрабатывает их все в потоковом режиме.