#bat #cmd
Есть некоторая необходимость производить логирование работы программы, при этом не
хотелось бы терять возможность отображения данных на экране консоли.
Команда:
dir > List.txt
произведет запись каталогов и файлов текущей директории в указанный файл. Хотелось
бы, чтобы данные также еще отобразились в консоли. Есть возможность наверняка такая,
например:
dir > list.txt 2>&1
но никак не соображу, как можно один поток писать и на экран и в файл.
Ответы
Ответ 1
Если у вас нет доступа к утилите tee, вы можете написать и скомпилировать её сами. Например, так: /* Tee utility by VladD Use it in whichever way you like Hopefully it doesn't do anything bad, but no warranty Compiles with MSVC 2012 */ #include "stdafx.h" // comment this line out if compiling with non-Microsoft compiler #include#include #include #include #include using namespace std; bool append = false; char** curr_arg; vector target_streams; vector stream_names; bool have_open_error = false; bool have_io_error = false; void evaluate_args() { for (; *curr_arg; curr_arg++) { string arg(*curr_arg); if (arg == "--") { curr_arg++; break; } else if (arg == "-a") { append = true; } // add more arguments here else if (arg.size() > 0 && arg[0] == '-') { cerr << "Unknown argument: " << arg << endl; exit(1); } else { break; } } } void create_streams() { auto openmode = ios::out | (append ? ios::app : ios::trunc); target_streams.push_back(&cout); stream_names.push_back("-"); for (; *curr_arg; curr_arg++) { string arg(*curr_arg); ostream* p; if (arg == "-") { p = &cout; } else { p = new ofstream(arg, openmode); if (!*p) { delete p; cerr << "Cannot open file `" << arg << "'" << endl; have_open_error = true; return; } } target_streams.push_back(p); stream_names.push_back(arg); } } void destroy_streams() { for (auto p : target_streams) { if (p != &cout) delete p; } } void process() { string line; while (getline(cin, line)) { for (size_t i = 0; i < target_streams.size(); i++) { auto p = target_streams[i]; if (!p) continue; (*p) << line << endl; if (!*p) { cerr << "Error occured writing to stream `" << stream_names[i] << "'" << endl; delete p; target_streams[i] = nullptr; have_io_error = true; } } } } int main(int argc, char* argv[]) { curr_arg = argv + 1; evaluate_args(); create_streams(); process(); destroy_streams(); return (have_open_error ? 0x2 : 0) | (have_io_error ? 0x4 : 0); } Ответ 2
В 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 и пользоваться соответствующим набором утилит. Для одной конкретной задачи это, возможно, слишком сложное решение. Но если необходимость в автоматизации и скриптах возникает часто, то в долгосрочной перспективе это, наверняка, будет оптимальным решением.Ответ 3
Есть способ, конечно же...и не один. Самое первое, что мне пришло в голову, так это объединение команд: dir > C:\log.txt && dir Можно также тупо сначала писать логи в файл, а затем сразу же выводить их оттуда, но данный способ основан, опять же на объединении команд( и способ костыльный, имхо ).Ответ 4
тут дали пример unix-like, так если скачать UnxUtils с sourceforge, то вполне можно использовать. Там есть команда tee отдельным exeОтвет 5
Вот так: dir >list.txt >&2 или dir >list.txt 1>&2
Комментариев нет:
Отправить комментарий