2012/08/26

The Bash Shell (2)


The bash shell

Bash 變數

  • Variables are named values
  1. 常使用在儲存資料和命令的輸出
  • 設定變數的方式 VARIABLE=VALUE
  • 參考這個變數值 $VARIABLE
$ HI="Hello, and welcome to $(hostname)."
$ echo $HI
Hello, and welcome to stationX.
  • ex:
# 將 ls /etc 的值存入 files 變數
[mtchang@localhost ~]$ files=$(ls /etc/)
# 將變數內容取出
[mtchang@localhost ~]$ echo $files
a2ps.cfg a2ps-site.cfg acpi 
...(skip)...

Environment Variables

  • Variables are local to a single shell by default
  • Environment variables 無法傳遞到 child shells
  1. Set with export VARIABLE=VALUE
  2. Accessed by some programs for configuration
  • ex:
[mtchang@localhost ~]$ hi="hello, nice to meet you."
[mtchang@localhost ~]$ echo $hi
hello, nice to meet you.
  • set, env and echo 這三個指令都是用來顯示變數內容的
[mtchang@localhost ~]$ set | less
[mtchang@localhost ~]$ env | less
[mtchang@localhost ~]$ echo $HOME

一些常用的變數

  • Configuration variables
  • PS1: PS1的bash prompt提示符號變數:(man 1 bash是一本很棒的線上手冊)
  1. \h hostname
  2. \u user name
  3. \w 目前工作目錄
  4. \! history目前指令數量
  5. \$ 秀「$」這個文字符號
  • 節錄部份 man 1 bash 內容
mtchang@cccm:~<360>$ man 1 bash
PROMPTING
       When  executing  interactively,  bash  displays  the primary prompt PS1 when it is
       ready to read a command, and the secondary prompt PS2 when it needs more input  to
       complete  a command.  Bash allows these prompt strings to be customized by insert-
       ing a number of backslash-escaped special characters that are decoded as follows:
              \a     an ASCII bell character (07)
              \d     the date in "Weekday Month Date" format (e.g., "Tue May 26")
              \D{format}
                     the format is passed to strftime(3) and the result is inserted  into
                     the prompt string; an empty format results in a locale-specific time
                     representation.  The braces are required
              \e     an ASCII escape character (033)
              \h     the hostname up to the first ‘.’
              \H     the hostname
              \j     the number of jobs currently managed by the shell
              \l     the basename of the shell’s terminal device name
              \n     newline
              \r     carriage return
              \s     the name of the shell, the basename of $0 (the portion following the
                     final slash)
              \t     the current time in 24-hour HH:MM:SS format
              \T     the current time in 12-hour HH:MM:SS format
              \@     the current time in 12-hour am/pm format
              \A     the current time in 24-hour HH:MM format
              \u     the username of the current user
              \v     the version of bash (e.g., 2.00)
              \V     the release of bash, version + patch level (e.g., 2.00.0)
              \w     the current working directory, with $HOME abbreviated with a tilde
              \W     the  basename  of the current working directory, with $HOME abbrevi-
                     ated with a tilde
              \!     the history number of this command
              \#     the command number of this command
              \$     if the effective UID is 0, a #, otherwise a $
              \nnn   the character corresponding to the octal number nnn
              \\     a backslash
              \[     begin a sequence of non-printing characters, which could be used  to
                     embed a terminal control sequence into the prompt
              \]     end a sequence of non-printing characters
  • PATH: 可執行程式的路徑
  • EDITOR: 預設文字編輯器
  • HISTFILESIZE: Number of commands in bash history
  • 資訊變數
  1. HOME: User's home directory
  2. EUID: User's effective UID
  • PS1設定範例:
[lcc09@localhost ~]$ PS1="\u@\h:\w(\!)\$ "
lcc09@localhost:~(512)$ PS1="[\u@\h:\w]\$ "
[lcc09@localhost:~]$

Aliases

  • Aliases let you create shortcuts to commands
   $ alias dir='ls -laF'
  • Use alias by itself to see all set aliases
  • Use alias followed by an alias name to see alias value
     $ alias dir
     alias dir='ls -laF'
  • 綜合範例
[lcc09@localhost:~]$ alias
# 列出目前系統的別名
alias l.='ls -d .* --color=tty'
alias ll='ls -l --color=tty'
alias ls='ls --color=tty'
alias vi='vim'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
[lcc09@localhost:~]$ unalias vi
# 解除某個別名
[lcc09@localhost:~]$ alias
alias l.='ls -d .* --color=tty'
alias ll='ls -l --color=tty'
alias ls='ls --color=tty'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'

擴展 bash shell 命令列

  • 解釋為劃分為字包含 " ' | & ; ( ) < >
  • alias 能夠和其他指令混用
  • 解釋為 curly-brace statements ({})
