簡體   English   中英

“printf -v”內部功能無法使用重定向輸出

[英]“printf -v” inside function not working with redirected output

使用bash 4.1.2和4.3.48,以下腳本給出了預期的輸出:

#!/bin/bash

returnSimple() {
   local  __resultvar=$1
   printf -v "$__resultvar" '%s' "ERROR"
   echo "Hello World"
}

returnSimple theResult
echo ${theResult}
echo Done.

按預期輸出:

$ ./returnSimple
Hello World
ERROR
Done.

但是,當函數的stdout通過管道傳遞給另一個進程時, __resultvar變量的賦值不再起作用:

#!/bin/bash

returnSimple() {
   local  __resultvar=$1
   printf -v "$__resultvar" '%s' "ERROR"
   echo "Hello World"
}

returnSimple theResult | cat
echo ${theResult}
echo Done.

意外輸出:

$ ./returnSimple
Hello World

Done.

為什么printf -v在第二種情況下不起作用? 應該printf -v不寫入值的函數的輸出是否被管道輸送到另一處理結果變量獨立

請參閱man bash ,有關Pipelines部分:

管道中的每個命令都作為單獨的進程執行(即,在子shell中)。

這就是你寫cmd | cat時的原因 cmd | catcmd接收無法修改的變量副本。

一個簡單的演示:

$ test() ((a++))
$ echo $a

$ test
$ echo $a
1
$ test | cat
$ echo $a
1

有趣的是,當使用eval $__resultvar="'ERROR'"而不是printf -v語句時也會發生同樣的情況。 因此,這不是與printf相關的問題。

相反,向主腳本和函數添加echo $BASH_SUBSHELL表明shell在第二種情況下產生子shell - 因為它需要將函數的輸出傳遞給另一個進程。 因此該函數在子shell中運行:

#!/bin/bash

returnSimple() {
    local  __resultvar=$1
    echo "Sub shell level: $BASH_SUBSHELL"
    printf -v "$__resultvar" '%s' "ERROR"
}

echo "Sub shell level: $BASH_SUBSHELL"
returnSimple theResult | cat
echo ${theResult}
echo Done.

輸出:

% ./returnSimple.sh
Sub shell level: 0
Sub shell level: 1

Done.

這就是為什么函數中的任何變量賦值都不會傳遞回調用腳本的原因。

暫無
暫無

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

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