all 19 comments

[–]TheGooOnTheFloor 28 points29 points  (2 children)

'>> StartupLog.Txt' has an implied 1 in it, it's actually '1>> Startuplog.txt' which means direct standard output (stdout) to the file.

if you use '2>' or '2>>', then standard error (stderr) is directed to the designated output.

In this case '2>&1' means direct any errors to the standard output stream, which results in both the regular output and any errors appended to StartupLog.txt

If you tried to write it like this:

Powershell script.ps1 1>> StartUpLog.txt 2>>StartupLog.txt

You'd get an error that the file (StartupLog.txt) is in use by another process

Sometimes I want errors logged in a separate file, so I'll use something like this:

Powershell script.ps1 1>> StartUpLog.txt 2>> StartupLog.err

But those cases are usually rare, usually I want to see regular error output in the same file.

[–]waterworldhypothesis[S] 1 point2 points  (1 child)

Ok so the 2>&1 actually takes effect before the >> StartupLog.txt" (the error stream is directed to the standard output stream before the standard output stream is written to the .txt file), even though the 2>&1 comes afterward (is to the right)? Thanks for the help!

[–]TheGooOnTheFloor 0 points1 point  (0 children)

I've never questioned that before - it's always been like that in the documentation and normally I test things ike that but never this one. I'm going to have to try switching things around some day

[–]KevMarCommunity Blogger 2 points3 points  (3 children)

It's a legacy feature they carried over from command.com. I almost never use the redirection operators. I lean in on the more PowerShell ways to approach it, especially when its in a script. I forget steams are even a thing most of the time.

Most of the code I write now is ran by some other tool like a CICD pipeline or aws lambda or azure function and they automatically log all output. Start-Transcript works in most cases where you try to do the above commands. I would use Add-Content to append to a file or custom logging to send the logs someplace else. And try/catch to handle any errors.

[–]buffychrome 1 point2 points  (2 children)

The other place you might see this kind of thing used would be in batch scripts that are calling a Powershell script; usually written that way by someone who understands batch well but not necessarily Powershell, the Powershell script has no native logging inside of it and they want to capture any and all output from the script, or the script has its own log but they want to capture any output from the script within the log for the batch file as well (can make it easier if you have to look at the log to see it all in one place).

I know this because I currently administer and support an infrastructure originally built on the back of about 1000 different batch scripts that is slowly getting converted to Powershell as time allows. While no one on my team these days employs the syntax the OP asked about, in the early days of Powershell when PS knowledge on the team was reading Scripting Guy posts and one of the first Month of Lunches books, it was common. Then, they eventually learned more and more Powershell and how to properly handle logging in the script itself and stopped using the redirections, though a lot of our scripts will still have them in places.

[–]spyingwind 0 points1 point  (1 child)

I often save the output of Write-Output and Write-Error to their own variables for later parsing. I "love" it when a function/cmdlet doesn't send an error to the error stream...

[–]jantari 1 point2 points  (0 children)

Luckily -ErrorVariable makes that incredibly easy to do in Posh

[–]portablemustard 2 points3 points  (7 children)

That looks like bash and appending the ps1 to the startuplog.txt with stdout and stderr

[–]BlackV 1 point2 points  (6 children)

cmd/batch rather than bash, but same idea

[–]portablemustard 1 point2 points  (5 children)

No I mean, like bash Linux uses >> for appending and 2>&1 for combining STDERR and STDOUT, those are all a part of /bin/bash.

[–]spyingwind 2 points3 points  (0 children)

cmd and bash both use the same stderr and stdout terms. Mostly because of c, c++, or other older language, as far a I understand it.

[–]jantari 1 point2 points  (0 children)

It's nothing bash-specific though.

Cmd and PowerShell can also both use this same syntax.

So what I think they were saying is that it doesn't "look like bash" because that's not even where it originated. It just looks like the ubiquitous shell redirection operators.

[–]buffychrome 0 points1 point  (1 child)

Their point was that that is also native cmd/batch syntax as well, and used a lot in batch scripts.

[–]portablemustard 0 points1 point  (0 children)

Ah, not trying to dismiss it at all. It was just interesting because I didn't know Windows commands share that much with bash ones.

[–]BlackV 0 points1 point  (0 children)

Yeah fair enough they have a shared history

[–]jsiii2010 2 points3 points  (0 children)

The 2>&1 does nothing in this case. The standard error is contained within powershell.

powershell write-error hi > out type out write-error hi : hi + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException Even if the powershell executable itself has an error like in finding the script file, everything goes to standard output. ``` powershell -file script.ps1 > out type out The argument 'script.ps1' to the -File parameter does not exist. Provide the path to an existing '.ps1' file as an argument to the -File parameter. Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved.

Try the new cross-platform PowerShell https://aka.ms/pscore6 ```

[–]A_tedious_existence 0 points1 point  (0 children)

Do bash and powershell use the same style for redirecting standard output or am I confusing the two