Как перенаправить вывод одной команды в _аргумент_ другой команды? — Хабр Q&A

Почему << (here document) и <<< (here string) нельзя использовать с переменными

Если мы захотим присвоить переменной значение с помощью рассмотренных операторов и попробуем выполнить:

a <<< 'just a string'

или

a <<< _EOF_

то будет получена ошибка:

bash: a: команда не найдена


Причина в том, что нельзя присвоить значение переменным передав данные в стандартном вводе. Например команда

&>

Последние версии bash предоставляют второй, более упрощённый метод для выполнения комбинированного перенаправления 2>&1:

ls -l /bin/usr &> ls-output.txt

В этом примере мы используем одинарную запись &> для перенаправления как стандартного вывода, так и стандартной ошибки в файл ls-output.txt.

&>>


Вы также можете добавить стандартные выходные данные и стандартные потоки ошибок в один файл, например так:

ls -l /bin/usr &>> ls-output.txt

Итак, &> является аналогом 2>&1, а &>> это то же самое, но с перенаправлением вывода в файл.

> /dev/null

Это частный случай перенаправления, когда всё из стандартного вывода перенаправляется в псевдоустройство /dev/null. Это означает уничтожение данные. То есть ничего не будет выводиться в стандартный вывод.

>>

Функция оператора >> похожа на > с тем отличием, что оператор >> не удаляет содержимое файла, а дописывает новые данные к уже существующим.

Если файл не существует, то оператор >> создаст его и запишет в него переданные данные.

>(команда)


Это ещё одна форма «подстановки процессов» (Process Substitution):

>(КОМАНДА)

Если используется эта форма, то вместо записи в файл, данные будут переданы на ввод для КОМАНДЫ.

<<

Оператор << называется here document. С его помощью можно ввести строку состоящую из нескольких строк или присвоить переменной многострочное значение.

Если в консоль ввести

a=строка

и нажать Enter, то переменной a будет присвоено значение «строка» и вновь станет доступно приглашение командной строки, потому что Enter по умолчанию является разделителем, символом новой строки. Из-за этого не получится ввести многострочное значение.

Оператор << (here document) меняет это правило — обозначением для новой строки становится другая последовательность символов. В качестве такого обозначения можно выбрать любой набор символов, единственное условие — этот набор не должен встречаться в водимых данных.


К примеру:

cat <<_EOF_

Данная запись означает, что запущена команда cat, после неё идёт оператор << и последовательность символов _EOF_. Эти символы (_EOF_) Enter означают, что _EOF_ – становится обозначением начала и конца для многострочных данных.

Второй ввод _EOF_ Enter означает конец многострочных данных. После этого будет выполнена команда, то есть будут выведены введённые цифры:

cat <<_EOF_
1
2
3
_EOF_


Если вы хотите переменной присвоить многострочное значение, то это можно сделать примерно так:

a=`cat <<_EOF_
1
2
3
_EOF_
`

Выведем значение переменной:

<<<

Оператор <<< называется here string. Он передаёт с правой стороны стандартный ввод. Чтобы было понятно, следующие команды эквивалентны:

wc <<< 'just a string'
 1  3 14

'just a string' | wc
      1       3      14

<(команда)

Конструкция <(КОМАНДА) называется «подстановка процессов» (Process Substitution). В качестве КОМАНДА может быть одна или более команд с аргументами. Конструкция

вернёт имя специального файла, прочитав который можно получить вывод КОМАНДЫ.


К примеру:

2> >(команда) > /dev/null

Эка комбинация, включающая в себя 3 уже рассмотренных элемента:

  • 2> означает перенаправление стандартного вывода ошибок (stderr)
  • >(КОМАНДА) означает подстановку процессов, в результате стандартный вывод ошибок будет передан для обработки в КОМАНДУ
  • > /dev/null означает перенаправления стандартного вывода в /dev/null, то есть фактическое уничтожение стандартного вывода

