內部變數的學習

來源:互聯網
上載者:User

內部變數的學習 內建變數,這些變數將會影響bash指令碼的行為.$BASH Bash的二進位程式檔案的路徑root@ubuntu:~/resource/shell-study/0506-2013# echo $BASH  /bin/bash  $BASH_ENV這個環境變數會指向一個Bash的開機檔案, 當一個指令碼被調用的時候, 這個開機檔案將會被讀取. $BASH_SUBSHELL這個變數用來提示子shell的層次. 這是一個Bash的新特性, 直到版本3的Bash才被引入近來. $BASH_VERSINFO[n]這是一個含有6個元素的數組, 它包含了所安裝的Bash的版本資訊. 這與下邊的$BASH_VERSION很相像, 但是這個更加詳細一些.root@ubuntu:~/resource/shell-study/0506-2013# for n in 0 1 2 3 4 5  > do   > echo "BASH_VERSINFO[$n] = ${BASH_VERSINFO[$n]}"  > done  BASH_VERSINFO[0] = 4  BASH_VERSINFO[1] = 1  BASH_VERSINFO[2] = 5  BASH_VERSINFO[3] = 1  BASH_VERSINFO[4] = release  BASH_VERSINFO[5] = i486-pc-linux-gnu  $BASH_VERSION安裝在系統上的Bash版本號碼root@ubuntu:~/resource/shell-study/0506-2013# echo $BASH_VERSION  4.1.5(1)-release  這個輸出的資訊和上面通過數組查詢到的資訊是一一對應的$DIRSTACK在目錄棧中最頂端的值. (將會受到pushd和popd的影響),這個內建變數與dirs命令相符, 但是dirs命令會顯示目錄棧的整個內容. $EDITOR指令碼所調用的預設編輯器, 通常情況下是vi或者是emacs. $EUID"有效"使用者ID,不管目前使用者被假定成什麼使用者, 這個數都用來表示目前使用者的標識號, 也可能使用su命令來達到假定的目的.,$EUID並不一定與$UID相同. $FUNCNAME(當前函數的名字)#!/bin/bash    func ()  {      echo "$FUNCNAME is running."  }  func  echo "FUNCNAME = $FUNCNAME"    exit 0  結果:root@ubuntu:~/resource/shell-study/0506-2013# ./test7.sh   func is running.  FUNCNAME =   root@ubuntu:~/resource/shell-study/0506-2013#   第二行沒有name,因為FUNCNAME只能用在函數方法內部使用$GLOBIGNORE一個檔案名稱的模式比對列表, 如果在通配(globbing)中匹配到的檔案包含有這個列表中的某個檔案, 那麼這個檔案將被從匹配到的結果中去掉. $GROUPS目前使用者所屬的組,這是一個目前使用者的組id列表(數組), 與記錄在/etc/passwd檔案中的內容一樣 $HOME使用者的home目錄, 一般是/home/usernam $HOSTNAMEhostname放在一個初始化指令碼中, 在系統啟動的時候分配一個系統名字. 然而, gethostname()函數可以用來設定這個Bash內部變數$HOSTNAME $HOSTTYPE主控件類型,就像$MACHTYPE, 用來識別系統硬體. root@ubuntu:~/resource/shell-study/0506-2013# echo $HOSTNAME  ubuntu  root@ubuntu:~/resource/shell-study/0506-2013# echo $HOSTTYPE  i486  root@ubuntu:~/resource/shell-study/0506-2013# echo $HOME  /root  root@ubuntu:~/resource/shell-study/0506-2013# echo $GROUPS  0  root@ubuntu:~/resource/shell-study/0506-2013#   $IFS內部域分隔字元,這個變數用來決定Bash在解釋字串時如何識別域, 或者單詞邊界.$IFS預設為空白(空格, 定位字元,和分行符號), 但這是可以修改的, 比如, 在分析逗號分隔的資料檔案時, 就可以設定為逗號. 注意$*使用的是儲存在$IFS中的第一個字元#!/bin/bash    output_args_one_per_line()  {      for arg      do echo "[$arg]"      done  }    echo "IFS=\" \""  IFS=" "  var=" a  b c   "  output_args_one_per_line $var    echo "----------------"  echo "IFS=:"  IFS=":"  var=":a::b:c:::"  output_args_one_per_line $var    exit 0  結果:root@ubuntu:~/resource/shell-study/0506-2013# ./test8.sh   IFS=" "  [a]  [b]  [c]  ----------------  IFS=:  []  [a]  []  [b]  [c]  []  []  root@ubuntu:~/resource/shell-study/0506-2013#   可以看出還是挺奇怪的,當使用IFS=" "和使用“:”時,結果還是有些出入的,同樣的事情也會發生在awk的"FS"域中.$IGNOREEOF忽略EOF: 告訴shell在log out之前要忽略多少檔案結束符(control-D). $LC_COLLATE常在.bashrc或/etc/profile中設定, 這個變數用來控制檔案名稱擴充和模式比對的展開順序. 如果$LC_COLLATE設定得不正確的話, LC_COLLATE會在檔案名稱匹配(filename globbing)中產生不可預料的結果. $LC_CTYPE這個內部變數用來控制通配(globbing)和模式比對中的字串解釋. $LINENO這個變數用來記錄自身在指令碼中所在的行號. 這個變數只有在指令碼使用這個變數的時候才有意義, 並且這個變數一般用於調試目的. $MACHTYPE機器類型,標識系統的硬體. $OLDPWD之前的工作目錄("OLD-print-working-directory", 就是之前你所在的目錄) $OSTYPE作業系統類型 $PATH可執行檔的搜尋路徑, 一般為/usr/bin/, /usr/X11R6/bin/, /usr/local/bin, 等等. $PPID進程的$PPID就是這個進程的父進程的進程ID(pid). [1] $PROMPT_COMMAND這個變數儲存了在主提示符$PS1顯示之前需要執行的命令. $PS1這是主提示符, 可以在命令列中見到它. $PS2第二提示符, 當你需要額外輸入的時候, 你就會看到它. 預設顯示">". $PS3第三提示符, 它在一個select迴圈中顯示(參見例子 10-29). $PS4第四提示符, 當你使用-x選項來呼叫指令碼時, 這個提示符會出現在每行輸出的開頭. 預設顯示"+". $PWD工作目錄(你當前所在的目錄),這與內建命令pwd作用相同. $REPLY當沒有參數變數提供給read命令的時候, 這個變數會作為預設變數提供給read命令. 也可以用於select菜單, 但是只提供所選擇變數的編號, 而不是變數本身的值#!/bin/bash  # REPLY是提供給'read'命令的預設變數.    echo -n "What is your favorite vegetable? "  read  echo "Your favorite vegetable is $REPLY."  #  若且唯若沒有變數提供給"read"命令時, REPLY才儲存最後一個"read"命令讀入的值.    echo -n "What is your favorite fruit? "  read fruit  echo "Your favorite fruit is $fruit."  echo "but...Value of \$REPLY is still $REPLY."  #  $REPLY還是儲存著上一個read命令的值,  #+ 因為變數$fruit被傳入到了這個新的"read"命令中.  exit 0  結果:root@ubuntu:~/resource/shell-study/0506-2013# ./test9.sh   What is your favorite vegetable?   Your favorite vegetable is .  What is your favorite fruit? apple  Your favorite fruit is apple.  but...Value of $REPLY is still .  root@ubuntu:~/resource/shell-study/0506-2013#   $SECONDS這個指令碼已經啟動並執行時間(以秒為單位).#!/bin/bash  TIME_LIMIT=10  INTERVAL=1  echo "Hit Control-C to exit before $TIME_LIMIT seconds."  while [ "$SECONDS" -le "$TIME_LIMIT" ]  do      if [ "$SECONDS" -eq 1 ];then          units=second      else            units=seconds      fi      echo "This script has been running $SECONDS $units."      #  在一台比較慢或者是附載過大的機器上,在單次迴圈中, 指令碼可能會忽略計數.       sleep $INTERVAL  done  echo -e "\a"  # Beep!(嗶嗶聲!)  exit 0  結果:root@ubuntu:~/resource/shell-study/0506-2013# ./test10.sh   Hit Control-C to exit before 10 seconds.  This script has been running 0 seconds.  This script has been running 1 second.  This script has been running 2 seconds.  This script has been running 3 seconds.  This script has been running 4 seconds.  This script has been running 5 seconds.  This script has been running 6 seconds.  This script has been running 7 seconds.  This script has been running 8 seconds.  This script has been running 9 seconds.  This script has been running 10 seconds.    root@ubuntu:~/resource/shell-study/0506-2013#   $SHELLOPTSshell中已經啟用的選項的列表, 這是一個唯讀變數.bash$ echo $SHELLOPTSbraceexpand:hashall:histexpand:monitor:history:interactive-comments:emacs $SHLVLShell層級, 就是Bash被嵌套的深度. 如果是在命令列中, 那麼$SHLVL為1, 如果在指令碼中那麼$SHLVL為2. $TMOUT如果$TMOUT環境變數被設定為非零值time的話, 那麼經過time秒後, shell提示符將會逾時. 這將會導致登出(logout).#!/bin/bash    #TMOUT=3  TIMELIMIT=5    PrintAnswer()  {      if [ "$answer" = TIMEOUT ];then          echo $answer      else          echo "Your favorite veggie is $answer"          kill $!      fi  }    TimerOn()  {      sleep $TIMELIMIT && kill -s 14 $$ &  }    Int14Vector()  {      answer="TIMEOUT"      PrintAnswer      exit 14  }    trap Int14Vector 14  echo "What is your favorite vegetable"  TimerOn  read answer  PrintAnswer    exit 0  結果:root@ubuntu:~/resource/shell-study/0506-2013# ./test11.sh   What is your favorite vegetable  TIMEOUT  root@ubuntu:~/resource/shell-study/0506-2013# ./test11.sh   What is your favorite vegetable  all  Your favorite veggie is all  root@ubuntu:~/resource/shell-study/0506-2013# ^C  $UID使用者ID號,目前使用者的使用者標識號, 記錄在/etc/passwd檔案中,這是目前使用者的真實id, 即使只是通過使用su命令來臨時改變為另一個使用者標識, 這個id也不會被改變. $UID是一個唯讀變數, 不能在命令列或者指令碼中修改它, 並且和id內建命令很相像.#!/bin/bash    ROOT_UID=0  if [ "$UID" -eq "$ROOT_UID" ];then      echo "You are root."  else      echo "You are just an ordinary user."  fi    ROOTUSER_NAME=root  username=`whoami`  #username=`id -nu`  if [ "$username" = "$ROOTUSER_NAME" ];then      echo "You are root."  else      echo "You are just an ordinary user."  fi  exit 0  結果:root@ubuntu:~/resource/shell-study/0507-2013# chmod +x test1.sh   root@ubuntu:~/resource/shell-study/0507-2013# ./test1.sh   You are root.  You are root.  位置參數$0, $1, $2, 等等 位置參數, 從命令列傳遞到指令碼, 或者傳遞給函數, 或者set給變數 $#命令列參數或者位置參數的個數$*所有的位置參數都被看作為一個單詞,"$*"必須被引用起來.$@與$*相同, 但是每個參數都是一個獨立的引用字串, 這就意味著, 參數是被完整傳遞的, 並沒有被解釋或擴充. 這也意味著, 參數列表中每個參數都被看作為單獨的單詞,當然, "$@"應該被引用起來.#!/bin/bash    E_BADARGS=65  if [ ! -n "$1" ];then      echo "usage: `basename $0` args1 args2 etc."      exit $E_BADARGS  fi    index=1  echo "Listing args with \"\$*\""  for arg in "$*"  do       echo "arg#$index = $arg"      let "index+=1"  done  echo "entire arg list seen as single word."    index=1  echo "Listing args with \"\$@\""  for arg in "$@"  do      echo "arg #$index = $arg"      let "index+=1"  done  echo "arg list seen as separate words."    index=1  echo "Listing args with \$* (unquoted):"  for arg in $*  do      echo "arg #$index = $arg"      let "index+=1"  done  echo "Arg list seen as separate words."    exit 0  結果:root@ubuntu:~/resource/shell-study/0507-2013# ./test2.sh 1 2 34  Listing args with "$*"  arg#1 = 1 2 34  entire arg list seen as single word.  Listing args with "$@"  arg #1 = 1  arg #2 = 2  arg #3 = 34  arg list seen as separate words.  Listing args with $* (unquoted):  arg #1 = 1  arg #2 = 2  arg #3 = 34  Arg list seen as separate words.  root@ubuntu:~/resource/shell-study/0507-2013#  shift的用法說明: #!/bin/bash  echo "$@"  shift  echo "$@"  shift  echo "$@"  結果;root@ubuntu:~/resource/shell-study/0507-2013# ./test3.sh 1 2 3 4 5 6  1 2 3 4 5 6  2 3 4 5 6  3 4 5 6  root@ubuntu:~/resource/shell-study/0507-2013#   $-傳遞給指令碼的標記(使用set命令). 參見例子 11-15.這本來是ksh的結構, 後來被引進到Bash中, 但是不幸的是, 看起來它不能夠可靠的用在Bash指令碼中. 一種可能的用法是讓一個指令碼測試自身是不是可互動的.$!運行在背景最後一個作業的PID(進程ID)$_這個變數儲存之前執行的命令的最後一個參數的值.#!/bin/bash  echo $_              # /bin/bash  du >/dev/null        # 這麼做命令列上將沒有輸出.  echo $_              # du  ls -al >/dev/null    # 這麼做命令列上將沒有輸出.  echo $_              # -al  (這是最後的參數)     :  echo $_   結果:root@ubuntu:~/resource/shell-study/0507-2013# ./test4.sh   ./test4.sh  du  -al  :  root@ubuntu:~/resource/shell-study/0507-2013#   $?命令, 函數, 或者是指令碼本身的退出狀態代碼#!/bin/bash    echo $?    cat file #wrong command  echo $?    echo "right command."  echo $?  exit 0  結果:root@ubuntu:~/resource/shell-study/0507-2013# ./test5.sh   0  cat: file: No such file or directory  1  right command.  0  root@ubuntu:~/resource/shell-study/0507-2013#    $$指令碼自身的進程ID. $$變數在指令碼中經常用來構造"唯一的"臨時檔案名稱

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.