在bash編程中,我目前面臨的一個問題是,我不僅想要在bash函數中修改全局變量,還要通過return
和$?
返回適當的返回代碼,並且能夠分配所有在出現期間出現的stdout
輸出函數調用函數外的變量。如何在捕獲標準輸出的同時修改bash函數中的全局變量並返回有效的返回碼?
雖然這些單獨的任務(修改全局var,返回狀態碼,將stdout分配給變量)似乎完全可能在bash中(甚至是這些願望中的兩個的組合),所有這三個需求的組合幾乎不可能(即只是不方便)。
下面是一個例子腳本我已經準備演示此問題:
#!/bin/bash
#
# This is the required output:
#
# -- cut here --
# RETURN: '2'
# OUTPUT: 'Hello World!'
# GLOBAL_VAR: '3'
# -- cut here --
#
GLOBAL_VAR=0
hello() {
echo "Hello World!"
GLOBAL_VAR=3
return 2
}
# (1) normal bash command substition (subshell)
# PROBLEM: GLOBAL_VAR is 0 but should be 3
# (hello is executed in subshell)
#
output=$(hello) ; result=$?
# (2) use 'read' and a reverse pipe
# PROBLEM: RETURN and GLOBAL_VAR is 0
# (hello in subshell and read return
# code returned)
#
#read output < <(hello) ; result=$?
# (3) normal function execution
# PROBLEM: no catched output!
#
#hello ; result=$?
# (4) using lastpipe + read
# PROBLEM: GLOBAL_VAR is 0 but should be 3
# (a pipe generateѕ a subshell?!?!)
#
#shopt -s lastpipe
#hello | read output ; result=${PIPESTATUS[0]}
# (5) ksh-like command substiution
# PROBLEM: Works, but ksh-syntax
# -> doesn't work in bash!
#
#output=${ hello; } ; result=$?
# (6) using a temp file to catch output of hello()
# WORKS, but ugly due to tmpfile and 2xsubshell use!
#
#tmp=$(mktemp)
#hello >${tmp} ; result=$?
#output=$(cat ${tmp})
#rm -f ${tmp}
###################################
# OUTPUT stuff
# this should output "2"
echo "RESULT: '${result}'"
# this should output "Hello World!"
echo "OUTPUT: '$output'"
# this should output "3"
echo "GLOBAL_VAR: '$GLOBAL_VAR'"
在這個腳本中我添加了一個函數hello()
它應該返回2的狀態代碼,設置全局變量GLOBAL_VAR
至3和輸出「Hello World!」到stdout
。 除了這個功能外,我還增加了6個潛在的解決方案來調用這個hello()
函數來實現我需要的輸出(它顯示在bash腳本代碼的頂部)。
通過在這6種不同的調用函數的方式中進行註釋,您將看到只有解決方案(6)才能滿足調用該函數的所有要求。
特別有趣的是,解決方案編號(5)顯示了ksh-syntax,它的工作原理與我需要此功能的工作方式完全相同。因此,使用ksh
調用此腳本將輸出具有所需值的所有變量。當然,這個解決方案(使用${ cmd; }
的命令替換)在bash中不受支持。然而,我肯定需要一個bash解決方案作爲主要腳本,我需要我的解決方案是一個僅限bash的腳本,我無法移植到ksh。
當然,解決方案(6)也符合我的要求,它需要將hello()
的輸出放在一個臨時文件中,然後再讀取它。在性能方面(需要幾個子shell,臨時文件管理),這對我來說不是真正的解決方案。
所以現在問題出現了,如果在bash中有其他任何潛在的解決方案滿足我的要求,以便上面的腳本完全符合我的要求,因此結合了我所有的三個要求?!?
我會使用解決方案#6 –
如果#6中的性能問題是一個實際問題,'bash'可能不是該程序的正確語言。 – chepner
我認爲你應該重新設計解決方案,而不需要將該函數設置爲全局變量。 – hek2mgl