## while循環陷阱
### 案例1
在寫while循環的時候,發現了一個問題,在while循環內部對變量賦值、定義變量、數組定義等等在循環外面會失效,失效案例如下。
```
#!/bin/bash
echo "abc xyz" | while read line
do
new_var=$line
done
echo new_var is null: $new_var?
```
原因,這使得while語句在子Shell中執行,意味著while語句內部設置的變量、數組、函數等在循環外部都不再生效。以下為解決方案。
```
#!/bin/bash
while read line
do
new_var=$line
done <<< "abc xyz"
echo new_var is null: $new_var?
```
"<<<" 以這種方式直接在命令之前分配的變量僅對命令進程生效。
案例來源:[https://www.cnblogs.com/f-ck-need-u/p/7431578.html](https://www.cnblogs.com/f-ck-need-u/p/7431578.html)
### 案例2
今天在一些機器上批量執行命令,將10多個IP追加到指定文件中(ip)通過以下Shell方式來批量執行。
```
#!/bin/bash
while read line
do
ssh $line "command"
done < ip
```
奇怪的是每次執行1行就退出。 網上google以下原因,while read 會從標準輸入讀取1行數據賦值給line變量,在while中循環嵌套ssh,ssh命令就會截取所有標準輸入的數據這就導致read再次讀數據時數據已經被ssh讀取,line變量獲取為空值最終導致循環結束。
解決方式:
* 方案1:ssh -n ,其中-n參數含義如下:
-n 把 stdin 重定向到 /dev/null \(實際上防止從 stdin 讀取數據\). 在后臺運行時一定會用到這個選項. 它的常用技巧是遠程運行 X11 程序. 例如, ssh -n shadows.cs.hut.fi emacs 將會在 shadows.cs.hut.fi 上啟動 emacs, 同時自動在加密通道中轉發 X11 連接. 在后臺運行. \(但是如果 要求口令或密語, 這種方式就無法工作; 參見 -f 選項.\)
* 方案2:ssh "command" < /dev/null
* 方案3:或者循環時使用for
案例來源:[http://blog.puppeter.com/read.php?65](http://blog.puppeter.com/read.php?65)
- Introduction
- 1.Shell編程基礎
- 什么是Shell
- 編寫第一個Bash程序
- 2.變量
- 什么是變量
- 變量四種賦值方式
- 指定變量類型
- 變量的類型
- 特殊變量
- 3.Bash符號相關
- Bash符號相關
- 特殊符號
- 數學運算符號
- 4.內建命令與外部命令
- 內建命令與外部命令
- 5.read命令
- read命令
- 6.條件語句
- if..then..fi
- if..then..else..fi
- if..then..elif..fi
- 空命令
- 文件測試符
- 字符串判斷、與、或和非
- []與[[]]符號
- 7.Bash循環 && 分支語句
- while循環語句
- for循環
- for..in循環
- until循環
- select循環
- case分支語句
- 8.正則表達式
- 正則表達式
- 9.子Shell和受限Shell
- 子Shell
- 受限Shell
- 10.函數與函數的加載
- 函數語法與案例
- 遞歸函數
- 函數的加載
- 11.Bash腳本風格
- Bash腳本風格
- 12.Bash腳本調試
- Bash腳本調試
- 13.sed && awk
- sed
- 14.awk
- awk
- 15 Bash雜項 && 案例
- while循環的陷阱
- Bash的生命周期
- IO重定向
- /bin/bash和/bin/sh區別
- 命令雜項
- Shell加密
- 16.10.2.案例
- Bash版回收站
- 17.Bash中文速查表
- 中文速查表