我有一個陷阱方法,它既不能訪問全域變數,也不能使用$*. 它看起來像這樣:
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
declare -a arr
finish_exit() {
echo "* = $*"
echo "arr = ${arr[*]}"
}
trap 'finish_exit "${arr[@]}"' EXIT
main() {
arr =("hello")
arr =("world")
}
main | tee -a /dev/null
腳本列印''。
如果我洗掉該| tee -a ...片段,腳本會按預期列印兩次 'hello\nworld'。
現在,如何在不丟失所有背景關系的情況下將輸出通過管道傳輸到日志檔案?一種解決方案是從腳本呼叫中路由所有內容,如下所示:
./myscript.sh >> /dev/null,但我認為應該有一種方法可以在腳本中執行此操作,這樣我就可以記錄每個呼叫,而不僅僅是那些由 cron 運行的呼叫。
我研究的另一個解決方案是:
main() {
...
} >> /dev/null
但這將導致互動式 shell 上沒有輸出。
獎勵業力解釋為什么這個子shell會在呼叫陷阱函式之前“擦除”全域變數。
uj5u.com熱心網友回復:
將使陷阱方法看不到全域變數
子shell 確實“看到”全域變數,它不執行陷阱。
為什么這個子shell會“擦除”全域變數
來自https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html:
命令替換、用括號分組的命令和異步命令在作為 shell 環境副本的子 shell 環境中呼叫,除了 shell 捕獲的陷阱被重置為 shell 在呼叫時從其父 shell 繼承的值。
如何在不丟失所有背景關系的情況下將輸出通過管道傳輸到日志檔案?
#!/bin/bash
exec 1> >(tee -a logfile)
trap 'echo world' EXIT
echo hello
要么
{
trap 'echo world' EXIT
echo hello
} | tee -a logfile
和研究:https ://serverfault.com/questions/103501/how-can-i-fully-log-all-bash-scripts-actions和類似的。
以下腳本:
#!/usr/bin/env bash
set -euo pipefail
{
set -euo pipefail
IFS=$'\n\t'
declare -a arr
finish_exit() {
echo "* = $*"
echo "arr = ${arr[*]}"
}
trap 'finish_exit "${arr[@]}"' EXIT
main() {
arr =("hello")
arr =("world")
}
main
} | tee -a /dev/null
為我輸出:
* = hello
world
arr = hello
world
我在管道set -o pipefail 之前添加了它,以保留退出狀態。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/439469.html
標籤:重击
上一篇:如何在后臺運行命令并捕獲輸出
下一篇:Mongodump歸檔記錄計數
