There is some need to make logging of the program, but I would not like to lose the ability to display data on the console screen.

Team:

dir > List.txt 

will write the directories and files of the current directory to the specified file. It would be desirable, that the data also was still displayed in the console. There is an opportunity for sure such, for example:

 dir > list.txt 2>&1 

but I can’t figure out how to write one stream on both the screen and the file.

  • See if there is a command (executable file) tee. In unix-like it is used for such tricks ls | tee file> file1 - alexlz
  • though late, but (for pro forma): "Using command redirection operators" windowsfaq.ru/content/view/260/57 - SpillbergFromUSA

5 answers 5

If you do not have access to the tee utility, you can write and compile it yourself.

For example:

 /* 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 <iostream> #include <fstream> #include <vector> #include <string> #include <cstdlib> using namespace std; bool append = false; char** curr_arg; vector<ostream*> target_streams; vector<string> 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); } 
  • Original license)) - Nick Volynkin
  • @NickVolynkin: Well :-) - VladD

In the shell and its descendants, there is the utility tee , which is designed to redirect streams and simultaneously write them to a file. man tee:

 tee [ -ai ] [ File ... ] 

The copy of the utility will be sent to the 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. 

The easiest way to access it is to install cygwin , and the easiest way to install it is via chocolatey . After that, you will be able to write scripts in bash and use the appropriate set of utilities.

For one particular task, this may be too complicated a solution. But if the need for automation and scripts often arises, then in the long run this will probably be the best solution.

    There is a way, of course ... and not one. The very first thing that occurred to me was the unification of commands:

     dir > C:\ log.txt && dir 

    You can also stupidly first write logs to a file, and then immediately output them from there, but this method is based, again on the merging of commands (and the method of the crutch, IMHO).

    • and this combination does not mean that the dir command was executed 2 times? .. I have a feeling that the dir command is executed, the data is written to the file, then the dir command is executed and the data is displayed on the screen ... Just for the utility that logs will output , this is not acceptable, it turns out, it will work 20 minutes to write to the log, and then the same amount to display on the screen =)) then it’s easier to write to the file, and then display the file to the screen =)) but I would like to so that the information on the screen is updated as data becomes available. - pincher1519

    they gave an example of unix-like, so if you download UnxUtils from sourceforge, then you can use it. There is a tee command for a separate exe

      Like this:

       dir >list.txt >&2 

      or

       dir >list.txt 1>&2 
      • Something is not working ... - Qwertiy
      • @Qwertiy Yes, the error came out. So far it has only happened with wintee code.google.com/archive/p/wintee - user207665