Курс языка программирования Raku / Объекты, ввод-вывод и исключения / Ввод и вывод / Запуск внешних программ 🆕
Захват вывода
Чтобы прочитать то, что печатает внешняя программа, а не отпускать
это на экран, передайте при запуске :out. У возвращённого
Proc появится дескриптор .out, из которого
можно читать:
my $proc = run 'echo', 'hello', :out;
my $output = $proc.out.slurp(:close);
say $output.chomp; # hello:out перенаправляет стандартный вывод программы в
Proc. Дескриптор .out работает так же, как
файловые дескрипторы из предыдущего раздела, а .slurp
читает из него всё сразу. Наречие :close — удобное
сокращение: после чтения оно закрывает дескриптор за вас, то есть
выполняет ту же уборку, которую вы делали явным .close у
файлового дескриптора, — так ничего не остаётся открытым. Наконец,
.chomp убирает завершающий перевод строки, который
добавляет echo.
То же работает и с shell, что удобно для перехвата
результата конвейера:
my $proc = shell 'echo hello | tr a-z A-Z', :out;
say $proc.out.slurp(:close).chomp; # HELLOПерехватить можно и поток ошибок — с помощью :err и
соответствующего дескриптора .err. Если передать и
:out, и :err, потоки останутся раздельными,
каждый в своём дескрипторе, и их можно читать по отдельности:
my $proc = run 'sh', '-c', 'echo out-line; echo err-line >&2', :out, :err;
say 'stdout: ', $proc.out.slurp(:close).chomp; # stdout: out-line
say 'stderr: ', $proc.err.slurp(:close).chomp; # stderr: err-lineЗдесь команда оболочки печатает одну строку в стандартный вывод и
одну — в стандартный поток ошибок (>&2
перенаправляет туда). Поскольку мы запросили оба потока,
.out и .err держат их независимо: обычный
вывод программы не смешивается с её диагностикой.
Захват вывода — это способ использовать внешнюю программу как строительный блок: запустить её, прочитать результат и продолжить работать с этими данными в собственной программе.
Навигация по курсу
← Тест — Запуск программ | Объект Proc →
💪 Или перейдите сразу к упражнениям этого
раздела.