
我可以使用以下命令將腳本的輸出從腳本內部重定向到日誌檔案exec
:
#!/bin/bash
exec > stdout.log 2>&1
echo hello world
是否可以將輸出重定向到less
而不是檔案?我試過
#!/bin/bash
exec > >(less) 2>&1
# output some text
for (( i=1; i <= 500; i++ )); do echo "hello world $i"; done
但這以一種奇怪的方式失敗了......可見的提示較少,但您最終回到了終端。
我想將其設定為腳本的開頭(因此它可以是有條件的,取決於參數、tty 等)。
答案1
您應該讓腳本等待less
子進程,否則您的腳本將在其之前終止,並且less
會突然發現自己位於前台進程組之外,無法再從終端讀取命令或恢復終端設定。
另外,為了防止less
永遠等待輸入結束,您的腳本應該關閉它的管道。
把所有這些放在一起:
exec > >(less) 2>&1
trap 'exec >&- 2>&-; wait' EXIT
# >&- 2>&- => close stdout and stderr => cause EOF on less' stdin
seq 1 50000
# the rest of your script
但這不是很好,不能移植到大多數其他 shell,並且依賴 bash 的未記錄(且不可靠)行為:wait
如果您的腳本中有多個腳本exec > >(...)
,則該方法將無法正常工作,並且它還會等待其他背景進程以 開始&
。
更好的想法是讓腳本呼叫自身,使用環境變數來避免無限遞歸:
if [ ! "$CALLED_MYSELF" ]; then
set -o pipefail # supported in bash, but not in all the shells
CALLED_MYSELF=1 "$0" "$@" 2>&1 | less
exit
fi
seq 1 50000
# the rest of your script
答案2
試試這個(不含線exec
):
for (( i=1; i <= 500; i++ )); do echo "hello world $i"; done | less
(更新)
如果您想包含整個腳本,可以將腳本包裝為{ ... }
#!/bin/bash
{
# output some text
for (( i=1; i <= 500; i++)) do echo "hello world $i"; done
# whatever output you want...
} | less