Перенаправление вывода в файл. Перенаправление ввода-вывода

Хотя обычно, как было сказано, ввод/вывод программы связаны со стандартными потоками, в оболочке существуют специальные средства для перенаправления ввода/вывода.

5.5.1 Операторы >, < и >>

Для обозначения перенаправления используются символы "> ", "< " и ">> ". Чаще всего используется перенаправление вывода команды в файл. Вот соответствующий пример:

$ ls -l > /home/jim/dir.txt

По этой команде в файле /home/jim/dir.txt будет сохранен перечень файлов и подкаталогов того каталога, который был текущим на момент выполнения команды ls ; при этом если указанного файла не существовало, то он будет создан; если он существовал, то будет перезаписан; если же вы хотите, чтобы вывод команды был дописан в конец существующего файла, то надо вместо символа > использовать >> . При этом наличие пробелов до или после символов > или >> несущественно и служит только для удобства пользователя.

Вы можете направить вывод не только в файл, но и на вход другой команды или на устройство (например, принтер). Так, для подсчета числа слов в файле /home/jim/report.txt можно использовать следующую команду:

$ cat /home/jim/report.txt > wc -w

а для вывода файла на печать — команду:

$ cat /home/jim/report.txt > lpr

Как видите, оператор > служит для перенаправления выходного потока. По отношению к входному потоку аналогичную функцию выполняет оператор < . Приведенный выше пример команды для подсчета числа слов в определенном файле можно переписать следующим образом (обратите внимание на отсутствие команды cat ):

$ wc -w < /home/jim/report.txt

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

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

$ cat > file

$ cat>file

$ >file cat

$ > file cat

Однако сам по себе (без какой-либо команды, для которой определены стандартные потоки) символ перенаправления не может использоваться, так что нельзя, например, введя в командной строке

$ file1 > file2

получить копию какого-то файла. Но это не уменьшает значения данного механизма, ведь стандартные потоки определены для любой команды. При этом перенаправить можно не только стандартный ввод и вывод, но и другие потоки. Для этого надо указать перед символом перенаправления номер перенаправляемого потока. Стандартный ввод stdin имеет номер 0, стандартный вывод stdout — номер 1, стандартный поток сообщений об ошибках stderr — номер 2. То есть полный формат команды перенаправления имеет вид (напомним, что пробелы возле > не обязательны):

command N > M

где N и M — номера стандартных потоков (0,1,2) или имена файлов. Употребление в некоторых случаях символов < , > и>> без указания номера канала или имени файла возможно только потому, что вместо отсутствующего номера по умолчанию подставляется 1, т. е. стандартный вывод. Так, оператор > без указания номера интерпретируется как 1 > .

Кроме простого перенаправления стандартных потоков существует еще возможность не просто перенаправить поток в тот или иной канал, а сделать копию содержимого стандартного потока. Для этого служит специальный символ & , который ставится перед номером канала, на который перенаправляется поток:

command N > &M

Такая команда означает, что выход канала с номером N направляется как на стандартный вывод, так и дублируется в канал с номером M . Например, для того, чтобы сообщения об ошибках дублировались на стандартный вывод, надо дать команду 2>&1, в то время как 1>&2 дублирует stdout в stderr. Такая возможность особенно полезна при перенаправлении вывода в файл, так как мы тогда одновременно и видим сообщения на экране, и сохраняем их в файле.

5.5.2 Оператор |

Особым вариантом перенаправления вывода является организация программного канала (иногда называет трубопроводом или конвейером). Для этого две или несколько команд, таких, что вывод предыдущей служит вводом для следующей, соединяются (или разделяются, если вам это больше нравится) символом вертикальной черты — "|". При этом стандартный выходной поток команды, расположенной слева от символа | , направляется на стандартный ввод программы, расположенной справа от символа | . Например:

$ cat myfile | grep Linux | wc -l

Эта строка означает, что вывод команды cat , т. е. текст из файла myfile, будет направлен на вход команды grep , которая выделит только строки, содержащие слово "Linux". Вывод команды grep будет, в свою очередь, направлен на вход команды wc -l , которая подсчитает число таких строк.

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

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

Статус выхода (логическое значение, возвращаемое после завершения работы программы) из канала совпадает со статусом выхода, возвращаемым последней командой конвейера. Перед первой командой конвейера можно поставить символ "!", тогда статус выхода из конвейера будет логическим отрицанием статуса выхода из последней команды. Оболочка ожидает завершения всех команд конвейера, прежде чем установить возвращаемое значение.

5.5.3 Фильтры

Последний из приведенных выше примеров (с командой grep ) можно использовать для иллюстрации еще одного важного понятия, а именно, программы-фильтра. Фильтры — это команды (или программы), которые воспринимают входной поток данных, производят над ним некоторые преобразования и выдают результат на стандартный вывод (откуда его можно перенаправить куда-то еще по желанию пользователя). К числу команд-фильтров относятся уже упоминавшиеся выше команды cat, more, less, wc, cmp, diff , а также следующие команды.

Таблица 5.1. Команды-фильтры

Команда

Краткое описание

grep , fgrep , egrep

Ищут во входном файле или данных со стандартного ввода строки, содержащие указанный шаблон, и выдают их на стандартный вывод

Заменяет во входном потоке все встречающиеся символы, перечисленные в заданном перечне, на соответствующие символы из второго заданного перечня

comm

Сравнивает два файла по строкам и выдает на стандартный вывод 3 колонки: в одной — строки, которые встречаются только в 1 файле, во второй — строки, которые встречаются только во 2-ом файле: и в третьей — строки, имеющиеся в обоих файлах

Форматирует для печати текстовый файл или содержимое стандартного ввода

sed

Строковый редактор, использующийся для выполнения некоторых преобразований над входным потоком данных (берется из файла или со стандартного ввода)

Особым фильтром является команда tee , которая "раздваивает" входной поток, с одной стороны направляя его на стандартный вывод, а с другой — в файл (имя которого вы должны задать). Легко видеть, что по своему действию команда tee аналогична оператору перенаправления 1>&file .

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

О перенаправлении и фильтрах можно было бы говорить очень много. Но этот материал имеется в большинстве книг по UNIX и Linux, например у Петерсена [П1.4] и Келли-Бутла [П1.8] . Поэтому ограничимся сказанным, и перейдем к рассмотрению так называемой среды или окружения, создаваемого оболочкой.

В. Костромин (kos at rus-linux dot net) - 5.5. Перенаправление ввода/вывода, каналы и фильтры

Если вывод в (графическую) консоль не очень объёмный, можно просто выдельть мышкой кусок и вставить его в сообщение щелчком средней кнопки. В противном случае можно использовать перенаправление вывода в файл через "воронку", например так:

Some_command parameters > logfile.txt

Чтобы видеть результат выполнения на экране, и одновременно писать в файл, можно воспользоваться командой tee :

Some_command parameters | tee -a logfile.txt

Команда setterm -dump создает "слепок" буфера текущей виртуальной консоли в виде простого текстового файла с именем по умолчанию - screen.dump. В качестве ее аргумента можно использовать номер консоли, для которой требуется сделать дамп. А добавление опции -file имя_файла перенаправит этот дамп в файл с указанным именем. Опция же -append присоединит новый дамп к уже существующему файлу - "умолчальному" screen.dump или поименованному опцией -file .

Т.е. после использования команды, например

Setterm -dump -file /root/screenlog

соответственно в файле /root/screenlog будет содержимое одной страницы консоли.

Нашёл еще одно решение для копирования/вставки текста в текстовой консоли без мыши. Также можно копировать текст из буфера прокрутки (т.е. всё что на экране и выше за экраном). Чтобы лучше разобраться, читайте о консольном менеджере окон screen . Также может пригодиться увеличить размер буфера прокрутки.

1) Запускаем screen

2) Нажимаем Enter. Всё. Мы находимся в нулевом окне консоли.

3) Выполняем нужные команды, вывод которых необходимо скопировать.

4) Ctrl+A, Ctrl+[ - мы в режиме копирования. Ставим курсор на начало выделения, жмём пробел, потом ставим курсор на конец выделения, жмём пробел. Текст скопирован в буфер.

5) Ctrl+A, с - мы создали новое 1-е окно.

6) Ctrl+A, 1 - мы перешли на 1-е окно.

7) Открываем любой (?) текстовый редактор (я пробовал в mc), и жмём Ctrl+A, Ctrl+] - текст вставлен. Сохраняем.

8) Ctrl+A, Ctrl+0 - вернуться обратно в нулевое окно.

Как увеличить буфер обратной прокрутки?

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

И такое средство есть, а называется оно framebuffer console , для краткости fbcon . Это устройство имеет файл документации fbcon.txt ; если вы устанавливали документацию к ядру, то он у вас есть. Выискивайте его где-то в районе /usr/share ветви (я не могу указать точный путь из-за разницы в дистрибутивах).

На этом месте прошу прощения: мы должны сделать небольшое отступление и немного поговорить о видеобуфере (framebuffer ).

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

Один из таких трюков связан с буфером прокрутки; оказывается, вы можете "попросить" видеобуфер выделить больше памяти буферу прокрутки. Достигается это через загрузочные параметры ядра. Сначала вы требуете framebuffer (видеобуфер); Затем запрашиваете больший буфер прокрутки.

Нижеследующий пример касается GRUB , но может быть легко адаптирован к LILO . В файле настройки GRUB - menu.lst - найдите соответствующую ядру строчку, и затем: Удалите опцию vga=xxx , если таковая присутствует. Добавьте опцию video=vesabf или то, что соответствует вашему "железу". Добавьте опцию fbcon=scrollback:128 . После этой процедуры, строка параметров ядра должна выглядеть приблизительно так:

Kernel /vmlinuz root=/dev/sdb5 video=radeonfb fbcon=scrollback:128

Спрашивается, зачем удалять опцию vga=xxx ? Из-за возможных конфликтов с видео-опцией. На своем ATI адаптере, я не могу изменить буфер прокрутки, если vga=xxx присутствует в списке. Возможно в вашем случае это не так. Если вышеперечисленные опции работают - хорошо; но что, если вы хотите увеличить число строк, или установить более мелкий шрифт на экране? Вы всегда делали это при помощи опции vga=xxx - а она-то и исчезла. Не переживайте - то же самое может быть достигнуто изменением параметров fbcon, как описано в файле fbcon.txt (но не описано в данной статье).

С опцией fbcon=scrollback:128 у меня буфер прокрутки увеличился до 17 экранов (35 раз Shift+PgUp по полэкрана). Кстати, 128 - это килобайт. Автор статьи утверждает, что больше установить нельзя. Я и не пробовал.

Можно заюзать script .

Script filename.log

когда все нужные команды выполнены -

Все записано в filename.log

В FreeBSD есть замечательная утилита watch, которая позволяет мониторить терминалы, но как оказалось, в Linux она выполняет совсем иные функции =\ Стоит погуглить на эту тему, чего-нть да найдется...

Три направления ввода-вывода являются выделенными - стандартный ввод, вывод и поток ошибок (stdin, stdout, stderr ). По умолчанию, все три потока связаны (ассоциированы) с терминалом. При этом программа выводит все свои сообщения в том числе и об ошибках на терминал. Shell позволяет перенаправить эти стандартные потоки, установить ввод-вывод и объединение потоков.

Перенаправление потоков ввода-вывода.

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

>>file -Перенаправление стандартного потока вывода в файл file с добавлением в конец файла.

