2015-11-07 25 views
0

我試着問人們哪些接口用作iptables上的公共接口: while循環接縫不記住變量,我真的不知道爲什麼。在while循環中不記住修改變量

#!/bin/sh 
### Show all available interfaces and configure to use them in while-loop: 
# Here is the answer of the function: 
# "${PUB_IF}" != "eth0" -a "${PUB_IF}" != "eth1" -a "${PUB_IF}" != "vmbr0" 
function good_interfaces() { 
ip a | grep '^[0-9]:' | grep -v 'lo' | awk '{ print $2 }' | sed -e 's/^/"/' -e 's/:$/"/' -e '/$/ i\-a "${PUB_IF}" !=' | sed '$!N; s/\n/ /g' | tr '\n' ' ' | awk 'sub("^...", "")' 
} 

### Show available interfaces 
# Here is the answer of "echo ${IF_LIST}" 
# eth0? eth1? vmbr0? 
IF_LIST=$(ip a | grep '^[0-9]:' | grep -v 'lo' | awk '{ print $2 }' | sed 's/:/\?/g' | tr '\n' ' ') 

while [ $(good_interfaces) ]; do 
# When i replace $(good_interfaces) by its answer, the loop works: 
# while [ "${PUB_IF}" != "eth0" -a "${PUB_IF}" != "eth1" -a "${PUB_IF}" != "vmbr0" ] --> without the variable it works but isn't personalized for all machines 
    echo "${IF_LIST}" 
    read -p "Enter the interface to use: " PUB_IF 
done; 

這裏是ip a答案:在你的代碼

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 
    inet 127.0.0.1/8 scope host lo 
     valid_lft forever preferred_lft forever 
    inet6 ::1/128 scope host 
     valid_lft forever preferred_lft forever 
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master vmbr0 state UP group default qlen 1000 
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff 
    inet x.x.x.x/x brd x.x.x.x scope global eth0 
     valid_lft forever preferred_lft forever 
3: eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000 
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff 
+2

請參閱http://stackoverflow.com/help/mcve – Jubobs

+0

序列'grep ... | grep -v ... | awk ... | sed ...'應該是單個命令 - 可能是'awk',但是現在你可以使用'sed'或'grep'來代替。無論如何,連續的四個命令都不需要。即使沒有這些,你也可以把序列放到一個函數中,這樣你就不必重複自己。這會讓我們有機會理解你的問題。我假設'未設置的PIB_IF'在原始代碼中不存在。如果是,'-z「$ {PUB_IF}」'測試是多餘的 - 它是未設置的,因此總是計爲零長度。 –

+0

在循環後不記住的循環中設置變量的正常原因是循環在子外殼中運行。這並不是顯而易見的問題。你可以在'ip a'中顯示三行或四行輸出 - 一個用於'lo'界面,至少另外兩個輸出,這樣我們那些沒有在他們機器上使用'ip'命令的人可以看到你正在處理的數據是什麼樣子的喜歡? –

回答

0

首先,一些評論:

  • #!/bin/sh
    拆卸空間上的這條線(和使用bash)。目前該行只評
  • ip a | grep '^[0-9]:' | grep -v 'lo' | a lot more
    對不起,該命令是越來越複雜的。當你看不到輸入時,你認爲你可以在兩個月內自己理解嗎?
  • IF_LIST=$(ip a | grep '^[0-9]:' | grep -v 'lo' | and more)
    一些代碼與功能共享good_interfaces
  • while [ $(good_interfaces) ]; do
    while循環想要一個真/假的表情,你希望你的函數返回的字符串將被視爲一個表達。

那麼應該如何實現一個讀取PUB_IF的構造並在有效時打破?

把所有有效的接口放在一個帶清晰分隔符的字符串中(我將使用空格)。 我會在字符串前後添加一個空格,以便稍後進行匹配。
要求PUB_IF並檢查。

valid_interfaces=" eth0 eth1 vmbr0 " 
PUB_IF="" 
# Edit: changed "while [ true ]; do" into "while true; do" 
while true; do 
    read -p "Enter the interface to use: " PUB_IF 
    if [[ "${valid_interfaces}" = *;${PUB_IF};* ]]; then 
     echo "${PUB_IF} is valid" 
     break 
    else 
     echo "Nope, please enter something like${valid_interfaces}" 
    fi 
done 

的另一個問題是如何找到有效的接口。使用剪切:

valid_interfaces=" $(ip a | grep ": <" | grep -v "lo" | cut -d: -f2 | tr '\n' ' ') 
+0

你想'而真實;做'而不是'而[true]; do'。即使它們在功能上等價,「[true]」也是如此,因爲括號中的字符串不是空的,也不是因爲它正在運行'true'命令。 –

+0

@Glenn謝謝,真的。即使「虛假」是真的。 –

+0

@沃爾特謝謝!你是對的,我真的不知道我只關注那種方法。你的很容易! 因此,在一個while循環中放置一個函數是不可能的,因爲雖然它不會將其看作一個表達式?沒有什麼能解決這個「問題」? 我試過你是代碼和部件'if [[「$ {valid_interfaces}」= *; $ {PUB_IF}; *]];那麼'在我的機器上不起作用。結果如下:'sh test; 輸入使用界面:eth test:6:test:[[:未找到 測試:6:測試:eth:未找到 eth有效' – h3rx9m