Bash

將 bash stdout+stderr 重定向到一個文件,將 stderr 重定向到另一個文件

  • October 22, 2020

我需要將所有輸出重定向到一個文件,此外還需要將 stderr 重定向到另一個文件。這可以輕鬆完成嗎?

假設我在本範例中的命令是:

php /tmp/doWork.php

我可以使用以下方法將輸出輸出到單獨的文件:

php /tmp/doWork.php 1> /tmp/stdout_file 2> /tmp/stderr_file

基於,我嘗試:

php /tmp/doWork.php &> /tmp/stdboth_file 2> /tmp/stderr_file

但這只是將 stdout 和 stderr 放入/tmp/stdboth_file並且從未寫入/tmp/stderr_file.

使用zsh(並且zsh僅)及其multios功能:

your-cmd 2> stdout+stderr.log >&2 2> stderr.log

由於 fd 2 被重定向兩次,因此zsh實現了內部tee以將其發送到兩個文件。

使用bash(或任何類似 Bourne 的 shell(除了zsh您需要禁用multios它才能在此處工作的地方)),您可以tee手動執行以下操作:

{ your-cmd 2>&1 >&3 3>&- | tee stderr.log 3>&-; } > stderr+stdout.log 3>&1

(儘管您失去了your-cmd. zshhas it in的退出狀態$pipestatus[1],但bash在其中"${PIPESTATUS[0]}"(前提是重定向到stderr+stdout.log沒有失敗))。

要記錄 的 pid your-cmd,您可以執行以下操作:

{ sh -ec 'echo "$$" > /var/run/pidfile; exec your-cmd' 2>&1 >&3 3>&- |
  tee stderr.log 3>&-; } > stderr+stdout.log 3>&1

具有yash和它的程序重定向功能:

your-cmd > stdout+stderr.log 2>(tee stderr.log)

(但請注意,yash不會等待該tee命令的終止,因此在您執行下一個命令時日誌文件可能尚未完成)。

可以通過,和中的程序替換來完成類似的事情(並且具有相同的警告) :bash``zsh``ksh93

{ your-cmd 2> >(tee stderr.log); } > stderr+stdout.log

要在後台執行並獲取 pid:

(exec your-cmd 2> >(tee stderr.log)) > stderr+stdout.log & pid=$!

rc

{your-cmd |[2=0] tee stderr.log} > stdout+stderr.log

rc的管道允許指定哪些文件描述符連接到管道。對於其他 shell,它始終是左側命令的 fd 1 和右側命令的 fd 0 (因此與上面的 fd 3 一起移動文件描述符)。如果其中之一或失敗,rc將報告失敗,但確切的數字可能會失去。your-cmd``tee

引用自:https://unix.stackexchange.com/questions/364166