Пример практического использования:

curl -v 100.19.18.59 2> >(grep -o -i -E '401 Unauthorized') > /dev/null

2>&1

Конструкция 2>&1 предназначена для перенаправления стандартного вывода и стандартного вывода ошибок в один файл.

В некоторых случаях мы можем захотеть записать весь вывод команды в один файл. Чтобы сделать это, мы должны одновременно перенаправить как стандартный вывод, так и стандартный вывод ошибок. Есть два способа сделать это. Во-первых, традиционный способ, который работает со старыми версиями оболочки:

ls -l /bin/usr > ls-output.txt 2>&1

Используя этот метод, мы выполняем два перенаправления. Сначала мы перенаправляем стандартный вывод в файл ls-output.txt, а затем перенаправляем дескриптор файла 2 (стандартная вывод ошибок) на дескриптор файла один (стандартный вывод), используя обозначения 2>&1.

Обратите внимание, что порядок перенаправлений является значительным. Перенаправление стандартной ошибки всегда должно происходить после перенаправления стандартного вывода, иначе оно не работает. В приведённом выше примере

>ls-output.txt 2>&1

перенаправляет стандартную ошибку в файл ls-output.txt, но при изменении порядка на

2>&1 >ls-output.txt

стандартная ошибка направлена на экран.

Cat > файл <<_eof_


Эта конструкция может показаться очень замысловатой, но она состоит из двух уже рассмотренных элементов:

  • > (перенаправление вывода в файл)

Рассмотрим пример:

cat > ФАЙЛ <<_EOF_
foo
bar
bar bar
foo foo
_EOF_

В результате выполнения этого кода, в ФАЙЛ будут записаны строки

foo
bar
bar bar
foo foo

Причём если ФАЙЛ уже существует, то он будет стёрт и заменён указанным содержимым.


То есть это один из способов сохранения в файл многострочного вывода.

Cat >> файл <<_eof_

Эта конструкция похожа на предыдущую, в ней используются

  • >> (перенаправление вывода в файл с дописыванием данных)

В результате выполнения следующего кода:

cat >> ФАЙЛ <<_EOF_
foo
bar
bar bar
foo foo
_EOF_


В ФАЙЛ будут сохранены строки:

foo
bar
bar bar
foo foo

Причём если ФАЙЛ уже существует, то он будет дописан.

Cat <<_eof_ > файл

Данная конструкция получает многострочный ввод по стандартному вводу и сохраняет его в файл. То есть это аналог

cat > ФАЙЛ <<_EOF_

в котором просто операторы поменяны местами.


К примеру, в следующем примере:

cat <<_EOF_ > num.txt
12345
67890
1011121314
_EOF_ 

В файл num.txt будут сохранены строки

12345
67890
1011121314

Cat <<_eof_ >> файл

Эта запись является аналогом

cat >> ФАЙЛ <<_EOF_

Следующим код

cat <<_EOF_ >> num.txt
12345
67890
1011121314
_EOF_

допишет файл num.txt строками

12345
67890
1011121314

Связанные статьи:

Example

The command dir file.xxx (where file.xxx does not exist) will display the following output:

Volume in drive F is Candy Cane Volume Serial Number is 34EC-0876

File Not Found

If you redirect the output to the NUL device using dir file.xxx > nul, you will still see the error message part of the output, like this:

File Not Found

To redirect (only) the error message to NUL, use the following command:

dir file.xxx 2> nul

Or, you can redirect the output to one place, and the errors to another.

dir file.xxx > output.msg 2> output.err

You can print the errors and standard output to a single file by using the “&1” command to redirect the output for STDERR to STDOUT and then sending the output from STDOUT to a file:

dir file.xxx 1> output.msg 2>&1

Summary

When redirecting output from an application using the ‘>’ symbol, error messages still print to the screen. This is because error messages are often sent to the Standard Error stream instead of the Standard Out stream.

:/>  Удаление двойных кавычек из переменных в пакетном файле создает проблемы со средой CMD

Output from a console (Command Prompt) application or command is often sent to two separate streams. The regular output is sent to Standard Out (STDOUT) and the error messages are sent to Standard Error (STDERR). When you redirect console output using the “>” symbol, you are only redirecting STDOUT.

Автодополнение путей файлов

В командной строке Windows можно выполнять подстановку имен файлов и каталогов при нажатии клавиши Tab. Например, для перехода, в каталог с длинным именем Program Files наберите начальную часть имени каталога

CD Pro и нажмите Tab. В строке ввода должна появиться команда :

CD “Program Files”

Как видим, выполняется подстановка недостающей части имени каталога, а в тех случаях, когда в нем имеется символ пробела, добавляются еще и двойные кавычки.

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

В чём различие << (here document) и <<< (here string)

Различие между этими операторами в том, что << передаёт многострочные данные, которые обрамляются указанной последовательностью символов, а <<< передаёт только строку.

Дублирование дескрипторов

Оператор перенаправления «&» дублирует выходные или входные данные с одного заданного дескриптора на другой заданный дескриптор. Например, для отправки выводных данных команды dir в файл File.txt и отправки ошибки вывода в файл File.txt введите:

dir>c:file.txt 2>&1

При дублировании дескриптора происходит копирование всех его исходных характеристик. Например, если дескриптор доступен только для записи, то все его дубликаты будут доступны только для записи. Нельзя продублировать дескриптор с доступом только для чтения в дескриптор с доступом только для записи.

Запуск командной строки.

Для запуска командной строки можно воспользоваться одним из следующих способов:

Пуск – Выполнить (или клавиши Win R) введите cmd и нажмите клавишу Enter;

Пуск – Все программы – Стандартные – Командная строка»;

Пуск – Поиск – Командная строка.
Также, для запуска командной строки можно использовать заранее подготовленный ярлык, ссылающийся на исполняемый файл %SystemRoot%system32cmd.exe ( обычно – C:Windowssystem32cmd.exe).

Использование буфера обмена.

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

В режиме выделения мышью, контекстное меню не используется, а текст выделяется с использованием левой кнопки мышки. Копирование и вставка выполняется при нажатии правой кнопки мышки.
При включенном режиме ”Разрешить сочетания клавиш с CONTROL”, можно использовать стандартные сочетания клавиш:

– CTRL C (CTRL Insert) – скопировать выделенный текст.

– CTRL V (Shift Insert) – вставить выделенный текст.

Использование истории команд и горячих клавиш.

Для вызова ранее введенных команд используются клавиши со стрелками Стрелка Вверх – на одну команду назад и Стрелка Вниз – на одну команду вперед. Кроме того, можно использовать функциональные клавиши:

F1 – посимвольный вызов последней введенной команды. Каждое нажатие F1 приводит к последовательной подстановке в поле ввода одного символа из предыдущей команды.

Использование оператора канала (|)

Оператор канала «вертикальная линия» (|) забирает выходные данные одной команды (по умолчанию STDOUT) и направляет их на вход другой команды (по умолчанию STDIN). Например, следующая команда сортирует каталог:

dir | sort

В данном примере обе команды запускаются одновременно, но команда sort приостанавливает работу до получения выходных данных команды dir. Команда sort использует выходные данные команды dir в качестве своих входных данных, а затем свои выходные данные отправляет в дескриптор 1 (STDOUT).

Используйте операторы перенаправления в пакетных файлах

Операторы перенаправления работают в пакетных файлах, включая команду так же, как в командной строке:

Выше приведен пример того, как создать пакетный файл, который использует оператор перенаправления с командой tracert .

Yahootracert.txt файл (показано выше) будет создан на Z: диск через несколько секунд после выполнения sample.bat файла.

Как использовать операторы перенаправления

Самый простой способ научиться использовать эти операторы перенаправления — это посмотреть несколько примеров:

ipconfig / all> mynetworksettings.txt
Перенаправление результатов ‘ipconfig’ в файл TXT.

Настройка командной строки.

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

:/>  Скачать Restore Point Creator Rus для Windows 10 (бесплатно)

Страница, посвященная настройкам командного процессора CMD

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

Объединение нескольких команд в цепочку

В командной строке Windows существует возможность последовательного выполнения нескольких команд в зависимости от результатов их выполнения. Для чего используются символы объединения команд – & (амперсанд) и | (вертикальная черта)

& – одиночный амперсанд используется для разделения нескольких команд в одной командной строке. Например:

Оператор добавления перенаправления

Оператор двойной стрелки добавляет, а не заменяет файл:

ipconfig / all >> \ server  files  officenetsettings.log
Добавление результатов «ipconfig» в существующий файл журнала.

В этом примере используется оператор перенаправления >>, который работает почти так же, как оператор > , но вместо перезаписи выходного файла, если он существует, он добавляет вывод команды в конец файла.

Вот пример того, как может выглядеть этот файл LOG после экспорта в него команды:

Файл журнала результатов командной строки.

Оператор перенаправления >> полезен, когда вы собираете похожую информацию с разных компьютеров или команд и хотите, чтобы все эти данные были в одном файле.

Приведенные выше примеры операторов перенаправления находятся в контексте командной строки, но вы также можете использовать их в файле BAT . Когда вы используете BAT-файл для передачи вывода команды в текстовый файл, используются те же самые команды, описанные выше, но вместо нажатия Enter для их запуска вам просто нужно открыть .BAT-файл.

Перенаправление обоих каналов

Мы можем перенаправить и оба канала одновременно с помощью обоих символов командной строки.

Запустив скрипт командой perl program.pl > out.txt 2> err.txt, на экране мы ничего не
увидим. Все, что выводилось в стандартный канал вывода, окажется в файле out.txt, а все, что было
в канале ошибок – в err.txt.


В этих примерах названия файлов out.txt и err.txt совершенно произвольны. Вы можете использовать
любые пути по своему усмотрению.

Перенаправление потоков в командном файле (cmd, bat)

В shell и его потомках есть утилита tee, которая как раз предназначена для того, чтобы перенаправлять потоки и одновременно записывать их в файл. man tee:

tee [ -ai ] [ File ... ]

The tee utility copies standard input to standard output, making a
copy in zero or more files. The output is unbuffered.

The following options are available:

 -a      Append the output to the files rather than overwriting them.

 -i      Ignore the SIGINT signal.

Самый простой способ получить к ней доступ — установить cygwin, а самый простой способ его установить — через chocolatey. После этого у вас появится возможность писать скрипты на bash и пользоваться соответствующим набором утилит.

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

Перенаправление стандартного канала ошибок

С другой стороны, если запустить скрипт командой perl program.pl 2> err.txt, то символ
2>перенаправит канал ошибок в файл err.txt.

На экране мы увидим:

Welcome to our little program


А если откроем файл err.txt, то в нем обнаружим: Could not open file.

Поддержка unix/linux/windows?

Раздельный вывод в STDOUT и STDERR внутри Perl’а работает на любой операционной системе, но
перенаправление может не сработать. Это зависит от того, как работает операционная система, или,
точнее, оболочка (командная строка).

Большая часть примеров выше должна работать на Unix/Linux, как и на MS Windows. Конкретно
/dev/null работает только на системах Unix/Linux.

Использование оператора «>>» для добавления вывода

Для добавления выходных данных команды в конец файла без потери хранящейся в нем информации используется двойной символ «больше» (>>). Например, следующая команда добавляет список каталогов, созданный командой dir, в файл Dirlist.txt:

dir>>dirlist.txt

Для добавления выходных данных команды netstat в конец файла Tcpinfo.txt введите:

