Если с правой стороны конвейера находится командлет или что-то, что выполняется внутри процесса Powershell, промежуточные результаты записываются по мере их готовности. Однако, если правая часть конвейера представляет собой программу, то это не тот случай, когда обе программы в конвейере выполняются одновременно. Почему это так? Есть ли способ запустить несколько внешних программ в конвейере таким образом, чтобы получить промежуточные результаты?
У меня есть сценарий Perl, который рекурсивно пересекает все каталоги, начиная с текущего каталога, и печатает пути.
pfind.bat
- это пакетный скрипт, который исполняет себя как скрипт perl, используя каламбур, аналогичный каламбуру в Unix-подобных системах✱.
@ REM = (<<'REM');
@ perl.exe %0 %*
@ goto :EOF
REM
undef @REM;
use strict;
use warnings;
use File::Find;
*STDERR = *STDOUT;
sub print_it {
printf "%s\n", $File::Find::name;
return 1;
}
find(\&print_it, q[.]);
Тем не менее, он печатает файлы с /
в качестве разделителей вместо \
, если я использую foreach
или его сокращение %
для выполнения замены путем сопоставления выражения над строками, а затем строки вывода из pfind
индивидуально преобразуются по мере их излучения.
PS C:\> pfind | % {$_.replace("/", "\")}
.
.\hiberfil.sys
.\pagefile.sys
.\swapfile.sys
Однако, если я попытаюсь сделать то же самое, используя perl.exe
, никакой вывод не будет получен, пока весь вывод не будет прочитан
PS C:\> pfind | perl.exe -pe 's,/,\\,g'
долгое время ничего не производит.
Прежде всего, почему process1 | process2
не дает промежуточных результатов при запуске под Powershell?
Во-вторых, похоже, что командлеты дают промежуточные результаты, потому что они выполняются внутри процесса Powershell. Существует ли командлет какой-либо формы, который можно использовать для потокового вызова внешних процессов в конвейере, т. Е. Можно ли написать Do-Pipeline 'pfind.bat' 'perl.exe -pe "s,/,\\,g"'
или что-то похожее на прямой Powershell для настройки конвейера?
Шебанг каламбур
#!/bin/sh
#! -*-perl-*-
eval 'exec perl -x -wS $0 ${1+"$@"}'
if 0;