-получение стандартного потока ввода из файла file.

prog1 | prog2 -Передача выходного потока программы prog1 во входной поток программы prog2.

n>file file.

n>>file -Перенаправление стандартного потока с дескриптором n в файл file с добавлением в конец файла.

n>&m -Объединение потоков с дескрипторами n и m .

$ prog1 >/dev/null 2>&1

/dev/null - это псевдоустройство, которое уничтожает направленный в него поток.

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

$ gzip -d archive.tar.gz | tar –xf

Здесь происходит разархивация файла archive.tar.gz , запакованного двумя архиваторами. Выходной поток от утилиты gzip передается во входной поток утилите tar . Аналогично эту же операцию можно было выполнить и по другому:

$ gzip -d archive.tar.gz

$ tar -xf archive.tar

Поскольку язык Bourne Shell является процедурным языком программирования, в нем также как и в других подобных языках есть операторы, позволяющие управлять последовательностью выполнения команд. Необходимым оператором является проверка некоторого условия, в зависимости от выполнения которого определяется дальнейший ход программы. Таким оператором является команда test. Эта команда проверяет выполнение некоторого условия. У команды test существует два варианта вызова:

test условие

[ условие ]

Следует отметить, что между скобкой и условием необходимо наличие пробелов, иначе Shell не сможет опознать "[" как команду test . При успешном завершении test возвращает "0" .

Условия проверки файлов:

-f file Файл "file" является обычным файлом.

-d file Файл "file" является каталогом.
-c file Файл "file" является специальным файлом.
-r file Файл "file" имеет разрешение на чтение.

-w file Файл "file" имеет разрешение на запись.

-x file Файл "file" имеет разрешение на исполнение.

-s file Файл "file" не пустой.

Условия проверки строк:

string1=string2 Строки string1 и string2 совпадают.

string1!=string2 Строки string1 и string2 не совпадают.

-n string1 Строка string1 существует.

-z string1 Строка string1 не существует.

Условия операций с целыми числами:

x -eq y x равно y

x -ne y x не равно y

x -gt y x больше y

x -ge y x больше или равно y

x -lt y x меньше y

x -le y x меньше или равно y

В этом случае команда test воспринимает строки именно как целые числа. Нулевому значению так же соответствует пустая строка.

Логические операции в контексте test

! (not) Логическое "НЕ"

-o (or) Логическое "ИЛИ"

-a (and) Логическое "И"

Условный оператор "if "

Общий вид использования условного оператора if представляется следующим образом:

if <условие>

then <список команд>

[ elif <условие>

then <список> ]

Выражения, выделенные в квадратных скобках, являются необязательными. Т.е. можно представить наиболее употребительную "порезанную" модификацию условного оператора:

if <условие>

then <список команд>

В этом случае если <условие> выполнено (код завершения 0) то выполняется <список команд>. В противном случае <список команд> пропускается.

Оператор выбора case

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

case <строка> in

Шаблон 1)

........

Шаблон2)

........

........

Значение <строка> сравнивается с шаблонами, по порядку. Если было найдено совпадение, тогда выполняются команды соответствующего раздела. Следует отметить, что шаблоны допускают использование масок. Если совпадения не было найдено, тогда выполняются команды из раздела с шаблоном "*" (аналогично default селектора switch в С ).

Для примера приведем кусочек инициализационного скрипта BSD UNIX . Здесь переменные (inetd_enable и inetd_flags ) были получены из другого файла (rc.conf).

. /etc/rc.conf

case {$inetd_enable} in

)

if [ -x /usr/sbin/inetd ]; then

/usr/sbin/inetd $inetd_flags

fi

;;

esac

Оператор цикла с перечислением for

Синтаксис оператора for

for <имя>

<список команд>

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

Оператор цикла с истинным условием while

Синтаксис оператора while в общем случае имеет следующую структуру:

while <условие>

<список команд>

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

Оператор цикла с ложным условием until

Синтаксис оператора until в общем случае имеет следующую структуру:

until <условие>

<список команд>

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

Основные команды ОС UNIX для работы с файлами

1. Команда pwd .

Синтаксис: pwd .

Описание: команда выводит имя текущей директории для работающего командного интерпретатора.

Задание 1.

Воспользуйтесь командой pwd для определения своей домашней директории.

Отразите команду и результат ее работы в отчете.

2. Команда man .

Синтаксис: man имя.

Имя - это имя интересующей нас команды, утилиты, системного вызова, библиотечной функции, файла.

Описание: UNIX MANUAL - руководство по операционной системе UNIX. Информация оттуда доступна в интерактивном режиме с помощью утилиты man .

Задание 2.

С помощью утилиты man посмотрите информацию о команде pwd.

Запишите кратко информацию о команде в отчет (на русском языке).

3. Команда cd .

Синтаксис:cd имя_директории.

Описание: это команда смены текущей директории. Имя_директории - это полное или относительное имя директории, которую вы хотите сделать текущей.

cd без параметров текущей сделает вашу домашнюю директорию.

Задание 3.

Сделайте текущей директорию на уровень выше. Проверьте это, затем вернитесь в свою домашнюю директорию. Проверьте смену директории.

Выполнение проделанных команд отразите в отчете.

4. Команда ls .

Синтаксис: ls имя_директории

Описание: команда просмотра состава указанной директории.

ls без параметров распечатывает список файлов из текущей директории.

В полученный список не войдут файлы, имена которых начинаются с символа “. ” - файлы, созданные различными системными программами в своих целях. Посмотреть полный список файлов можно, указав в команде ls ключ “-a”,

т.е. ls -aимя_директории

Права доступа к файлам

С каждым файлом в ОС UNIX связано 12-битное слово, называемое «правами доступа» к файлу.

Младшие 9 бит этого слова объединены в три группы по три бита; каждая группа задает права доступа для владельца файла, для его группы и для всех остальных пользователей. Три бита в каждой группе отвечают за право на чтение, запрос и использование файла.

Чтобы узнать права доступа к тому или иному файлу, можно воспользоваться командой

, например:

> ls -l /bin/cat

Расположенная в начале строки группа символов -rwxr-xr-x показывает тип файла (первый символ; минус означает, что мы имеем дело с обыкновенным файлом, буква d означала бы каталог и т.п.) и права доступа, соответственно, для владельца (в данном случае rwx , т.е. чтение, запись и исполнение), группы и всех остальных (в данном случае r-x , т.е. права на запись отсутствуют). Таким образом, файл /bin/cat доступен любому пользователю на чтение и исполнение, но модифицировать его может только пользователь root (т.е. администратор).

Можно записать слово прав доступа к файлу в виде восьмеричного числа (3 знака - восьмеричная цифра), трехзначного (владелец, группа, остальные пользователи) каждый знак в этом трехзначном восьмеричном числе формируется как сумма прав: 4- права на чтение, 2- права на запись, 1 - на использование (из двоичной триады): (111) 2 =2 0 +2 1 +2 2 =(1+2+4) 10 .

Например, 7 = 1 + 2 + 4 Þ права rwx

4 2 1

6 = 0 + 2+ 4 Þ права rw- -

4 2 0

В трехзначном числе задания прав: 744 для владельца определены все права, для группы - только чтение, для остальных пользователей - только на чтение.

Для использования прав доступа к файлам используется команда chmod , которая позволяет задать новые права доступа в виде восьмеричного числа, например:

$ chmod 744 filel.c.

Задание 4.

а) Для получения полной информации о команде ls воспользуйтесь утилитой man. Перенаправьте вывод команды в какой-либо текстовый файл.

б) Посмотрите полное содержимое текущей директории и перенаправьте этот вывод также в текстовый файл.

в) С помощью команды ls -l <имя_файла> выведите информацию о правах доступа к тому текстовому файлу, с которым вы работали в п. 4б, затем перенаправьте эту информацию в тот же текстовый файл. Объясните полученный вывод.

5. Команда cat .

Перенаправление ввода/вывода.

Для просмотра содержимого небольшого текстового файла на экране можно воспользоваться командой:

сat имя_файла

Внимание! Не пытайтесь просматривать таким образом содержимое директории и бинарных файлов.

Большой тестовый файл удобно просматривать командой more (описание использования найдите в UNIX MANUAL ). Почему здесь неудобна команда сat ?

В команде сat можно задавать несколько имен файлов:

сat файл1 файл 2 … файл N

при этом содержимое всех файлов подряд будет выведено на экран.

Можно перенаправить вывод в какой-нибудь файл:

сat файл 1 файл 2 > файл_ результатов

Перенаправление вывода со стандартного потока вывода (экрана) в файл является стандартным для всех команд. Перенаправить стандартный ввод (с клавиатуры), например, брать данные для программы из файла, можно с помощью знака “<”.

сat > новый_файл - создаст новый текстовый файл с содержимым, вводимым вами с клавиатуры.

Прервать процесс ввода данных-

Задание 5.

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

6. Простейшие команды работы с файлами: cp, rm, mkdir, mv

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

mkdir имя_директории

Для копирования содержимого одного файла в другой используется команда:

cp файл_источник файл_назначение.

Команда

cp файл 1 файл 2 …. файл N директория назначения

служит для копирования файла или файлов в уже существующую директорию с именем директории_назначения под своими именами. Вместо имен копируемых файлов можно использовать их шаблоны. Шаблоны задаются с помощью метасимволов:

* - соответствует всем цепочкам литер, включая пустую.

Все одиночные литеры

[ …] - соответствует любой литере, заключенной в скобки. Пара литер, разделенных минусом, задает диапазон литер.

Команда

cp - r дир_источник дир_назначение

служит для рекурсивного копировария одной директории (дир_источник) в новую директориию (дир_назначение).

Вместо имен в командах копирования могут использоваться их шаблоны.

Команда

rm файл 1 файл 2 …. файл N

позволяет удалить 1 или несколько регулярных файлов из текущей директории.

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

Rm-r дир 1 дир 2

Команда переименования:

mv имя_источника имя_назначения

Файл с именем имя_источника переименовывает в файл с именем имя_назначения. При этом перед выполнением команды файла с именем имя_назначения существовать не должно.

Задание 6.

Создайте новую директорию внутри своей домашней. Организуйте там небольшой тестовый файл с содержимым из двух строк:

«Изучаю работу в ОС UNIX

Организую скрипт».

Скопируйте содержимое этого файла в другой - с тем же именем, но в директории /home. Удалите первоначально созданный файл из вашей директории, если копирование прошло успешно. Проверьте содержимое использованных директориий и файлов.

Задание 7.

1). Когда вы освоили работу в интерактивном режиме с простейшими командами ОС UNIX, создайте с помощью редактора Kwriter скрипт со сценарием, соответствующим последовательному выполнению:

Задание 3,

Задание 4Б,4В,

Задание 5,

Задание 6.

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

Необходимо, чтобы в командном файле была организована грамотная выдача запросов на ввод данных с клавиатуры с помощью команды: $ echo - n “текст запроса”.

2). Сохраните скрипт с именем Myscript1, запустите его на выполнение командой

sh Myscript1

введите запрашиваемые данные и проверьте полученные результаты.

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

Системные вызовы getuid и getpid

Узнать идентификатор пользователя, запустившего программу на выполнение,-UID и идентификатор группы, к которой он относится,-GID можно с помощью системных вызовов getuid() и getpid() ,применив их внутри этой программы.

Прототипы системных вызовов:

#include

#include

uid_t getuid(void);

gid_t getgid(void);

Задание 8.

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