netstat>>tcpinfo.txt

Перенаправление стандартного канала вывода

(В дальнейших примерах предполагается, что вы используете bash-совместимую оболочку. Другие оболочки
могут работать по-другому.)

Как пользователь, не глядя в код, мы можем разделить два канала: если выполнить команду
perl program.pl > out.txt, символ >перенаправит канал вывода в файл
out.txt. Так что на экране мы увидим только содержимое стандартного канала ошибок.

Could not open file

Если открыть файл out.txt (с помощью Блокнота, vim или любого другого текстового редактора), мы
увидим в нем текст Welcome to our little program.

Как выводить сообщения об ошибках?


В Perl, когда программа запускается, эти два канала вывода представляются двумя символами:
STDOUT для стандартного канала вывода, и STDERR для стандартного канала ошибок.

Изнутри программы Perl вы можете выводить сообщение в любой из этих каналов, поместив
соответствующий символ сразу после ключевого слова print:

print STDOUT "Welcome to our little programn";
print STDERR "Could not open filen";

(Обратите внимание, после слов STDOUT и STDERR в этих выражениях нет запятой ,!)

Если запустить этот скрипт (perl program.pl), на экране мы увидим следующее:

Welcome to our little program
Could not open file


То есть мы не увидим, что эти сообщения пришли из разных каналов вывода.

Порядок вывода (буферизация)

Небольшое предупреждение:

Этот код:

print "до";
print STDERR "Небольшая проблема.n";
print "после";

Может вывести что-нибудь вроде:

Небольшая проблема.
допосле


Обратите внимание, что «до» и «после» попали на экран после сообщения об ошибке. Несмотря
на то, что мы ожидали увидеть «до», собственно, до сообщения об ошибке.

Причина этого в том, что по умолчанию Perl буферизирует вывод в STDOUT, но не буферизирует STDERR.
Чтобы выключить буферизацию, можно использовать волшебную палочку $|:

:/>  Как поменять время на папке

$| = 1;

print "до";
print STDERR "Небольшая проблема.n";
print "после";
доНебольшая проблема.
после

Также обычно можно решить эту проблему, добавив перевод строки в STDOUT:

print "доn";
print STDERR "Небольшая проблема.n";
print "после";


И вывод выглядит даже лучше:

до
Небольшая проблема.
после

Как перенаправить вывод одной команды в _аргумент_ другой команды?

Всем привет.

Я слегка запутался 🙂

Обычно в ОС (DOS, win) используются (наверное) два варианта входных данных для программ.

1. программа ожидает ввод (например, more)

2. программа читает аргументы командной строки (type)

Есть конвейер, который удобно применять с типом 1.
Например type <текстовый файл> | more отлично перекинет весь текст из одной программы в другую.
Можно даже перенаправление использовать: more <текстовый файл

Собственно вопрос: а что делать, если я хочу использовать конвейер/перенаправление, но программа (например type), поддерживает только аргументы командной строки и обычный ввод никак не принимает?

Например, я хочу найти в папке все файлы .bat и вывести их на экран.
Пишу:
dir /b | find “.bat” | type
И, конечно, ничего не работает.
Потому что type ожидает, что ей дадут аргумент. А не “ввод”.

Вопрос: как запихать “ввод” в какой-нибудь аргумент, и сделать это внутри cmd|bat файла? Возможно ли это?
(Ну, type то можно обмануть, если зафиксировать имя файла. А что делать, если нужно прокидывать произвольную строку?)

Канал вывода по умолчанию

По сути, слово STDOUT можно опустить, и написать просто:

print "Welcome to our little programn";
print STDERR "Could not open filen";

Когда скрипт perl запускается, STDOUT назначается каналом вывода по умолчанию. Это значит,
что любая операция вывода, для которой явно не указан канал, выведет данные в STDOUT.

Перенаправление вывода cmd windows на стандартный ввод (>&0)

учитывая, что CMD.EXE печально недокументирован, я не уверен, каким должно быть ожидаемое поведение. Я, конечно, не видел никакой документации о том, что такое ожидаемое поведение. Поэтому я думаю, что вам будет трудно найти кого-либо, кто мог бы дать окончательный ответ о том, является ли какое-либо из поведения ошибкой. Но я согласен, что это, безусловно, непоследовательно и кажется мне, по крайней мере, недостатком дизайна.

Я бы не охарактеризовал ситуацию как хаотичную в том, что поведение определенной команды, кажется, воспроизводимой. Но командир.EXE непоследователен в том, что я не вижу никакого способа предсказать, как любая команда ведет себя без тестирования.

у меня нет объяснений, но у меня есть некоторые уточненные классификации поведения.

перенаправление stdout или stderr на stdin работает отлично, если ни одна команда не пытается что-либо записать в перенаправленный вывод. Странное поведение возникает только при попытке внутренней команды запись в stdout или stderr после перенаправления в stdin.

я расширил ваши тесты, и видели следующие различные поведения:

Перенаправленный STDERR 2>&01

Я не делал исчерпывающего тестирования, но каждая внутренняя команда, которую я тестировал, которая записывает в stderr, немедленно завершит сеанс команды, если stderr был перенаправлен на stdin. Примеры включают в себя:

cd invalidPath 2>&0
vol x 2>&0
copy nonExistentFile 2>&0
move nonExistentFile 2>&0
set nonExistentVariable 2>&0
dir nonExistentFile 2>&0

то, что вы думали, было исключением на самом деле никогда не пишет в stderr. Попробуйте выполнить следующие действия без перенаправления, и вы увидите сообщение об ошибке:

dir nonExistentFIle *

так что нет никаких причин для команды, чтобы завершить сеанс команды, если stderr перенаправляется на стандартный ввод.

DIR выводит сообщение об ошибке, только если не удается найти соответствующий файл по всем предоставленным маскам файлов.

:: This prints an error message
dir nonExistentFile1 nonExistentFile2

:: So this terminates the command session
dir nonExistentFile1 nonExistentFile2 2>&0

Перенаправленный STDOUT 1>&0

здесь поведение я видел для перенаправления вывода:

1) выход исчезает в эфир, без какого-либо сообщения об ошибке.

примеры:

vol >&0
copy /-y file1 existingFile2 >&0
move /-y file1 existingFile2 >&0

2) Вывод не выполняется и выводится сообщение об ошибке stderr. Одна команда может создавать несколько сообщений, по одному для каждой неудачной попытки записи в stdout.

примеры:

cd >&0
echo Hello >&0

:: This generates 2 error messages, one for the time,
:: and another for the subsequent empty line
time /t >&0

3) выход терпит неудачу, и пакетная обработка завершенный. Активные SETLOCAL остаются в силе, даже после завершения пакета, если ошибка происходит в пределах вызываемой подпрограммы. В этом отношении он ведет себя так же, как фатальная синтаксическая ошибка.

до сих пор я видел только одну команду демонстрируют такое поведение:

dir >&0

Я ожидал бы, что команда DIR создаст сообщение об ошибке для каждой попытки вывода строки. Но это, кажется, завершается после сбоя на первой строке, и пакетная обработка также прерванный.

4) некоторые команды демонстрируют несколько моделей поведения.

примеры:

:: This SET command generates an error message for each
:: defined variable (behavior 2)
set >&0

:: But this SET command fails to display the prompt without
:: error message (behavior 1). Note that the echo of user input
:: is written directly to :con. It does not use stdout or stderr.
set "var=prompt" >&0

:: A single PAUSE exhibits both behaviors 1 and 2. The prompt to
:: press a key simply dissapears, and the echo of the user input
:: generates an error. Note that in this case, the echo of user
:: input is written to stdout.
pause >&0

Оставьте комментарий