パスワードを忘れた? アカウント作成
351206 journal

Ryo.Fの日記: PowerShellのリダイレクションの謎 4

日記 by Ryo.F

PowerShellにはリダイレクション演算子がある。例えば、次のように使える:

PS C:\Users\Administrator> get-process none, powershell
Get-Process : 名前 "none" のプロセスが見つかりません。プロセス名を確認し、コマンドレットを再度呼び出してください。
発生場所 行:1 文字:12
+ get-process <<<<  none, powershell 2>&1
    + CategoryInfo          : ObjectNotFound: (none:String) [Get-Process]、ProcessCommandException
    + FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand
 
Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    606      26    46520      46924   576     1.22   2688 powershell
    843      27    40328      53576   568     3.83   3020 powershell
 
PS C:\Users\Administrator>

このエラー出力と標準出力をまとめてファイルへリダイレクトしたい。

PS C:\Users\Administrator> get-process none, powershell 2>&1 > log.txt
PS C:\Users\Administrator> cat log.txt
Get-Process : 名前 "none" のプロセスが見つかりません。プロセス名を確認し、コマンドレットを再度呼び出してください。
発生場所 行:1 文字:12
+ get-process <<<<  none, powershell 2>&1 > log.txt
    + CategoryInfo          : ObjectNotFound: (none:String) [Get-Process]、ProcessCommandException
    + FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand
 
Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    597      26    46980      47424   575     1.25   2688 powershell
    843      27    40328      53576   568     3.83   3020 powershell
PS C:\Users\Administrator>

期待通り動いている。ここまでは善しとしよう。

しかし、だ。
これがPowerShellスクリプトの実行だと事情が変わってくる。「2>&1」がまったく効いていないように見える。
まず、エラーをスローするスクリプトを準備する。

PS C:\Users\Administrator> cat .\error.ps1
echo "This is not an error."
throw "This is an error."
PS C:\Users\Administrator> .\error.ps1
This is not an error.
This is an error.
発生場所 C:\Users\Administrator\error.ps1:2 文字:6
+ throw <<<<  "This is an error."
    + CategoryInfo          : OperationStopped: (This is an error.:String) []、RuntimeException
    + FullyQualifiedErrorId : This is an error.
 
PS C:\Users\Administrator>

これをリダイレクトしてみる。

PS C:\Users\Administrator> .\error.ps1 > log.txt
This is an error.
発生場所 C:\Users\Administrator\error.ps1:2 文字:6
+ throw <<<<  "This is an error."
    + CategoryInfo          : OperationStopped: (This is an error.:String) []、RuntimeException
    + FullyQualifiedErrorId : This is an error.
 
PS C:\Users\Administrator> cat log.txt
This is not an error.
PS C:\Users\Administrator>

エラー出力もまとめてログファイルにリダイレクトしたい。

PS C:\Users\Administrator> .\error.ps1 > log.txt 2>&1
This is an error.
発生場所 C:\Users\Administrator\error.ps1:2 文字:6
+ throw <<<<  "This is an error."
    + CategoryInfo          : OperationStopped: (This is an error.:String) []、RuntimeException
    + FullyQualifiedErrorId : This is an error.
 
PS C:\Users\Administrator> cat log.txt
This is not an error.
PS C:\Users\Administrator>

なんでやねん。

この議論は、Ryo.F (3896)によって ログインユーザだけとして作成されたが、今となっては 新たにコメントを付けることはできません。
  • get-process none, powershell 2>&1 > log.txt

    .\error.ps1 > log.txt 2>&1

    では、リダイレクトする順番が違うように見えますが、それは関係ないのでしょうか。

    --
    1を聞いて0を知れ!
    • 最後の例を見る限り、伝統的な/bin/sh系とはリダイレクト評価順序が違うのかも知れませんね。

      > .\error.ps1 2>&1 >log.txt

      を試してみないと判りませんが。

      # (そーだとしたら)これだよ、M$ってーのは。

      親コメント
      • 実は指摘を受ける前にやってみましたが、関係ないようです。

        PS C:\Users\Administrator> .\error.ps1 2>&1 > log.txt
        This is an error.
        発生場所 C:\Users\Administrator\error.ps1:2 文字:6
        + throw <<<<  "This is an error."
            + CategoryInfo          : OperationStopped: (This is an error.:String) []、RuntimeException
            + FullyQualifiedErrorId : This is an error.
         
        PS C:\Users\Administrator> cat .\log.txt
        This is not an error.
        PS C:\Users\Administrator>

        さらに、

        PS C:\Users\Administrator> get-process none, powershell > log.txt 2>&1
        PS C:\Users\Administrator>

        # (そーだとしたら)これだよ、M$ってーのは。

        違う意味でそうですね(笑)。

        親コメント
    • 別コメントに書きましたが、そういうことでは無いようです。

      ついでに恥をさらしておくと、昔、以下の様に嵌ったことがあります。

      sh-3.2$ ls nofile > log.txt 2>&1
      sh-3.2$ cat log.txt
      ls: nofile: No such file or directory
      sh-3.2$

      これを受けて、

      sh-3.2$ ls nofile | tee log.txt 2>&1
      ls: nofile: No such file or directory
      sh-3.2$ cat log.txt
      sh-3.2$

      失敗。さらに、

      sh-3.2$ ls nofile | 2>&1 tee log.txt
      ls: nofile: No such file or directory
      sh-3.2$ cat log.txt
      sh-3.2$

      再失敗。
      正しくは、

      sh-3.2$ ls nofile 2>&1 | tee log.txt
      ls: nofile: No such file or directory
      sh-3.2$ cat log.txt
      ls: nofile: No such file or directory
      sh-3.2$

      もしくは、

      sh-3.2$ 2>&1 ls nofile | tee log.txt
      ls: nofile: No such file or directory
      sh-3.2$ cat log.txt
      ls: nofile: No such file or directory
      sh-3.2$

      でした。

      親コメント
typodupeerror

あつくて寝られない時はhackしろ! 386BSD(98)はそうやってつくられましたよ? -- あるハッカー

読み込み中...