Linux學習心得:細細品味shell指令碼中的細節與使用者體驗 ^_^

來源:互聯網
上載者:User

        學習Linux已經有一周半了,在馬哥的強壓下,寫了二十幾個shell指令碼。。。shellRegex,awk語句,程式執行流,test語句,sed語句,函數還有一些其他的小命令,如tr,grep,cut,wc等等。越發覺得shell指令碼的可愛,沒錯,是可愛!因為它的快速上手,迷人的Regex,變換莫測的程式執行流和awk語句,還有強大的功能,很難想象這麼簡單的語言和linux如此完美的結合在一起,好像是linux的可愛的“妻子”。

        聽馬哥說,中國的程式員並不是不如印度,國際上很多編程大賽,中國程式員都拿獎,但是軟體外包卻不如印度。並不是他們編的程式好,而是中國的程式員編程有點“豆腐渣程——只把要求實現的功能都實現了,其他的不管了。。。同樣是一個小程式,印度人可能寫幾百行,上前行,而中國人唯寫幾十行。。並不是人家不能寫那麼短,而是為了“使用者體驗”。

        廢話不說了,切入正題。

###########################

shell指令碼中的細節:

首先是變數的運用:有時候我們不得不多次輸入一個路徑,這個時候我們就可以把路徑定義成變數,例如:FILE=/etc/passwd,在使用時用$FILE引用即可。這個技巧很好用,但是當一個指令碼有多個路徑或多個變數的時候,變數的名字會容易記混,或者打錯。所以,在我看來變數的使用原則如下:

1. 盡量避免引用過多的變數,不能貪多,否則整個指令碼充滿了變數,反而不易讀懂。

2. 變數是用來使整個指令碼變的方便的,所有應該是出現多次的參數才需要變數來引用。

3. 變數的名字應該易讀,易記,易輸入,盡量避免過於相似的變數。

4. 有些時候,變數需要在一個指令碼中被多次重新賦值,但要注意使用,否則容易出錯。

 

所有的語句都需要精簡嗎?

以前我一直認為,代碼要短越好,這樣執行效率會更高,但是現在有一個問題,再好的代碼,如果容易“崩潰”的話,再精簡有什麼用?有些時候,不得不在完成程式功能的基礎上考慮程式的可用性。比如當使用者輸入錯誤怎麼辦,使用者中突退出怎麼辦,使用者輸入的資料怎麼是否需要驗證。比如,你一個不懂網路知識的人誤將IP地址和GATEWAY設為不同的網段,那麼這個操作就會造成無法接入互連網。舉個例子

寫一個指令碼:
1、提示使用者選擇所要設定的網卡;
2、提示使用者使用dhcp或者static作為選定網卡的BOOTPROTO
  a、如果使用者選擇dhcp,則將其設定檔中的BOOTPROTO的值設為dhcp,而後重啟此網卡;
  b、如果使用者選擇static,則將其設定檔中的BOOTPROTO的值設為static,並提示使用者輸入IP地址,子網路遮罩和網關;其中網關可以為空白,但IP地址或子網路遮罩不可為空;設定完成後重啟此網卡;
3、無論上述動態或靜態設定,設定完成後將網卡IP地址設定後資訊再次顯示給使用者;

 

我們來分析:這個程式的功能其實很簡單,只要求能夠識別使用者的輸入資訊是dhcp還是static,然後進行相應的設定,但是我來考慮:

 

考慮:1、如果使用者沒有做出任何修改之前就不想設定了,如何退出?
            2、如果使用者已經設定了一些資訊,如IP地址等卻又不想設定了,而使用了Ctrl+c,如何處置?

            3、如果使用者輸入的是錯誤的IP資訊怎麼辦?

            4、如果使用者輸入的是錯誤的NETMASK怎麼辦?

            5、如果使用者輸入的是不匹配的IP和GATEWAY怎麼辦?

            6、如果使用者輸入的資訊已經存在怎麼辦?

            7、使用者輸入的網卡是否存在?

            8、萬一網卡重啟發生錯誤怎麼辦?

整個代碼如下

#!/bin/bash#建立臨時檔案和標識FLAG=0TMPFILE=`mktemp /tmp/eth.XXXXXXXX`#讀取使用者輸入read -p "Interface: " ETHCARD#判定使用者輸入的網卡是否存在ALLECARD=`ifconfig -a | awk '/^[^[:space:]l]/{print $1}'`until echo $ALLECARD | grep "$ETHCARD" &> /dev/null; do  echo -e "\033[31mWrong Card name.\033[0m"  read -p "Interface: " ETHCARDdone#網卡路徑的變數,以後要多次應用ETHFILE=/etc/sysconfig/network-scripts/ifcfg-$ETHCARD#判定使用者輸入的協議是否正確read -p "Boot Protocol: " MYBOOTPROTOuntil echo $MYBOOTPROTO | grep -E "dhcp|static" &> /dev/null ; do  echo -e "\033[31mWrong BOOTPROTO.\033[0m"  read -p "Boot Protocol: " MYBOOTPROTOdone#判定DHCP和staticif [ "$MYBOOTPROTO" == "dhcp" ]; then  sed -i "s/^BOOTPROTO=.*/BOOTPROTO=dhcp/g" $ETHFILE  if [ $? -eq 0 ]; then    ifdown $ETHCARD && ifup $ETHCARD    [ $? -eq 0 ] && echo "Set $ETHCARD done."  fielif [ "$MYBOOTPROTO" == "static" ]; then  cat $ETHFILE > $TMPFILE  read -p "Ip Address: " MYIP#判定IP的正確性  until [[ $MYIP =~   ^([1-9]|[1-9][0-9]|1[0-9]{1,2}|2[01][0-9]|22[0-3])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])){2}(\.([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4]))$ ]];do    echo -e "\033[31mWrong IP.\033[0m"    read -p "Ip Address: " MYIP  done#判定NETMASK的正確性    read -p "Netmask: " MYNM    until [[ $MYNM =~ ^255(\.(0|255)){3}$ ]]; do    echo -e "\033[31mWrong NetMask.\033[0m"    read -p "Netmask: " MYNM  done    read -p "Gateway: " MYGW#判定IP與GATEWAY的匹配  for I in {1..4}; do    [ $[`echo $MYIP | cut -d. -f $I`&`echo $MYNM | cut -d. -f $I`] -ne $[`echo $MYGW | cut -d. -f $I`&`echo $MYNM | cut -d. -f $I`] ] && FLAG=1 && break  done  until [[ $MYGW =~   ^([1-9]|[1-9][0-9]|1[0-9]{1,2}|2[01][0-9]|22[0-3])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])){2}(\.([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4]))$ ]] && [ $FLAG -eq 0 ];do    echo -e "\033[31mWrong GateWay.\033[0m"    read -p "Gateway: " MYGW    for I in {1..4}; do      [ $[`echo $MYIP | cut -d. -f $I`&`echo $MYNM | cut -d. -f $I`] -ne $[`echo $MYGW | cut -d. -f $I`&`echo $MYNM | cut -d. -f $I`] ] && FLAG=1 && break || FLAG=0    done  done#檔案裡資訊是否存在,調用臨時檔案  sed -i "s/^BOOTPROTO=.*/BOOTPROTO=static/g" $TMPFILE  grep "^IPADDR=" $TMPFILE &> /dev/null  && sed -i "s/IPADDR=.*/IPADDR=$MYIP/" $TMPFILE || echo "IPADDR=$MYIP" >> $TMPFILE  grep "^NETMASK=" $TMPFILE &> /dev/null && sed -i "s/NETMASK=.*/NETMASK=$MYNM/" $TMPFILE || echo "NETMASK=$MYNM" >> $TMPFILE  if [ -z $MYGW ]; then     sed -i '/^GATEWAY=.*/d' $TMPFILE  else     grep "^GATEWAY=" $TMPFILE &> /dev/null && sed -i "s/GATEWAY=.*/GATEWAY=$MYGW/" $TMPFILE || echo "GATEWAY=$MYGW" >> $TMPFILE  fi  cp -f $TMPFILE $ETHFILE  ifdown $ETHCARD && ifup $ETHCARD  [ $? -eq 0 ] && echo "Set $ETHCARD done."else   echo "No such options."  exit 1fi#刪除臨時檔案,避免臨時檔案過多   rm -f $TMPFILE

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.