![](/img/trans.png)
[英]change a counter according to a output function in a while loop - in bash
[英]Sending the output of a while loop to a bash function
我創建了一個.bashrc文件,其中有兩個功能。 一個在while循環中循環遍歷文件的每一行。 我試圖保存行的內容(如果它們符合特定條件),然后將所有三個匹配項傳遞給第二個函數,然后將它們回顯。 但是,我嘗試了導出變量,還嘗試了管道傳遞給第二個函數,但均無效。 當我嘗試在代碼示例中進行說明時,管道的行為也很奇怪。
readAndPipe() {
while read -r line || [[ -n "$line" ]]; do
(
if [[ $line == FIRSTNAME=BOB ]]; then
echo $line;
fi;
if [[ $line == LASTNAME=SMITH ]]; then
echo $line;
fi;
if [[ $line == BIRTHMONTH=AUGUST ]]; then
echo $line;
fi;
); done < "file.txt" | printArguments $1 #pass the original command line argument;
}
printArguments() {
#This is where the weirdness happens
echo $@ #Prints: only the original command line argument
echo $# #Prints: 1
echo $2 $3 $4 #Prints nothing
varName=$(cat $2 $3 $4)
echo $varName #Prints: FIRSTNAME=BOB
# LASTNAME=SMITH
# BIRTHMONTH=AUGUST
cat $2 $3 $4 #Prints nothing
echo $(cat $2 $3 $4) #Prints nothing
cat $2 $3 $4 | tr "\n" '' #Prints tr: empty string2
}
顯然我不是bash專家,所以我確定這里有很多錯誤,但是我想知道的是
$@
, $*
, $1
, $2
等是傳遞給函數的參數 。 例如,在myfunc foo bar baz
,我們有$ 1 == foo,$ 2 == bar和$ 3 == baz。
將數據通過管道傳輸到函數時,必須從stdin中檢索數據:
myfunc() {
data=$(cat)
echo "I received: >$data<"
}
for n in {1..5}; do echo "x=$n"; done | myfunc
產生
I received: >x=1
x=2
x=3
x=4
x=5<
varName=$(cat $2 $3 $4)
之所以有效,是因為$ 2 $ 3和$ 4 為空 ,所以外殼程序會看到:
varName=$(cat )
cat“只能工作一次”的原因是因為您正在消費流。 一旦消耗掉,它就消失了。 “你不能吃蛋糕也不能吃。”
printArguments
函數可以使用readarray
命令將傳入的行捕獲到數組中,而不是使用cat
來將所有傳入的文本捕獲到變量中:
printArguments() {
readarray -t lines
echo "I have ${#lines[@]} lines"
echo "they are:"
printf ">>%s\n" "${lines[@]}"
}
{ echo foo; echo bar; echo baz; } | printArguments
輸出
I have 3 lines
they are:
>>foo
>>bar
>>baz
在交互式bash提示符下鍵入help readarray
了解更多信息。
想象一個腳本:
func() {
echo $# # will print 2, func were executed with 2 arguments
echo "$@" # will print `arg1 arg2`, ie. the function arguments
in=$(cat) # will pass stdin to `cat` function and save cat's stdout into a variable
echo "$in" # will print `1 2 3`
}
echo 1 2 3 | func arg1 arg2
# ^^^^^^ function `func` arguments
# ^ passed one command stdout to other command stdin
# ^^^ outputs `1 2 3` on process stdout
cat
調用,讀取stdin
並將其輸出到stdout
。 in=$(cat)
將讀取標准輸入,因為普通的cat
只會將輸出(即cat
的標准輸出)保存到變量中) 對您的腳本:
readAndPipe() {
# the while read line does not matter, but it outputs something on stdout
while read -r line || [[ -n "$line" ]]; do
echo print something
# the content of `file.txt` is passed as while read input
done < "file.txt" | printArguments $1 # the `print something` (the while loop stdout output) is passed as stdin to the printArguments function
}
printArguments() {
# here $# is equal to 1
# $1 is equal to passed $1 (unless expanded, will get to that)
# $2 $3 $4 expand to nothing
varName=$(cat $2 $3 $4) # this executes varName=$(cat) as $2 $3 $4 expand to nothing
# now after this point stdin has been read (it can be read once, it's a stream or pipe
# is you execute `cat` again it will block (waiting for more input) or fail (will receive EOF - end of file)
echo $varName #Prints: `print something` as it was passed on stdin to this function
}
如果文件file.txt
僅包含:
FIRSTNAME=BOB
LASTNAME=SMITH
BIRTHMONTH=AUGUST
您可以只加載文件. file.txt
. file.txt
或source file.txt
。 這將“加載”文件,即。 使其成為腳本的一部分,語法就是bash。 所以你可以:
. file.txt
echo "$FIRSTNAME"
echo "$LASTNAME"
echo "$BIRTHMONTH"
這是在/ etc /中創建配置文件的常用方法,然后由腳本加載它們。 這就是為什么在許多/ etc /文件中,注釋以#
開頭的原因。
筆記:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.