簡體   English   中英

分別重定向和重組stderr / stdout,而不會丟失順序

[英]Separately redirecting and recombining stderr/stdout without losing ordering

我想執行一個命令,並想重定向stderr和stdout,如下所示:

stderr和stdout->僅應在保持順序的同時寫入logs.log文件

stderr->應該打印到SCREEN並也寫入errors.log

到目前為止,我可以將它們重定向到屏幕和文件log.txt,如下所示:

command 2>&1 | tee logs.log

但是以上不是我所需要的。

為了更清楚地說明結果是什么。

執行命令后,我只需要在屏幕上看到stderr的結果,我需要使用stderr創建一個名為errors.log的文件,而在目錄中需要使用stdout和stderr生成另一個名為logs.log的文件。創建它們的原始順序。

從理論上講,如果沒有一些丑陋的黑客手段,則在執行單獨的重定向時保持完美的順序是不可能的。 僅在直接寫入同一文件(在O_APPEND模式下)時保留順序。 一旦在一個進程中放置了類似tee東西,而沒有在另一個過程中放了東西,那么排序保證就會消失,並且如果不保留有關以什么順序調用了哪些syscall的信息,就無法檢索到。

那么,這種黑客將是什么樣子? 它可能看起來像這樣:

# eat our initialization time *before* we start the background process
sudo sysdig-probe-loader

# now, start monitoring syscalls made by children of this shell that write to fd 1 or 2
# ...funnel content into our logs.log file
sudo sysdig -s 32768 -b -p '%evt.buffer' \
  "proc.apid=$$ and evt.type=write and (fd.num=1 or fd.num=2)" \
  > >(base64 -i -d >logs.log) \
  & sysdig_pid=$!

# Run your-program, with stderr going both to console and to errors.log
./your-program >/dev/null 2> >(tee errors.log)

也就是說,這仍然是丑陋的駭客:它只捕獲直接寫入FD 1和FD 2的消息,並且不會跟蹤可能發生的任何進一步重定向。 (這可以通過執行對FIFO的寫操作,並使用sysdig跟蹤對這些FIFO的寫操作來改善;這樣fdup()和類似的操作將按預期方式工作;但是以上足以證明這一概念)。


明確進行單獨處理

在這里,我們通過告訴sysdig生成JSON流作為輸出,然后對其進行迭代,演示了如何使用此方法僅對stderr着色,並保持stdout sysdig

exec {colorizer_fd}> >(
  jq --unbuffered --arg startColor "$(tput setaf 1)" --arg endColor "$(tput sgr0)" -r '
    if .["fd.filename"] == "stdout" then
      ("STDOUT: " + .["evt.buffer"])
    else
      ("STDERR: " + $startColor + .["evt.buffer"] + $endColor)
    end
  '
)

sudo sysdig -s 32768 -j -p '%fd.filename %evt.buffer' \
  "proc.apid=$$ and evt.type=write and proc.name != jq and (fd.num=1 or fd.num=2)" \
  >&$colorizer_fd \
  & sysdig_pid=$!

# Run your-program, with stdout and stderr going to two separately-named destinations
./your-program >stdout 2>stderr

因為我們要取消輸出文件名( stdoutstderr ),所以對於上面的代碼來說,這些文件名必須是恆定的-可以使用所需的任何臨時目錄。


顯然,您實際上不應執行任何此類操作。 更新程序以支持其本國語言(Java中的Log4j,Python日志記錄模塊等)可用的任何日志記錄基礎結構,以允許對其日志記錄進行顯式配置。

這將為您提供大部分幫助:

your_command 2> >(tee -a logs.log errors.log) 1>>logs.log

但我認為您將無法完全將輸出的順序保留在logs.log文件中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM