[英]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
因為我們要取消輸出文件名( stdout
和stderr
),所以對於上面的代碼來說,這些文件名必須是恆定的-可以使用所需的任何臨時目錄。
顯然,您實際上不應執行任何此類操作。 更新程序以支持其本國語言(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.