[英]How to pipe input to a Bash while loop and preserve variables after loop ends
Bash 允許使用: cat <(echo "$FILECONTENT")
Bash 也允許使用: while read i; do echo $i; done </etc/passwd
while read i; do echo $i; done </etc/passwd
結合前兩個可以使用: echo $FILECONTENT | while read i; do echo $i; done
echo $FILECONTENT | while read i; do echo $i; done
最后一個的問題是它創建了子shell,並且在while循環結束后變量i
不能再訪問了。
我的問題是:
如何實現這樣的事情: while read i; do echo $i; done <(echo "$FILECONTENT")
while read i; do echo $i; done <(echo "$FILECONTENT")
while read i; do echo $i; done <(echo "$FILECONTENT")
或換句話說:我如何確定i
在 while 循環中存活?
請注意,我知道將 while 語句包含在{}
中,但這並不能解決問題(假設您想在 function 中使用 while 循環並返回i
變量)
進程替換的正確符號是:
while read i; do echo $i; done < <(echo "$FILECONTENT")
當循環終止時,循環中分配的最后一個i
值可用。 另一種選擇是:
echo $FILECONTENT |
{
while read i; do echo $i; done
...do other things using $i here...
}
大括號是 I/O 分組操作,本身不會創建子 shell。 在這種情況下,它們是管道的一部分,因此作為子 shell 運行,但這是因為|
,而不是{ ... }
。 你在問題中提到了這一點。 AFAIK,您可以在函數內部從這些內部返回。
Bash 還提供了shopt
內置函數,其眾多選項之一是:
lastpipe
如果設置,並且作業控制未處於活動狀態,shell 將運行當前 shell 環境中未在后台執行的管道的最后一個命令。
因此,在腳本中使用類似的東西可以在循環后使用修改后的sum
:
FILECONTENT="12 Name
13 Number
14 Information"
shopt -s lastpipe # Comment this out to see the alternative behaviour
sum=0
echo "$FILECONTENT" |
while read number name; do ((sum+=$number)); done
echo $sum
在命令行執行此操作通常會違反“作業控制未激活”(即,在命令行中,作業控制處於活動狀態)。 在不使用腳本的情況下測試失敗。
此外,正如Gareth Rees在他的回答中所指出的,您有時可以使用here 字符串:
while read i; do echo $i; done <<< "$FILECONTENT"
這不需要shopt
; 您可以使用它來保存進程。
Jonathan Leffler 解釋了如何使用流程替換來做您想做的事情,但另一種可能性是使用here 字符串:
while read i; do echo "$i"; done <<<"$FILECONTENT"
這節省了一個過程。
此功能使 jpg 文件重復 $NUM 次(bash)
function makeDups() {
NUM=$1
echo "Making $1 duplicates for $(ls -1 *.jpg|wc -l) files"
ls -1 *.jpg|sort|while read f
do
COUNT=0
while [ "$COUNT" -le "$NUM" ]
do
cp $f ${f//sm/${COUNT}sm}
((COUNT++))
done
done
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.