12

I use this command to see output both in the console and a file:

powershell -command "my_command_1 | tee ('logs\{0}.log' -f (Get-Date -format 'yyyy.MM.dd-HH.mm'))"  
powershell -command "my_command_2 | tee ('logs\{0}.log' -f (Get-Date -format 'yyyy.MM.dd-HH.mm'))"
# etc

It works not as good as I expected and I have some questions:

  1. How do I redirect stderr also to a file?
  2. The output works very strange. For some commands there is a huge delay between text is printed and console/file is updated. For some other commands output seems updated when text is printed (I run commands without tee and I know what it should print). This delay makes this tee almost useless - what if some critical error will be printed so I need to stop the command, but I won't see anything until it's too late?

    For some commands output is printed only after the full command is done.

  3. Furthermore, even if the command asks user input, the console/file output is empty! For that command I know what it expects and blindly print needed text and it worked, but for others - with no output I'll wait something to happen infinitely while the command will wait for my input!

Are there solutions for these issues? If not, this tee thing in PowerShell is completely useless.

3
  • I'm hesitant to believe that a tool used in thousands of scripts is "completely useless" just because it may not meet your specific requirements. Apr 20, 2011 at 6:52
  • Right, I mean it's useless in this particular case :) I'd better leave tee alone, than will have such bad issues.
    – race1
    Apr 20, 2011 at 13:21
  • When the source of the pipeline is a plain executable writing string data to stdout (rather than a cmdlet with typed output), the pipeline will pass data to consumer in one string object, only after the source exits, as opposed to passing chunk by chunk like in Bash on Linux. A workaround is to write your own tee-like program to avoid the pipeline. Like this: stackoverflow.com/a/56051270/435522
    – alexei
    Dec 16, 2022 at 1:46

1 Answer 1

10
  1. My-Command 2>&1 | Tee-Object 'myfile.log'. See Get-Help about_Redirection.
  2. You should be trapping errors, not relying on Ctrl+C. See Get-Help about_Try_Catch_Finally. Is the command you're running an external program or a script?
  3. As I understand it, typically string objects are not sent down the pipe until an end-of-line character is reached. The reason is quite simple: if it didn't do this, partial (read: incomplete) strings would go down the pipe. Tee might handle partial strings fine, but other cmdlets like ForEach-Object or Select-Object certainly would not. Note that Get-Content has a special switch -ReadCount which somewhat overrides this behavior, and it will seriously mess with a Select-Object -Skip/-First/-Last/-Unique command further down the pipe.

It very well may be that external programs you're running aren't going to obey the conventions that PowerShell is expecting. Tee, for example, is properly called Tee-Object, which should tell you the kinds of things it's good at working with. In that case, you may be further along the line to get tee.exe from GNU Win32 Utils or MSYS which are designed for immediately forwarding content.

2
  • 1. Thanks; 2. Correct, I meant some critical unforeseen situations; 3. I don't understand what is guilty for incomplete strings :) Eventually my commands run Python scripts - it's fabric commands. I tried to use tee.exe from linux utils compiled for windows - the same result, no output in some cases. Does that mean that my concrete configuration and concrete scripts won't work well with tee utilities at all? Thank you.
    – race1
    Apr 20, 2011 at 13:20
  • That sounds to me like the python script is misbehaving.
    – Bacon Bits
    Apr 22, 2011 at 12:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .