5

Вернувшись в университет, когда нам нужно было отправить задание в CS, мы должны были выполнить ряд шагов, включая запуск script, date, whoami, etc. , А затем запустить нашу программу.

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

С тех пор я искал версию для Dos и / или Windows, но вышел пустой. Некоторые программы могут быть перенаправлены в файл, но тогда отображение не отображается, а некоторые программы, похоже, вообще не работают с перенаправлением.

Есть идеи?


Редактировать:

Пока что полученные ответы, похоже, работают точно так же, как стандартные команды перенаправления (<, >, |). Они не работают со всеми программами. Например, компилятор Microsoft C++ CL.EXE. Если вы запускаете cl /? с помощью команды перенаправления или передачи через другую программу (например, TEE) вы не получите заголовок / текст баннера.

Другой пример - программа, которую я написал некоторое время назад на Паскале (я думаю, что последняя компиляция была во FreePascal). Текст справки вообще не перенаправляется. Я видел, как это происходит с другими программами, такими как MKISOFS. Он имеет длинный текст справки, но его нельзя приостановить, отправив его через БОЛЬШЕ или перенаправив в файл!

Я размышлял об этом много лет. Раньше я думал, что это может быть потому, что текст пишется прямо на экран (например, порт B800) или что-то, но я еще не выяснил причину, не говоря уже о том, чтобы найти программу, которая может выполнить эту работу.

7 ответов7

2

Взгляните на Cygwin, он дает вам доступ ко всем этим замечательным инструментам командной строки UNIX в Windows.

2

Хорошо, как обычно, я взял на себя задачу написать программу. Сегодня вечером у меня было немного свободного времени, и я собрал собственную (то есть, не Cygwin) тестовую программу, которая работает именно так, как я надеялся, хотя и с двумя ограничениями. (У меня нет постоянно включенного хоста, но я позабочусь о том, чтобы очистить программу, написать документы и выпустить ее.)

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

  2. Он не может получить вход от stderr. Например, если вы выполняете cl /? | script.exe c:\test.log , только файл справки компилятора Microsoft будет отправлен в файл; баннер будет отображаться только на экране. (Это несколько сбивает с толку из-за того, как работает программа, поэтому я собираюсь разобраться в этом.)

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

Проблему (2) можно обойти, перенаправив stderr в stdout перед тем, как передать его следующим образом. Это не красиво (или не так удобно, но работает).

cl /? 2>&1| script.exe c:\test.log

Это может / должно также быть работоспособным со стороны программы, тем самым упрощая конвейер, но мне еще предстоит найти какую-либо информацию о том, как (по крайней мере, «обычным / официальным» способом, например, через C++). У меня есть идея установить обработчик прерываний в таблицу векторов прерываний для перехвата вызовов общих функций API-интерфейсов, которые могут / вероятно будут работать. Фактически, в 1998 году я написал экспериментальный DOS TSR (который также работает в Windows NTVDM), который перехватывает выходные функции и окрашивает их (то есть, общую синтаксическую раскраску) перед отправкой их на экран. Было бы / должно быть легко адаптировать его для отправки копии в файл.

1

Я нашел порт Cygwin для команды сценария Unix. Он захватывает как STDOUT, так и STDERR (поэтому он получает выходные данные заголовка из cl.exe).

Однако захват команд cmd.exe немного запутан по двум причинам:

  • Сценарий порождает оболочку Cygwin Bash (не cmd.exe)
  • скрипт не работает при запуске из оболочки cmd.exe; это должно быть начато с Cygwin.

Вы можете сделать это, хотя:

  1. откройте оболочку cygwin.
  2. стартовый скрипт
  3. запустить оболочку cmd.exe из оболочки cygwin
  4. делай свои вещи в cmd.exe
  5. выход из cmd.exe
  6. выйти из сценария

* также оболочка cmd.exe, порожденная изнутри cygwin, действует немного странно, но команды, кажется, работают:

  • окно, которое обычно появляется, если вы пытаетесь запустить cl.exe без первого запуска vcvars32.bat, не появляется
  • ввод с консоли очень привередливый (например, ввод LEFT RIGHT cl или UP cl не работает.)
