簡體   English   中英

在bash tee中,使函數變量成為局部變量,我該如何轉義?

[英]In bash tee is making function variables local, how do I escape this?

我堅持使用bash scipt,它應該同時寫入stdout和文件。 我正在使用函數和其中的一些變量。 每當我嘗試將函數重定向到文件並使用tee在屏幕上打印時,我都無法使用函數中使用的變量,因此它們會以某種方式變為局部變量。 這是簡單的示例:

#!/bin/bash
LOGV=/root/log

function var()
{
echo -e "Please, insert VAR value:\n"
read -re VAR
}
var 2>&1 | tee $LOGV
echo "This is VAR:$VAR"

輸出:

[root@testbox ~]# ./var.sh   
Please, insert VAR value:

foo
This is VAR:
[root@testbox ~]#

提前致謝!

編輯:響應@Etan Reisner建議使用var 2>&1 > >(tee $LOGV)

這種構造的唯一問題是日志文件無法接收所有內容...

[root@testbox~]# ./var.sh
Please, insert VAR value: 

foo 
This is VAR:foo
[root@testbox ~]# cat log 
Please, insert VAR value:

這是BashFAQ#24的變體。

var 2>&1 | tee $LOGV

...像任何Shell管道一樣,可以選擇在子進程中運行var函數,並且實際上在bash中具有這種行為。 (POSIX sh規范未定義哪些管道組件(如果有)在父外殼程序內部運行的詳細信息)。


避免這種情況就像不使用管道一樣簡單。

var > >(tee "$LOGV") 2>&1

...使用進程替換(bash采用的ksh擴展名,在POSIX sh中不存在)通過文件名(在現代Linux上為/dev/fd/##形式)表示tee子進程,可以將輸出重定向到將功能移動到管道中。


如果要確保在其他命令運行之前退出tee ,請使用鎖:

#!/bin/bash
logv=/tmp/log

collect_var() {
        echo "value for var:"
        read -re var
}
collect_var > >(logv="$logv" flock "$logv" -c 'exec tee "$logv"') 2>&1
flock "$logv" -c true # wait for tee to exit

echo "This is var: $var"

順便說一句,如果您要運行多個命令,並且以這種方式將它們的輸出通過管道傳輸,則應該僅調用tee一次,並根據需要將其輸入:

#!/bin/bash
logv=/tmp/log
collect_var() { echo "value for var:"; read -re var; }

exec 3> >(logv="$logv" flock "$logv" -c 'exec tee "$logv"') # open output to log
collect_var >&3 2>&3         # run function, sending stdout/stderr to log
echo "This is var: $var" >&3 # ...and optionally run other commands the same way
exec 3>&-                    # close output
flock "$logv" -c true        # ...and wait for tee to finish flushing and exit.

暫無
暫無

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

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