【shell簡介】
java
全部的命令都是在shell終端輸入而且執行。打開終端就會出現一個提示符。其形式一般有兩種:linux
[root@localhost ~]#
或者shell
[hcc@localhost ~]$
其實$表示普通用戶,#表示超級用戶(root user)。超級用戶是linux系統中權限最高的用戶。
vim
shell腳本一般是以"#!"(shebang)其實的文本文件,以下所示:數組
#!/bin/bash
linux環境下的任何腳本語言,都是以這樣一個被稱爲shebang的特殊行爲起始的。/bin/bash是Bash的路徑。關於shebang的解釋:#發音爲sharp,!發音爲bang,所以shebang合起來就表示了#!
bash
linux執行腳本有兩種方式:一種是將腳本做爲sh的命令行參數,另外一種是將腳本做爲具備執行權限的可執行文件。
app
#將腳本做爲sh的命令行參數(注意:這種方式腳本的shebang標示符無效)ide
sh script.sh
#將腳本做爲具備執行權限的可執行文件函數
chmod a+x script.sh #若是該腳本沒有執行權限,須要賦予執行權限 ./script.sh #直接運行該腳本,假設腳本在當前目錄
若是是以可執行文件的方式來執行腳本的話,shell程序首先會讀取腳本的首行,即shebang標示符。若是首行是 #!/bin/bash,那麼內部會以以下的命令行來執行該腳本spa
/bin/bash script.sh
在bash中,每一個命令都是經過分號或者換行符來進行分割的
cmd1;cmd2
至關於兩條命令
cmd1 cmd2
【終端打印】
一、使用echo完成終端打印
默認狀況下,echo會在每次調用後添加一個換行符
[hcc@localhost ~]$ echo "Hello World" Hello World [hcc@localhost ~]$
若是不想換行,可使用-n阻止echo換行
[hcc@localhost ~]$ echo -n "Hello World" Hello World[hcc@localhost ~]$
echo命令後面的字符串能夠有三種形式,分別是:帶雙引號的字符串、帶單引號的字符串、不帶符號的字符串。三者之間的區別以下:
(1)帶雙引號的字符串,不能直接輸出!號,以下例
[hcc@localhost ~]$ echo "Hello World!" -bash: !": event not found [hcc@localhost ~]$
在雙引號的字符串中必定要輸出!號,有兩種辦法:
#使用轉義字符(缺點:轉義字符也打印出來了,不推薦)
[hcc@localhost ~]$ echo "Hello World\!" Hello World\! [hcc@localhost ~]$
#首先執行set +H命令,在使用echo打印(推薦)
[hcc@localhost ~]$ set +H [hcc@localhost ~]$ echo "Hello World!" Hello World! [hcc@localhost ~]$
(2)帶單引號的字符串,不能識別變量,內容只做爲一個字符串輸出
#使用單引號,原樣的將字符串內容進行輸出
[hcc@localhost ~]$ echo '$PATH' $PATH [hcc@localhost ~]$
(3)不帶任何標識的字符串
不帶任何標識的字符串,在遇到;號時,命令會被拆分,以下例
[hcc@localhost ~]$ echo $PATH;hello /usr/lib/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/hcc/bin -bash: hello: command not found [hcc@localhost ~]$
經過例子能夠看到,shell將;號後面的hello當成了第二條命令。
二、echo的轉義輸出
#使用-e可以完成echo的轉義輸出
\a 發出警告聲; \b 刪除前一個字符; \c 最後不加上換行符號; \f 換行但光標仍舊停留在原來的位置; \n 換行且光標移至行首; \r 光標移至行首,但不換行; \t 插入tab; \v 與\f相同; \\ 插入\字符; \nnn 插入nnn(八進制)所表明的ASCII字符;
例子:
[root@localhost ~]# echo -e "1\t2\t3\t" 1 2 3 [root@localhost ~]#
三、echo打印彩色輸出
在終端打印彩色很是的好玩,咱們可使用轉義序列來實現。
每種顏色對應的顏色碼:
重置=0, 黑色=30, 紅色=31, 綠色=32, ***=33, 藍色=34, 洋紅=35, 青色=36, 白色=37。 黑色背景=40, 紅色背景=41, 綠色背景=42, ***背景=43, 藍色背景=44, 洋紅背景=45, 青色背景=46, 白色背景=47
使用 \e[顏色碼m 便可以實現顏色的轉義
例子
四、printf進行格式化輸出
printf使用的參數和C語言中printf使用的參數如出一轍。
默認狀況,printf不像echo同樣在末尾自動添加換行符,所以須要換行的話,須要加上\n
例子:
[hcc@localhost ~]$ vim printf.sh #!/bin/bash #文件名 printf.sh printf "%-5s %-10s %-4s\n" No Name Mark printf "%-5s %-10s %-4.2f\n" 1 hucc 96.50 printf "%-5s %-10s %-4.2f\n" 2 zhsl 97.50 printf "%-5s %-10s %-4.2f\n" 3 luzh 98.50
執行該腳本:
[hcc@localhost ~]$ chmod a+x printf.sh [hcc@localhost ~]$ ./printf.sh No Name Mark 1 hucc 96.50 2 zhsl 97.50 3 luzh 98.50 [hcc@localhost ~]$
解釋:%-5s指明瞭一個佔5個字符的字符串,-表示左對齊,若是不指定-那麼默認是右對齊方式的。
五、打印總結
打印總的來講很簡單,可是很是經常使用,屬於必須掌握的知識點。
【玩轉變量以及環境變量】
在bash中,每個變量的值的類型都是字符串,不管你給的變量有沒有用單引號或者雙引號,值都是以字符串的形式進行存儲的。
有一些特殊的變量會被shell環境和操做系統用來存儲一些特別的值,這類變量就被稱爲環境變量。
一、查看某個進程的環境變量
#顯示瞬間行程 (process) 的動態
[root@localhost ~]# ps PID TTY TIME CMD 28414 pts/0 00:00:00 bash 28433 pts/0 00:00:00 ps [root@localhost ~]#
#查看某個進程的環境變量
[root@localhost ~]# cat /proc/28414/environ USER=rootLOGNAME=rootHOME=/rootPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/binMAIL=/var/mail/rootSHELL=/bin/bashSSH_CLIENT=192.168.99.100 52296 22SSH_CONNECTION=192.168.99.100 52296 192.168.99.11 22SSH_TTY=/dev/pts/0TERM=linuxSELINUX_ROLE_REQUESTED=SELINUX_LEVEL_REQUESTED=SELINUX_USE_CURRENT_RANGE=[root@localhost ~]#
環境變量之間默認是已\0進行分隔的,可讀行不是特別好,咱們能夠用tr命令將\0替換成\n
[root@localhost ~]# cat /proc/28414/environ |tr "\0" "\n" USER=root LOGNAME=root HOME=/root PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin MAIL=/var/mail/root SHELL=/bin/bash SSH_CLIENT=192.168.99.100 52296 22 SSH_CONNECTION=192.168.99.100 52296 192.168.99.11 22 SSH_TTY=/dev/pts/0 TERM=linux SELINUX_ROLE_REQUESTED= SELINUX_LEVEL_REQUESTED= SELINUX_USE_CURRENT_RANGE= [root@localhost ~]#
二、實戰演練
一個變量能夠經過如下方式進行復制,注意=號左右都沒有空格
name=value # =號左右都沒有空格
例子:
[root@localhost ~]# name=hucc [root@localhost ~]# echo $name hucc [root@localhost ~]#
環境變量是未在當前進程中定義,而從父進程繼承而來的變量。
例如在安裝jdk的時候咱們須要指定JAVA_HOME和PATH兩個環境變量
export JAVA_HOME=/usr/local/src/jdk1.7.0_55 export PATH=$PATH:$JAVA_HOME/bin
export命令用於設置環境變量
三、補充內容
(1)得到字符串長度
例子:
[root@localhost ~]# num=0123456789 [root@localhost ~]# echo ${#num} 10 [root@localhost ~]#
(2)識別當前的shell版本
[root@localhost ~]# echo $SHELL /bin/bash [root@localhost ~]# echo $0 -bash [root@localhost ~]#
(3)檢查是否爲超級用戶
[root@localhost ~]# vim isRoot.sh #!/bin/bash #文件名:isRoot.sh if [ $UID -ne 0 ];then echo "不是超級管理員,請以超級管理員的身份進行登陸" else echo "歡迎你,超級管理員" fi
執行該腳本:
[root@localhost ~]# chmod a+x isRoot.sh [root@localhost ~]# ./isRoot.sh 歡迎你,超級管理員 [root@localhost ~]#
(4)修改Bash提示字符串
#默認的shell提示腳本是在/etc/bashrc文件中定義的
[root@localhost ~]# cat /etc/bashrc | grep PS1 if [ "$PS1" ]; then [ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@\h \W]\\$ " # if [ "$PS1" ]; then # PS1="[\u@\h:\l \W]\\$ " if [ "$PS1" ]; then [root@localhost ~]#
修改提示字符串(只是用變量覆蓋了,並無修改環境變量,若是想要修改環境,能夠到/etc/profile中進行修改)
【經過shell進行數學運算】
一、使用let進行數學運算(只能計算整數,推薦使用)
例子:
[root@localhost ~]# num1=4 [root@localhost ~]# num2=5 [root@localhost ~]# result=num1+num2 #沒有使用let,直接識別是字符串 [root@localhost ~]# echo $result num1+num2 [root@localhost ~]# let result=num1+num2 #let能夠執行算數操做,而且不用加上$ [root@localhost ~]# echo $result 9 [root@localhost ~]# let num1++ #let能夠進行自增操做 [root@localhost ~]# echo $num1 5 [root@localhost ~]# let num2-- #let能夠進行自減操做 [root@localhost ~]# echo $num2 4 [root@localhost ~]# let num1+=num2 #let的簡寫算術操做 [root@localhost ~]# echo $num1 9 [root@localhost ~]#
經過例子能夠看到,let命令能夠直接執行基本的算數操做,而且使用let時,變量名之間再也不須要加上$
二、使用[]和(())進行算術操做(只能計算整數)
操做符[]和(())跟使用let命令相似,可是須要加上$標示符,例如
[root@localhost ~]# no1=4 [root@localhost ~]# no2=5 [root@localhost ~]# result=$[no1+no2] #使用[]操做符 [root@localhost ~]# echo $result 9 [root@localhost ~]# result=$((no1-no2)) #使用(())操做符 [root@localhost ~]# echo $result -1 [root@localhost ~]#
三、使用expr進行算術操做(只能計算整數)
expr使用起來也差很少,也須要加上$標示符,例如
[root@localhost ~]# no1=4 [root@localhost ~]# result=$(expr $no1 + 4) [root@localhost ~]# echo $result 8 [root@localhost ~]#
四、使用bc命令進行復雜的算術運算,好比浮點數的運算以及使用高級函數
(1)設定小數的精度
例子:
[root@localhost ~]# echo "8/3"|bc #若是不設定精度,默認計算是整數 2 [root@localhost ~]# echo "scale=2;8/3"|bc #能夠在具體操做前用scale設定精度,用;號隔開 2.66 [root@localhost ~]#
(2)進制轉換
例子:
[root@localhost ~]# no=90 [root@localhost ~]# echo "obase=2;$no"|bc 1011010 [root@localhost ~]# echo "obase=16;$no"|bc 5A [root@localhost ~]#
(3)計算平方根
例子:
[root@localhost ~]# echo "scale=2;sqrt(30)"|bc 5.47 [root@localhost ~]#
【玩轉文件描述符和重定向】
一、預備知識
文件描述符
0---stdin 1---stdout 2---stderr
重定向
> 將輸出重定向到文件,會把文件的內容清空。 >> 將輸出重定向到文件,追加到末尾,不會把文件的內容清空。
二、實戰演練
例子:
[hcc@localhost ~]$ echo "Tom" > out.txt #將輸出重定向到文件 [hcc@localhost ~]$ cat out.txt Tom [hcc@localhost ~]$ echo "Jerry" > out.txt #會將文件以前的內容清空 [hcc@localhost ~]$ cat out.txt Jerry [hcc@localhost ~]$ echo "Jim" >> out.txt #不會將文件以前的內容清空 [hcc@localhost ~]$ cat out.txt Jerry Jim [hcc@localhost ~]$
重定向操做符默認使用標準輸出。也就是說 >至關於1> >>至關於1>>
對於錯誤信息的處理
[hcc@localhost ~]$ ls + ls: 沒法訪問+: 沒有那個文件或目錄 [hcc@localhost ~]$ echo $? #當一個命令執行錯誤時,會返回一個非0的狀態,這個狀態能夠從$?變量中獲取 2 [hcc@localhost ~]$
下面的例子不會將錯誤信息打印到文本中,而是會打印到命令窗口:
[hcc@localhost ~]$ ls + > out.txt ls: 沒法訪問+: 沒有那個文件或目錄 #在命令窗口打印了 [hcc@localhost ~]$ cat out.txt [hcc@localhost ~]$ #在文件中沒有內容,說明沒有重定向到文件中
如何將錯誤信息重定向到文件中:
[hcc@localhost ~]$ ls + 2> out.txt #在命令窗口沒有打印出錯誤信息 [hcc@localhost ~]$ cat out.txt #在文件中有錯誤信息,說明將錯誤信息重定向到文件中了 ls: 沒法訪問+: 沒有那個文件或目錄 [hcc@localhost ~]$
將錯誤信息和成功信息分別重定向到分別的文件中
[hcc@localhost ~]$ ls + 1>>out.txt 2>>err.txt #將成功信息重定向out.txt 將錯誤信息重定向到err.txt [hcc@localhost ~]$ ls 1>>out.txt 2>>err.txt #將成功信息重定向out.txt 將錯誤信息重定向到err.txt [hcc@localhost ~]$ cat out.txt err.txt out.txt printf.sh [hcc@localhost ~]$ cat err.txt ls: 沒法訪問+: 沒有那個文件或目錄 [hcc@localhost ~]$
總結:其實道理很簡單,不管是成功信息仍是失敗信息,若是沒有重定向則默認在命令窗口輸出,1>或者>只能重定向成功的信息到文件,2>只能重定向錯誤的信息到文件。
【數組和關聯數組】
一、預備知識
數組是shell腳本中很是重要的組成部分,它藉助索引將多個獨立的數據存儲爲一個集合。
Bash支持普通數組和關聯數組。普通數組只能使用整數做爲數組的索引(我的感受至關於java中的數組),關聯數組可使用字符串做爲數組的索引(感受至關於java中的map,確切的說應該是Properties類)。
二、實戰演練
(1)普通數組
普通數組的經常使用操做:
[hcc@localhost ~]$ a1=("apple" "banana" "orange" "pear") #直接定義普通數組 [hcc@localhost ~]$ a2[0]="Tom" #經過索引-值的方式定義數組 [hcc@localhost ~]$ a2[1]="Jerry" #經過索引-值的方式定義數組 [hcc@localhost ~]$ a2[2]="Kitty" #經過索引-值的方式定義數組 [hcc@localhost ~]$ a2[3]="Jack" #經過索引-值的方式定義數組 [hcc@localhost ~]$ echo ${a1[0]} #經過索引獲取數組的值 apple [hcc@localhost ~]$ echo ${a2[*]} #打印整個數組 Tom Jerry Kitty Jack [hcc@localhost ~]$ echo ${a1[@]} #打印整個數組 apple banana orange pear [hcc@localhost ~]$ echo ${#a1[*]} #打印數組的長度 4 [hcc@localhost ~]$
(2)關聯數組
關聯數組的經常使用操做:
[hcc@localhost ~]$ declare -A array #關聯數組須要聲明 [hcc@localhost ~]$ array=([name]="hucc" [age]="23" [address]="五道口") #直接定義 [hcc@localhost ~]$ array[salary]="8000" #經過索引-值的方式添加數組的內容 [hcc@localhost ~]$ echo ${array[name]} #經過索引獲取數組的值 hucc [hcc@localhost ~]$ echo ${!array[*]} #打印數組全部的索引,一樣適用於普通數組 name age address salary [hcc@localhost ~]$ echo ${array[*]} #打印數組全部的值 hucc 23 五道口 8000 [hcc@localhost ~]$