Включите программу с результатами в отчет.

Контрольные вопросы

1. Понятие файла в ОС UNIX . Что такое домашняя директория?

2. Какие существуют средства группирования команд Shell -интерпретатора? приведите примеры использования.

3. Как осуществляется перенаправление ввода-вывода?

4. Что такое конвейер команд? приведите пример.

5. Как средствами Shell выполнить арифметические действия над Shell -переменной?

6. Каковы правила генерации имен файлов?

7. Как выполняется подстановка результатов выполнения команд?

8. Как интерпретировать строку cmd1 & cmd2 & ?

9. Как интерпретировать строку cmd1 && cmd2 & ?

10. Как интерпретировать строку cmd1 || cmd2 & ?

11. Как в UNIX определены права доступа к файлу? Какой командой их можно посмотреть для конкретного файла?

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

Лабораторная работа № 3.

Процессы в операционной системе UNIX.

Цель работы

Научиться создавать процессы и освоить изменение пользовательского контекста процессов с помощью системных вызовов, применяемых в программах на языке С , в ОС UNIX .

1. Изучить организацию процессов в UNIX : понятие процесса, контекст процесса, жизненный цикл процесса, идентификация процессов, иерархическая структура процессов. Написать на С и отладить программу в соответствии с заданием 1.

2. Ознакомиться с созданием процесса в UNIX , с организацией завершения процесса. Написать и отладить программу (язык С ) в соответствии с Заданием 2, включить ее в отчет.

3. Изучить параметры функции main() в языке С , переменные среды и аргументы командной строки. Написать программу на языке С в соответствии с Заданием 3, отладить и включить ее в отчет вместе с результатами.

4. Изучить семейство функций для организации системного вызова exec().

5. Написать программу на языке С в соответствии с вариантом Задания 4, выданного преподавателем, отладить программу и продемонстрировать полученные результаты преподавателю. Включить программу с результатами в отчет.

6. Защитить работу преподавателю, ответив на контрольные вопросы.

В системе по-умолчанию всегда открыты три "файла" — (клавиатура), (экран) и (вывод сообщений об ошибках на экран). Эти, и любые другие открытые файлы, могут быть перенапрвлены. В данном случае, термин "перенаправление" означает получить вывод из файла, команды, программы, сценария или даже отдельного блока в сценарии (см. Пример 3-1 и Пример 3-2) и передать его на вход в другой файл, команду, программу или сценарий.

С каждым открытым файлом связан дескриптор файла. Дескрипторы файлов, и — 0, 1 и 2, соответственно. При открытии дополнительных файлов, дескрипторы с 3 по 9 остаются незанятыми. Иногда дополнительные дескрипторы могут сослужить неплохую службу, временно сохраняя в себе ссылку на, или. Это упрощает возврат дескрипторов в нормальное состояние после сложных манипуляций с перенаправлением и перестановками (см. Пример 16-1).

COMMAND_OUTPUT > # Перенаправление stdout (вывода) в файл. # Если файл отсутствовал, то он создется, иначе — перезаписывается. ls -lR > dir-tree.list # Создает файл, содержащий список дерева каталогов. : > filename # Операция > усекает файл "filename" до нулевой длины. # Если до выполнения операции файла не существовало, # то создается новый файл с нулевой длиной (тот же эффект дает команда "touch"). # Символ: выступает здесь в роли местозаполнителя, не выводя ничего. > filename # Операция > усекает файл "filename" до нулевой длины. # Если до выполнения операции файла не существовало, # то создается новый файл с нулевой длиной (тот же эффект дает команда "touch"). # (тот же результат, что и выше — ": >", но этот вариант неработоспособен # в некоторых командных оболочках.) COMMAND_OUTPUT >> # Перенаправление stdout (вывода) в файл. # Создает новый файл, если он отсутствовал, иначе — дописывает в конец файла. # Однострочные команды перенаправления # (затрагивают только ту строку, в которой они встречаются): # ——————————————————————— 1>filename # Перенаправление вывода (stdout) в файл "filename". 1>>filename # Перенаправление вывода (stdout) в файл "filename", файл открывается в режиме добавления. 2>filename # Перенаправление stderr в файл "filename". 2>>filename # Перенаправление stderr в файл "filename", файл открывается в режиме добавления. &>filename # Перенаправление stdout и stderr в файл "filename". #============================================================================== # Перенаправление stdout, только для одной строки. LOGFILE=script.log echo "Эта строка будет записана в файл \"$LOGFILE\"." 1>$LOGFILE echo "Эта строка будет добавлена в конец файла \"$LOGFILE\"." 1>>$LOGFILE echo "Эта строка тоже будет добавлена в конец файла \"$LOGFILE\"." 1>>$LOGFILE echo "Эта строка будет выведена на экран и не попадет в файл \"$LOGFILE\"." # После каждой строки, сделанное перенаправление автоматически "сбрасывается". # Перенаправление stderr, только для одной строки. ERRORFILE=script.errors bad_command1 2>$ERRORFILE # Сообщение об ошибке запишется в $ERRORFILE. bad_command2 2>>$ERRORFILE # Сообщение об ошибке добавится в конец $ERRORFILE. bad_command3 # Сообщение об ошибке будет выведено на stderr, #+ и не попадет в $ERRORFILE. # После каждой строки, сделанное перенаправление также автоматически "сбрасывается". #============================================================================== 2>&1 # Перенаправляется stderr на stdout. # Сообщения об ошибках передаются туда же, куда и стандартный вывод. i> i в j . # Вывод в файл с дескриптором i передается в файл с дескриптором j . >&j # Перенаправляется файл с дескриптором 1 (stdout) в файл с дескриптором j . # Вывод на stdout передается в файл с дескриптором j . 0< FILENAME < FILENAME # Ввод из файла. # Парная команде ">", часто встречается в комбинации с ней. # # grep search-word filename # Файл "filename" открывается на чтение и запись, и связывается с дескриптором "j". # Если "filename" отсутствует, то он создается. # Если дескриптор "j" не указан, то, по-умолчанию, бередся дескриптор 0, stdin. # # Как одно из применений этого — запись в конкретную позицию в файле. echo 1234567890 > File # Записать строку в файл "File". exec 3<> File # Открыть "File" и связать с дескриптором 3. read -n 4 <&3 # Прочитать 4 символа. echo -n . >&3 # Записать символ точки. exec 3>&- # Закрыть дескриптор 3. cat File # ==> 1234.67890 # Произвольный доступ, да и только! | # Конвейер (канал). # Универсальное средство для объединения команд в одну цепочку. # Похоже на ">", но на самом деле — более обширная. # Используется для объединения команд, сценариев, файлов и программ в одну цепочку (конвейер). cat *.txt | sort | uniq > result-file # Содержимое всех файлов.txt сортируется, удаляются повторяющиеся строки, # результат сохраняется в файле "result-file".