1

В этом разделе часто задаваемых вопросов по General Pascal объясняется причина, а также решение для программ Turbo Pascal.

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

О. Вы, вероятно, используете модуль CRT, и его стандартный метод записи в стандартный вывод - прямая запись на экран. Чтобы разрешить перенаправление вывода, все записи должны выполняться DOS. Установка переменной DirectVideo в значение false не влияет на перенаправление, так как все, что она делает, это использует BIOS для записи экрана, а не DOS.

Чтобы включить перенаправление, вы не должны использовать блок CRT

ИЛИ ЖЕ

assign(output,'');
rewrite(output);

Это заставит весь вывод пройти через DOS и, таким образом, может быть перенаправлен при желании. Чтобы восстановить ситуацию по умолчанию:

AssignCRT(output);
rewrite(output);
1

К сожалению, кажется, что вам не повезет найти готовое решение Microsoft. Вы можете проверить аналогичный пост на StackOverflow. Дайджест:

1

Многие альтернативы CMD облегчают жизнь на многих направлениях, в том числе решают проблему, указанную вами в отсутствующей команде сценария. Я использовал PowerCMD, и он перенаправляет вывод в свою папку журнала по умолчанию. Таким образом, как конечный пользователь, вы будете видеть команды при вводе, а также ошибки и вывод команд, в то время как вся ваша работа "записывается" в файл журнала.

Чтобы настроить его в PowerCMD, зайдите в File -> Preference -> Auto Save.

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

c:\Software\Microsoft\SysinternalsSuite>date
The current date is: Fri 02/13/2015 
Enter the new date: (mm-dd-yy) 
c:\Software\Microsoft\SysinternalsSuite>someBadCommand
'someBadCommand' is not recognized as an internal or external command,
operable program or batch file.
0

Это действительно два вопроса в одном, один для DOS и один для Windows, хотя ответ для обоих одинаков.

Это просто невозможно для такой программы существовать.

Существует два основных варианта script на Unices и на Linux. Один (такой как эта версия Linux) использует каналы, другой (такой как эта версия HP/UX) использует псевдотерминалы, чтобы избежать проблем с программами TUI, которые представляют "полноэкранные" интерфейсы, которые есть у конвейерного подхода. Windows NT просто не имеет псевдо-терминального механизма. В Windows NT просто невозможно захватить ввод-вывод в консоль и из консоли, как это происходит с псевдо-терминалами в системах POSIX. Можно использовать подход трубы, но ...

  • ... DOS не имеет трубного механизма. (Не смущайтесь тем, что вы можете делать в интерпретаторах команд DOS. Это не трубы.)
  • ... в Windows NT он будет страдать от проблем - почти таких же, как для конвейерного подхода в Unices и Linux - что ...
    • … Некоторые программы распознают, что их стандартный вывод не является консолью, и действуют иначе.
    • ... другие программы, которые обрабатывают канал как консоль, потерпят неудачу, потому что устройства канала не поддерживают системные вызовы консоли.

Cygwin полагается на сотрудничество целевых программ под общим предлогом.

Вам может быть интересно узнать о команде script Cygwin и о том, почему она работает не совсем корректно с другими программами, отличными от Cygwin.

Cygwin пытается эмулировать псевдо-терминалы, используя каналы Windows NT. Он основан на том факте, что каждая программа Cygwin использует библиотеку времени выполнения Cygwin, которая "знает", когда канал "действительно" является псевдо-терминалом, использует информацию, закрытую для библиотеки времени выполнения Cygwin, и действует соответствующим образом. Функция isatty() библиотеки времени выполнения говорит "да", когда среда выполнения видит канал, который "действительно" является псевдо-терминалом Cygwin. Таким образом, программы Cygwin, запускаемые script Cygwin, будут работать так, как будто они подключены к (псевдо) терминалам.

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .