亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在while循環中修改的變量不會被記住。

在while循環中修改的變量不會被記住。

在while循環中修改的變量不會被記住。在下面的程序中,如果我設置了變量$foo中的值1。if語句,它的工作原理是在if語句之后記住它的值。但是,當我將相同的變量設置為if在一個while語句之后,它就被遺忘了。while循環。它的行為就像我在使用變量的某種拷貝$foo內部while循環和我只是在修改特定的副本。下面是一個完整的測試程序:#!/bin/bashset -eset -u foo=0bar="hello"  if [[ "$bar" == "hello" ]]then    foo=1    echo "Setting \$foo to 1: $foo"fiecho "Variable \$foo after if statement: $foo"   lines="first line\nsecond line\nthird line" echo -e $lines | while read linedo    if [[ "$line" == "second line" ]]    then    foo=2    echo "Variable \$foo updated to $foo inside if inside while loop"    fi    echo "Value of \$foo in while loop body: $foo"doneecho "Variable \$foo after while loop: $foo"# Output:# $ ./testbash.sh# Setting $foo to 1: 1# Variable $foo after if statement: 1# Value of $foo in while loop body: 1# Variable $foo updated to 2 inside if inside while loop# Value of $foo in while loop body: 2# Value of $foo in while loop body: 2# Variable $foo after while loop: 1# bash --version# GNU bash, version 4.1.10(4)-release (i686-pc-cygwin)
查看完整描述

3 回答

?
慕桂英3389331

TA貢獻2036條經驗 獲得超8個贊

echo?-e?$lines?|?while?read?line?
????...done

這個while循環在子shell中執行。因此,一旦子shell退出,您對變量所做的任何更改都將不可用。

相反,您可以使用這里串在主外殼進程中重寫while循環;僅echo -e $lines將在子shell中運行:

while?read?linedo
????if?[[?"$line"?==?"second?line"?]]
????then
????????foo=2
????????echo?"Variable?\$foo?updated?to?$foo?inside?if?inside?while?loop"
????fi
????echo?"Value?of?\$foo?in?while?loop?body:?$foo"done?<<<?"$(echo?-e?"$lines")"

你可以擺脫那些相當丑陋的人echo在上述字符串中,在賦值時立即展開反斜杠序列。lines。這個$'...'引用的形式可以在這里使用:

lines=$'first?line\nsecond?line\nthird?line'while?read?line;?do
????...done?<<<?"$lines"


查看完整回答
反對 回復 2019-05-30
?
繁花如伊

TA貢獻2012條經驗 獲得超12個贊

備選解決辦法:

消去echo

while?read?line;?do...done?<<EOT
first?line
second?line
third?line
EOT

在“這里是文檔”中添加回顯。

while?read?line;?do...done?<<EOT
$(echo?-e?$lines)EOT

echo背景:

coproc?echo?-e?$lineswhile?read?-u?${COPROC[0]}?line;?do?...done

顯式地重定向到文件句柄(請注意< <!):

exec?3<?<(echo?-e??$lines)while?read?-u?3?line;?do...done

或者重定向到stdin:

while?read?line;?do...done?<?<(echo?-e??$lines)

一張是給你的chepner(消除echo):

arr=("first?line"?"second?line"?"third?line");for((i=0;i<${#arr[*]};++i))?{?line=${arr[i]};?...}

變量$lines可以在不啟動新的子shell的情況下轉換為數組。人物\n必須轉換為某個字符(例如,一個真正的新行字符),并使用IFS(內部字段分隔符)變量將字符串拆分為數組元素??梢赃@樣做:

lines="first?line\nsecond?line\nthird?line"echo?"$lines"OIFS="$IFS"IFS=$'\n'?arr=(${lines//\\n/$'\n'})
?#?ConversionIFS="$OIFS"echo?"${arr[@]}",?Length:?${#arr[*]}set|grep?^arr

結果是

first?line\nsecond?line\nthird?line
first?line?second?line?third?line,?Length:?3arr=([0]="first?line"?[1]="second?line"?[2]="third?line")


查看完整回答
反對 回復 2019-05-30
?
慕絲7291255

TA貢獻1859條經驗 獲得超6個贊

描述了管道創建的子shell中設置的變量的一般情況:

E4)如果我將命令的輸出輸送到read variable,為什么輸出沒有出現在$variable讀取命令何時結束?

這與Unix進程之間的父-子關系有關。它影響在管道中運行的所有命令,而不僅僅是對read。例如,將命令的輸出轉換為while循環,反復調用read會導致同樣的行為。

管道的每個元素,甚至是內置或shell函數,都運行在單獨的進程中,即運行管道的shell的子進程中。子進程不能影響其父進程的環境。當read命令將變量設置為輸入,該變量僅在子shell中設置,而不是在父shell中設置。當子shell退出時,變量的值將丟失。

許多以read variable可以轉換為命令替換,這將捕獲指定命令的輸出。然后,可以將輸出分配給一個變量:

grep?^gnu?/usr/lib/news/active?|?wc?-l?|?read?ngroup

可以轉換成

ngroup=$(grep?^gnu?/usr/lib/news/active?|?wc?-l)

不幸的是,這并不能將文本拆分到多個變量中,就像給出多個變量參數時的Read一樣。如果需要這樣做,可以使用上面的命令替換將輸出讀入變量并使用bash模式刪除擴展操作符分割變量,或者使用以下方法的一些變體。

例如/usr/local/bin/ipaddr是以下shell腳本:

#!?/bin/shhost?`hostname`?|?awk?'/address/?{print?$NF}'

而不是使用

/usr/local/bin/ipaddr?|?read?A?B?C?D

若要將本地機器的IP地址分解為單獨的八進制,請使用

OIFS="$IFS"IFS=.set?--?$(/usr/local/bin/ipaddr)IFS="$OIFS"A="$1"?B="$2"?C="$3"?D="$4"

但是,請注意,這將改變shell的位置參數。如果你需要它們,你應該在做這件事之前先保存它們。

這是一般的方法-在大多數情況下,您不需要將$IFS設置為不同的值。

其他一些用戶提供的替代方案包括:

read?A?B?C?D?<<?HERE
????$(IFS=.;?echo?$(/usr/local/bin/ipaddr))HERE

如果過程替換可用,

read?A?B?C?D?<?<(IFS=.;?echo?$(/usr/local/bin/ipaddr))


查看完整回答
反對 回復 2019-05-30
  • 3 回答
  • 0 關注
  • 1774 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號