Операции перенаправления и/или конвейеры могут комбинироваться в одной командной строке.

command < input-file > output-file command1 | command2 | command3 > output-file См. Пример 12-23 и Пример A-17.

Допускается перенаправление нескольких потоков в один файл.

ls -yz >> command.log 2>&1 # Сообщение о неверной опции "yz" в команде "ls" будет записано в файл "command.log". # Поскольку stderr перенаправлен в файл.

Закрытие дескрипторов файлов

Закрыть дескриптор входного файла.

0<&-, <&-

Закрыть дескриптор выходного файла.

1>&-, >&-

Дочерние процессы наследуют дескрипторы открытых файлов. По этой причине и работают конвейеры. Чтобы предотвратить наследование дескрипторов — закройте их перед запуском дочернего процесса.

# В конвейер передается только stderr. exec 3>&1 # Сохранить текущее "состояние" stdout. ls -l 2>&1 >&3 3>&- | grep bad 3>&- # Закрыть дескр. 3 для "grep" (но не для "ls"). # ^^^^ ^^^^ exec 3>&- # Теперь закрыть его для оставшейся части сценария. # Спасибо S.C.

Дополнительные сведения о перенаправлении ввода/вывода вы найдете в Приложение D.

16.1. С помощью команды exec

Команда exec перенаправляет ввод со на файл. С этого момента весь ввод, вместо (обычно это клавиатура), будет производиться из этого файла. Это дает возможность читать содержимое файла, строку за строкой, и анализировать каждую введенную строку с помощью sed и/или awk.

Пример 16-1. Перенаправление с помощью exec

#!/bin/bash # Перенаправление stdin с помощью "exec". exec 6<&0 # Связать дескр. #6 со стандартным вводом (stdin). # Сохраняя stdin. exec < data-file # stdin заменяется файлом "data-file" read a1 # Читается первая строка из "data-file". read a2 # Читается вторая строка из "data-file." echo echo "Следующие строки были прочитаны из файла." echo "——————————————" echo $a1 echo $a2 echo; echo; echo exec 0<&6 6<&- # Восстанавливается stdin из дескр. #6, где он был предварительно сохранен, #+ и дескр. #6 закрывается (6<&-) освобождая его для других процессов. # # <&6 6<&- дает тот же результат. echo -n "Введите строку " read b1 # Теперь функция "read", как и следовало ожидать, принимает данные с обычного stdin. echo "Строка, принятая со stdin." echo "—————————" echo "b1 = $b1" echo exit 0

Аналогично, конструкция exec >filename перенаправляет вывод на в заданный файл. После этого, весь вывод от команд, который обычно направляется на, теперь выводится в этот файл.

Пример 16-2. Перенаправление с помощью exec

#!/bin/bash # reassign-stdout.sh LOGFILE=logfile.txt exec 6>&1 # Связать дескр. #6 со stdout. # Сохраняя stdout. exec > $LOGFILE # stdout замещается файлом "logfile.txt". # ———————————————————— # # Весь вывод от команд, в данном блоке, записывается в файл $LOGFILE. echo -n "Logfile: " date echo "————————————-" echo echo "Вывод команды \"ls -al\"" echo ls -al echo; echo echo "Вывод команды \"df\"" echo df # ———————————————————— # exec 1>&6 6>&- # Восстановить stdout и закрыть дескр. #6. echo echo "== stdout восстановлено в значение по-умолчанию == " echo ls -al echo exit 0

Пример 16-3. Одновременное перенаправление устройств, и, с помощью команды exec

#!/bin/bash # upperconv.sh # Преобразование символов во входном файле в верхний регистр. E_FILE_ACCESS=70 E_WRONG_ARGS=71 if [ ! -r "$1" ] # Файл доступен для чтения? then echo "Невозможно прочитать из заданного файла!" echo "Порядок использования: $0 input-file output-file" exit $E_FILE_ACCESS fi # В случае, если входной файл ($1) не задан #+ код завершения будет этим же. if [ -z "$2" ] then echo "Необходимо задать выходной файл." echo "Порядок использования: $0 input-file output-file" exit $E_WRONG_ARGS fi exec 4<&0 exec < $1 # Назначить ввод из входного файла. exec 7>&1 exec > $2 # Назначить вывод в выходной файл. # Предполагается, что выходной файл доступен для записи # (добавить проверку?). # ———————————————— cat — | tr a-z A-Z # Перевод в верхний регистр # ^^^^^ # Чтение со stdin. # ^^^^^^^^^^ # Запись в stdout. # Однако, и stdin и stdout были перенаправлены. # ———————————————— exec 1>&7 7>&- # Восстановить stdout. exec 0<&4 4<&- # Восстановить stdin. # После восстановления, следующая строка выводится на stdout, чего и следовало ожидать. echo "Символы из \"$1\" преобразованы в верхний регистр, результат записан в \"$2\"." exit 0

Next: Перенаправление ошибок в файл Up: Перенаправление ввода-вывода Previous: Перенаправление ввода из файла Contents Index

Перенаправление вывода в файл

Для перенаправления стандартного вывода в файл используйте оператор `>’.

Перенаправление ввода/вывода в Linux

Укажите после имени команды оператор >, а затем имя файла, который будет служить приемником вывода. Например, чтобы записать вывод результатов работы программы в файл, введите:

Если Вы перенаправите стандартный вывод в уже существующий файл, он будет перезаписан с начала. Чтобы добавить стандартный вывод к содержимому существующего файла, необходимо использовать оператор `»’. Например, для добавления результатов работы при повторном запуске программы в файл, введите:

Alex Otwagin 2002-12-16

Программа обычно ценна тем, что может обрабатывать данные: принимать одно, на выходе выдавать другое, причём в качестве данных может выступать практически что угодно: текст, числа, звук, видео… Потоки входных и выходных данных для команды называются ввод и вывод . Потоков ввода и вывода у каждой программы может быть и по несколько. В каждый процесс, при создании в обязательном порядке получает так называемые стандартный ввод (standard input, stdin) и стандартный вывод (standard output, stdout) и стандартный вывод ошибок (standard error, stderr).

Стандартные потоки ввода/вывода предназначены в первую очередь для обмена текстовой информацией. Тут даже не важно, кто общается с помощью текстов: человек с программой или программы междй собой - главное, чтобы у них был канал передачи данных и чтобы они говорили «на одном языке».

Текстовый принцип работы с машиной позволяет отвлечься от конкретных частей компьютера, вроде системной клавиатуры и видеокарты с монитором, рассматривая единое оконечное устройство , посредством которого пользователь вводит текст (команды) и передаёт его системе, а система выводит необходимые пользователю данные и сообщения (диагностику и ошибки). Такое устройство называется терминалом . В общем случае терминал - это точка входа пользователя в систему, обладающая способностью передавать текстовую информацию. Терминалом может быть отдельное внешнее устройство, подключаемое к компьютеру через порт последовательной передачи данных (в персональном компьютере он называется «COM port»). В роли терминала может работать (с некоторой поддержкой со стороны системы) и программа (например, xterm или ssh). Наконец, виртуальные консоли - тоже терминалы, только организованные программно с помощью подходящих устройств современного компьютера.

При работе с командной строкой, стандартный ввод командной оболочки связан с клавиатурой, а стандартный вывод и вывод ошибок - с экраном монитора (или окном эмулятора терминала). Покажем на примере простейшей команды - cat. Обычно команда cat читает данные из всех файлов, которые указаны в качестве её параметров, и посылает считанное непосредственно в стандартный вывод (stdout). Следовательно, команда

/home/larry/papers# cat history-final masters-thesis

выведет на экран сначала содержимое файла, а затем - файла.

Однако если имя файла не указано, программа cat читает входные данные из stdin и немедленно возвращает их в stdout (никак не изменяя). Данные проходят через cat , как через трубу. Приведём пример:

/home/larry/papers# cat Hello there. Hello there. Bye. Bye. Ctrl D /home/larry/papers#

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

Приведём другой пример. Команда sort читает строки вводимого текста (также из stdin, если не указано ни одного имени файла) и выдаёт набор этих строк в упорядоченном виде на stdout. Проверим её действие.

/home/larry/papers# sort bananas carrots apples Ctrl+D apples bananas carrots /home/larry/papers#

Как видно, после нажатия Ctrl D , sort вывела строки упорядоченными в алфавитном порядке.

Стандартный ввод и стандартный вывод

Допустим, вы хотите направить вывод команды sort в некоторый файл, чтобы сохранить упорядоченный по алфавиту список на диске. Командная оболочка позволяет перенаправить стандартный вывод команды в файл, используя символ. Приведём пример:

/home/larry/papers# sort > shopping-list bananas carrots apples Ctrl D /home/larry/papers#

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

/home/larry/papers# cat shopping-list apples bananas carrots /home/larry/papers#

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

/home/larry/papers# sort items shopping-list /home/larry/papers# cat shopping-list apples bananas carrots /home/larry/papers#

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

/home/larry/papers# sort < items apples bananas carrots /home/larry/papers#

Результат команды sort < items эквивалентен команде sort items , однако первая из них демонстрирует следующее: при выдаче команды sort < items система ведёт себя так, как если бы данные, которые содержатся в файле, были введены со стандартного ввода. Перенаправление осуществляется командной оболочкой. Команде sort не сообщалось имя файла: эта команда читала данные из своего стандартного ввода, как если бы мы вводили их с клавиатуры.

Введём понятие фильтра . Фильтром является программа, которая читает данные из стандартного ввода, некоторым образом их обрабатывает и результат направляет на стандартный вывод. Когда применяется перенаправление, в качестве стандартного ввода и вывода могут выступать файлы. Как указывалось выше, по умолчанию, stdin и stdout относятся к клавиатуре и к экрану соответственно. Программа sort является простым фильтром - она сортирует входные данные и посылает результат на стандартный вывод. Совсем простым фильтром является программа cat - она ничего не делает с входными данными, а просто пересылает их на выход.

Выше уже демонстрировалось, как использовать программу sort в качестве фильтра. В этих примерах предполагалось, что исходные данные находятся в некотором файле или что эти исходные данные будут введены с клавиатуры (стандартного ввода). Однако как поступить, если вы хотите отсортировать данные, которые являются результатом работы какой-либо другой команды, например, ls ?

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

Перенаправление ввода-вывода

Применим сначала команду ls :

/home/larry/papers# ls english-list history-final masters-thesis notes /home/larry/papers#

Теперь перенаправляем выход команды ls в файл с именем file-list

/home/larry/papers# ls > file-list /home/larry/papers# sort -r file-list notes masters-thesis history-final english-list /home/larry/papers#

Здесь выход команды ls сохранен в файле, а после этого этот файл был обработан командой sort . Однако этот путь является неизящным и требует использования временного файла для хранения выходных данных программы ls .

Решением в данной ситуации может служить создание состыкованных команд (pipelines). Стыковку осуществляет командная оболочка, которая stdout первой команды направляет на stdin второй команды. В данном случае мы хотим направить stdout команды ls на stdin команды sort . Для стыковки используется символ, как это показано в следующем примере:

/home/larry/papers# ls | sort -r notes masters-thesis history-final english-list /home/larry/papers#

Эта команда короче, чем совокупность команд, и её проще набирать.

Рассмотрим другой полезный пример. Команда

/home/larry/papers# ls /usr/bin

выдаёт длинный список файлов. Большая часть этого списка пролетает по экрану слишком быстро, чтобы содержимое этого списка можно было прочитать. Попробуем использовать команду more для того, чтобы выводить этот список частями:

/home/larry/papers# ls /usr/bin | more

Теперь можно этот список «перелистывать».

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

/home/larry/papers# ls | sort -r | head -1 notes /home/larry/papers\#

где команда head выводит на экран первую строку получаемого ей входного потока строк (в нашем случае поток состоит из данных от команды ls ), отсортированных в обратном алфавитном порядке.

Использование состыкованных команд (конвейер)

Эффект от использования символа для перенаправления вывода файла является деструктивным; иными словами, команда

/home/larry/papers# ls > file-list

уничтожит содержимое файла, если этот файл ранее существовал, и создаст на его месте новый файл.

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

/home/larry/papers# ls >> file-list

приписывает вывод команды ls в конец файла.

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

Недеструктивное перенаправление вывода

Что-то вроде этого должно делать то, что вам нужно?

Проверьте это: wintee

Нет необходимости в cygwin.

Однако я столкнулся и сообщил о некоторых проблемах.

Также вы можете проверить http://unxutils.sourceforge.net/ потому что он содержит tee (и не нужен cygwin), но будьте осторожны, что выходные EOL являются UNIX-подобными.

И последнее, но не менее важно, если у вас есть PowerShell, вы можете попробовать Tee-Object. Введите в консоли PowerShell для получения дополнительной информации.

Это работает, хотя это немного уродливо:

Это немного более гибко, чем некоторые другие решения, поскольку он работает по-своему, поэтому вы можете использовать его для добавления.

Я использую это довольно много в пакетных файлах для регистрации и отображения сообщений:

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

Перенаправление ввода и вывода

По крайней мере, таким образом вам не нужно вносить изменения в сообщения в двух местах.

Обратите внимание, что _ — это просто короткое имя файла, поэтому вам нужно будет удалить его в конце вашего пакетного файла (если вы используете пакетный файл).

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

Если у вас есть cygwin в вашем пути к среде Windows, вы можете использовать:

Простое консольное приложение C # сделало бы трюк:

Чтобы использовать это, вы просто передаете исходную команду в программу и указываете путь к любым файлам, для которых вы хотите дублировать вывод. Например:

Будет отображать результаты поиска, а также сохранять результаты в файлах files1.txt и files2.txt.

Обратите внимание, что на пути обработки ошибок не так много (ничего!), И поддержка нескольких файлов может не потребоваться.

Я также искал одно и то же решение, после небольшой попытки, я смог успешно выполнить это в командной строке. Вот мое решение:

Он даже захватывает любую команду PAUSE.

Альтернативой является tee stdout для stderr в вашей программе:

Затем в вашем dos batchfile:

Stdout перейдет в файл журнала, и stderr (те же данные) отобразятся на консоли.

Как отобразить и перенаправить вывод в файл. Предположим, что если я использую команду dos, dir> test.txt, эта команда перенаправляет вывод в файл test.txt без отображения результатов. как написать команду для вывода вывода и перенаправления вывода в файл с помощью DOS, т. е. командной строки Windows, а не в UNIX / LINUX.

Вы можете найти эти команды в biterscripting (http://www.biterscripting.com) полезными.

Это вариант предыдущего answer MTS, однако он добавляет некоторые функции, которые могут быть полезны другим. Вот метод, который я использовал:

  • Команда задается как переменная, которая может использоваться позже в коде, для вывода в командное окно и добавления в файл журнала с использованием
    • команда избегает redirection с использованием символа моркови, чтобы команды не оценивались первоначально
  • Временной файл создается с именем файла, аналогичным пакетному файлу с именем который использует синтаксис расширения параметра командной строки чтобы получить имя командного файла.
  • Результат добавляется в отдельный файл журнала

Вот последовательность команд:

  1. Сообщения вывода и ошибки отправляются во временный файл
  2. Содержимое временного файла тогда равно:
    • добавлен в файл журнала
    • вывод в командное окно
  3. Временный файл с сообщением удаляется

Вот пример:

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

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

Я согласен с Брайаном Расмуссеном, порт unxutils — самый простой способ сделать это. В разделе « Пакетные файлы » его страниц Scripting Rob van der Woude предоставляет массу информации об использовании команд MS-DOS и CMD. Я подумал, что у него может быть собственное решение вашей проблемы, и после того, как я TEE.BAT там копаться, я нашел TEE.BAT , который, кажется, именно так, представляет собой пакетный языковой пакет MS-DOS. Это довольно сложный пакетный файл, и я бы склонен использовать порт unxutils.

Я устанавливаю perl на большинстве своих машин, поэтому ответ с помощью perl: tee.pl

dir | perl tee.pl или каталог | perl tee.pl dir.bat

сырой и непроверенный.