# 擴展為 /etc/o* 及 /etc/c*
[root@cccm ~]# ls /etc/{o,c}*
  • 解釋為 tilde statements (~)
  • 解釋為 variables ($) 通常用 $ ${} $(()) $[] $() `
  • Expand file globs (*, ?, [abc], etc)
  • Prepare I/O redirections (<, >)
  • Run the command  !

Preventing Expansion(預防擴展)

  • Backslash ( \ ) 避免特殊字元被shell 解釋掉,具有脫逸某個字元的功能。
$ echo Your cost: \$5.00
Your cost: $5.00
  • Quoting(引號) prevents expansion
  1. Single quotes (') inhibit all expansion
  2. Double quotes (") inhibit all expansion, except:
  3. $ (dollar sign) - variable expansion
  4. ` (backquotes) - command substitution
  5. \ (backslash) - single character inhibition
  6.  ! (exclamation point) - history substitution
  • 請觀察 quoting 的差異
[root@cccm ~]# echo $HOME
/root
[root@cccm ~]# echo \$HOME
$HOME
[root@cccm ~]# echo '$HOME'
$HOME
[root@cccm ~]# echo "$HOME"
/root
[root@cccm ~]# echo `$HOME`
-bash: /root: is a directory

Login vs non-login shells

  • Startup is configured differently for login and non-login shells
  • Login shells are:
  1. Any shell created at login (includes X login)
  2. su -
  • Non-login shells are:
  1. su
  2. graphical terminals
  3. executed scripts
  4. any other bash instances
  • 請觀察其中的差異
[root@cccm ~]# su mtchang
[mtchang@cccm root]$ exit
exit
[root@cccm ~]# su - mtchang
[mtchang@cccm ~]$

Bash啟動工作指令稿

  • 再bash的啟動過程中,會依序載入這些啟動命令稿
  • 存儲在 /etc/profile (全域) and ~/.bash_profile (使用者)
  • 只有可以登入的 shell 才有作用
  • 通常用來
  1. 設定環境變數
  2. Running commands (eg. mail-checker script)
  • 存儲在 /etc/bashrc (全域) and ~/.bashrc (使用者)
  • Run for all shells
  • 通常用來
  1. Setting 本地端的變數
  2. Defining aliases(別名設定)
  • Bash 離開時的任務
  • 存儲在 ~/.bash_logout (user)
  • 在 login shell 離開時執行
  • 通常用來
  1. Creating automatic backups
  2. Cleaning out temporary files

Scripting

shell變數運算

(3.6) 變數的算數運算

在變數的算數運算方面 , 我們主要靠的是 expr 這個指令 . 各位
可以先在提示符號下試試 :

  % expr 30 + 20
  50
  % expr 30 - 20
  10
  % expr 30 \* 20     <-- * 是乘號 , 但要以反斜線去除特殊意義
  600
  % expr 30 / 20      <-- 只會取整數部份
  1

從上面我們可以看到 , expr 的確可以作整數的四則運算 . 但我們提
過 , 變數是沒有資料型別的 , 所以 expr 只能處理變數內容為可視
為整數的變數 . 如 :

  % var1=10
  % expr $var1 + 1        <-- 把 var1 加 1 

像下面就錯了 :

  % var1=10         
  % var2=20
  % expr var1 + var2      <-- var1 及 var2 不是內容 , $var1
  expr: non-numeric argument   $var2 才是

上面要改成 :

  % var1=10         
  % var2=20
  % expr $var1 + $var2  
  
下面是無意義的例子 :

  % var1=red
  % var2=green
  % expr $var1 + $var2    <-- expr 不能處理 red + green

那假如我們要把某一變數的內容加一再放回去呢 ?
如同 Pascal 中的 i:=i+1 , C 語言中的 i=i+1 那要如何作 ?   
很簡單 , 如下 :

  % i=`expr $i + 1`  

等號右邊的反單引號會先執行 , expr 把 i 加 1 然後再把得到
的結果指定給 i

命令列輸入的引數

  • Positional parameters are special variables that hold the command-line arguments to the script.
  • The positional parameters available are $1, $2, $3, etc. . These are normally assigned to more meaningful variable names to improve clarity.
  • $* holds all command-line arguments
  • $# holds the number of command-line arguments
  • 範例:
[lcc09@localhost:~]$ vi argu.sh  #vi建立一個script
#!/bin/bash
echo "The program name is $0"
printf "The first argument is %s and %s \n" $1 $2
echo "All argument are $*
[lcc09@localhost:~]$ chmod +x argu.sh  #賦予執行權限
[lcc09@localhost:~]$ ./argu.sh centos fedora linux is good #執行script並帶引數
The program name is ./argu.sh
The first argument is centos and fedora
All argument are centos fedora linux is good

Taking input with the read command

  • Use read to assign input values to one or more shell variables:
  1. -p designates prompt to display
  2. read reads from standard input and assigns one word to each variable
  3. Any leftover words are assigned to the last variable
  4. read -p "Enter a filename: " FILE
[lcc09@localhost:~]$ vi read.sh
#!/bin/bash
read -p "Enter name: " FIRST LAST
echo "first is $FIRST and last is $LAST"
[lcc09@localhost:~]$ ./read.sh
Enter name: mt chang
first is mt and last is chang

參考文件

張貼留言