20天學會bash shell script (二)

pingley發表於2012-04-05
20天學會bash shell script. (二)
shell 算數表示式
語法格式:
expr oprand1 math-operator op2
算數運算子:
+,- 加,減
\*, /  乘,處
% 取模
[linux@zeng bin]$ cat math.sh
#!/bin/bash
#
#This shell script. about shell arithmetic.

expr 4 + 1
expr 5 - 1
expr 20 / 4
expr 10 % 3
expr 2 \* 5

x=`expr 2 + 8`
echo "2+8 is equal $x" 
注: 在shell script. 中運算元與運算子之間需要有空格的存在。
如果需要把一個表示式的值賦給一個變數,表示式應該用反單引號括起來。
比如我們這邊的x=`expr 2 + 8`
[linux@zeng bin]$ math.sh
5
4
5
1
10
2+8 is equal 10
關於shell script. 中的引號
1、雙引號,被雙引號包圍的字元儲存變,除了(\ 和 $ )。
2、單引號,被單引號包圍的字元儲存不變。
3、反單引號,執行被反單引號包圍的命名。
[linux@zeng bin]$ cat quotes.sh
#!/bin/bash
#
#This shell script. about quotes.
#
var=100
echo "The varible var value is $var"
echo 'The varible var value is $var'
echo `pwd`
[linux@zeng bin]$ quotes.sh
The varible var value is 100
The varible var value is $var
/home/linux/bin
read 語句
大多數程式需要與使用者互動。所以就不能少接受使用者輸入的語句。在shell 中read
可以用來接受使用者從鍵盤的輸入,並把資料儲存在一個變數中。
語法格式:
read variable1,variable2,...variableN
[linux@zeng bin]$ cat  read_input.sh
#!/bin/bash
#
#This shell script. read you input from keyboard.
#
echo "Can you tell me what are you looking for?"
read look
echo "You are looking for $look."
[linux@zeng bin]$ read_input.sh
Can you tell me what are you looking for?
job
You are looking for job.
萬用字元
1、*  匹配任何字元或者字串。
2、? 匹配單個字元。
3、[...] 匹配在其中的任何一個字元。
4、[..-..] 匹配在期間的任何一個字元。
上面的..表示字元或者數字。
先來看下當前目錄下的檔案有那些。
[linux@zeng bin]$ ls
math.sh  quotes.sh  read_input.sh  test01.sh  wildcard.sh
為了說明萬用字元,我編寫了如下內容的一個指令碼。
[linux@zeng bin]$ cat wildcard.sh 
#!/bin/bash
#
#This shell script. about wild card.
#
echo "Show all files in current dictionary."
ls *
echo "Find files start character m."
find . -name  m*
echo "Find files test??.sh, ? represent a character unknow."
find . -name test??.sh
echo "Find files start with string mat end up  with .sh, but a character in [abch]."
find . -name mat[abch].sh
echo "Find files start with character m end up with th.sh,but a character in a from z."
find . -name m[a-z]th.sh
[linux@zeng bin]$ wildcard.sh
Show all files in current dictionary.
math.sh  quotes.sh  read_input.sh  test01.sh  wildcard.sh
Find files start character m.
./math.sh
Find files test??.sh, ? represent a character unknow.
./test01.sh
Find files start with string mat end up  with .sh, but a character in [abch].
./math.sh
Find files start with character m end up with th.sh,but a character in a from z.
./math.sh
在shell 命令列下一次執行多個命令
語法格式:command1;command2
我這裡一次執行兩個命令,who i am 用來檢視登入的使用者的資訊。
pwd 列印出當前的目錄。
[linux@zeng bin]$ who i am ;pwd#用分號分隔命令。
linux    pts/1        2012-04-05 18:27 (192.168.56.1)
/home/linux/bin
注這裡的 who i am 列印出來的總是最初登入系統時的使用者資訊。
[linux@zeng bin]$ su - root
Password: 
[root@zeng ~]# who i am
linux    pts/1        2012-04-05 18:27 (192.168.56.1)
命令列引數
命令列引數的作用:
1、用來控制命令(程式)的執行。
2、命令(程式)處理的資料的來源。
如果需要給命令或者我們的shell script. 傳遞引數,我們可以使用shell script. 預設的變數($0,$1...)
我們透過下面一個指令碼來演示。
這個指令碼的主要功能是根據使用者在命令列提供的引數,進行檔案的複製。
[linux@zeng bin]$ cat argument.sh 
#!/bin/bash
#
#This shell script. about command line arguments.
#
echo "Total number of command line arguments are $#"
echo "Your shell script. name is $0"
echo "First argument is $1"
echo "Second argument si $2"
cp $1 $2
echo "All argument are:$* or $@"
[linux@zeng bin]$ argument.sh /etc/inittab /home/linux/bin
Total number of command line arguments are 2
Your shell script. name is /home/linux/bin/argument.sh
First argument is /etc/inittab
Second argument si /home/linux/bin
All argument are:/etc/inittab /home/linux/bin or /etc/inittab /home/linux/bin
剛才執行指令碼的時候複製過來的檔案。
[linux@zeng bin]$ ll inittab
-rw-r--r--. 1 linux linux 926 Apr  5 20:08 inittab
注:
$# 表示引數的個數,這裡是2.
$0 表示執行命令(程式)的名稱,這裡是 /home/linux/bin/argument.sh
$1 表示由命令列提供的第一個引數。
$2表示由命令列提供的第二個引數。
$N 表示由命令列提高的第N個引數。
$@與$* 表示所有的命令列引數。
資料流重定向與管道命令
在linux 中資料流分為三類:
1、標準輸入(stdin),檔案描述符0,使用< 或 <<.>
2、標準輸出(stdout), 檔案描述符 1,使用> 或 >>.
3、標準錯誤輸出(stderr), 檔案描述符 2,使用 2> 或2>>.
示例:
把 ll 的輸出重定向到 list.txt 檔案。在這裡list.txt 檔案將會被自動的建立,如果該檔案已經存在其中的內容會被覆蓋掉。
[oracle@zeng ~]$ ll > list.txt
使用mail.txt 檔案中的內容作為輸入。
[oracle@zeng ~]$ mail root < mail.txt
 ~/.bash_profile 檔案中新增一行。
[oracle@zeng ~]$ echo "HISTSIZE=100" >> ~/.bash_profile 
使用輸出重定向把標準輸出和標準錯誤輸出分開來。
[oracle@zeng ~]$ find /home -name .bash_profile
find: `/home/linux': Permission denied
find: `/home/hello': Permission denied
/home/oracle/.bash_profile
[oracle@zeng ~]$ find /home -name .bash_profile >right.txt 2>error.txt
[oracle@zeng ~]$ cat right.txt
/home/oracle/.bash_profile
[oracle@zeng ~]$ cat error.txt
find: `/home/linux': Permission denied
find: `/home/hello': Permission denied
如果標準錯誤輸出我們不想儲存的話,可以將他從定位到 /dev/null(bit bucket,垃圾黑桶)。
[oracle@zeng ~]$ find /home -name .bash_profile >>right.txt 2>/dev/null
使用的是>>,所以append find 的輸出。
[oracle@zeng ~]$ cat right.txt
/home/oracle/.bash_profile
/home/oracle/.bash_profile
標準輸出重定向是不會重定向標準錯誤輸出的。
[oracle@zeng ~]$ find /home -name .bash_profile >right.txt  
find: `/home/linux': Permission denied
find: `/home/hello': Permission denied
可以使用&> right.txt 或者使用> right.txt 2>&1來把標準輸出與標準錯誤輸出重定向到同一個檔案中。
[oracle@zeng ~]$ find /home -name .bash_profile &>right.txt 
[oracle@zeng ~]$ cat right.txt
find: `/home/linux': Permission denied
find: `/home/hello': Permission denied
/home/oracle/.bash_profile
管道命令(pipe):就是把一個程式的輸出作為另外一個程式的輸入。語法格式如下:
命令1的標準輸出作為命令2的標準輸入:command1 | command2
命令1 的標準輸出與標準錯誤輸出作為命令2的標準輸入:command1 2>&1 | command2
排序與計數命令
很多時候我們需要對資料進行排序,以使資料以更可讀的方式呈現。或者體現出
某種規律,或者進行計數。
我編輯瞭如下的文字檔案。
[linux@zeng bin]$ cat source.txt 
ORACLE
oracle
IBM
EMC
SISCO
HUAWEI
MICROSOFT
VMWARE
VMWARE
redhat
[linux@zeng bin]$ cat source.txt |sort
EMC
HUAWEI
IBM
MICROSOFT
oracle
ORACLE
redhat
SISCO
VMWARE
VMWARE
我在這裡使用sort 進行排序,預設sort 是按照第一個字母進行排序的(從a-z,A-Z小寫字母更大)。
[linux@zeng bin]$ cat source.txt |sort -r
VMWARE
VMWARE
SISCO
redhat
ORACLE
oracle
MICROSOFT
IBM
HUAWEI
EMC
使用 -r 項進行反向排序。
sort 的常用選項還有:
-f 忽略大小寫
-n 使用純數字進行排序,預設使用的是按照字元排序。
-t 域的分割。
-f 按照那個域進行排序的意思。
[linux@zeng bin]$ cat /etc/passwd | sort -t ':' -k 3 -n
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
其中-t 指定域之間的分割符這裡是 :,預設是使用Tab 分割。
-k 表示按照第三個域來進行排序,即按照uid 進行排序。
-n 表示按照數值進行排序。
怎麼來報告或者消除重複的行呢?可以使用uniq 命令。
[linux@zeng bin]$ cat source.txt |sort -r|uniq
VMWARE
SISCO
redhat
ORACLE
oracle
MICROSOFT
IBM
HUAWEI
EMC
重複的行就消除了。
[linux@zeng bin]$ cat source.txt |sort -r|uniq -ic
      2 VMWARE
      1 SISCO
      1 redhat
      2 ORACLE
      1 MICROSOFT
      1 IBM
      1 HUAWEI
      1 EMC
還可以使用uniq 來做一些統計.
-i 表示忽略大小寫的不同。
-c 進行出現次數的計數。
[linux@zeng bin]$ cat source.txt |sort -r|uniq -icd
      2 VMWARE
      2 ORACLE
-d 是隻計數重複的行。
如果覺得sort,uniq還不夠用,我們還有"廁所"wc 命令。
來看看系統中有幾個使用者。
[linux@zeng bin]$ cat /etc/passwd|wc -l
42
-l 表示統計行的數量,包括空行。
[linux@zeng bin]$ cat source.txt|wc -w
10
統計下有多少個單詞,-w 即使word 的意思。
還可以進行統計檔案bytes 的大小。
[linux@zeng bin]$ cat source.txt|wc -c
66
[linux@zeng bin]$ ll source.txt 
-rw-rw-r--. 1 linux linux 66 Apr  5 20:48 source.txt

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26110315/viewspace-720411/,如需轉載,請註明出處,否則將追究法律責任。

相關文章