Bash Shell 小試牛刀
一、終端打印
[[email protected] ~]# echo welcome to bash!
welcome to bash!
[[email protected] ~]$ echo ‘welcome to bash!‘
welcome to bash!
[[email protected] ~]$ echo "welcome to bash\!"
welcome to bash\!
(註意,雙引號內不能直接用特殊符號,需要用轉義符\)
[[email protected] ~]$ printf "hello world"
hello world
#!/bin/bash
#filename:printf.sh
printf "%-5s %-10s %-4s\n" no name mark
printf "%-5s %-10s %-4.2f\n" 1 sarath 80.3456
printf "%-5s %-10s %-4.2f\n" 2 james 90.9989
printf "%-5s %-10s %-4.2f\n" 3 jeff 77.564
得到如下結果
[[email protected] shell]$ sh printf.sh
no name mark
1 sarath 80.35
2 james 91.00
3 jeff 77.56
1.工作原理
%s ,%c,%d和%f都是格式替換符,其所對應的參數可以置於帶引號的格式字符串之後。
%-5s指明格式為左對齊且寬度為5的字符串替換,不夠的用空格補上。
對於%-4.2f,其中.2指定保留2個小數位。
2.補充內容
(1)在echo中轉義換行符
[[email protected] shell]$ echo -e "1\t2\t3"
1 2 3
(2)打印彩色輸出
重置=0,黑色=30,紅色=31,綠色=32,黃色=33,藍色=34,洋紅=35,青色=36,白色
打印彩色文本
[[email protected] shell]$ echo -e "\e[1;31m this is red text \e[0m"
this is red text
設置彩色背景,重置=0,黑色=40,紅色=41,綠色=42,黃色=43,藍色=44,洋紅=45,青色=46,白色=47
二、玩轉變量和環境變量
在bash中,每一個變量的值都是字符串。無論你給變量賦值時有沒有引號,值都是以字符串形式存在。有一些特殊的變量會被shell環境和操作系統環境用來存儲一些特別的值,這類變量就稱為環境變量。
Cat /proc/$PID/environ(查看運行時的環境變量)
例子:
[[email protected] shell]$ pgrep mysql
11029
11313
[[email protected] shell]$ sudo cat /proc/11313/environ
TERM=xtermOLDPWD=/application/mysqlPATH=/sbin:/usr/sbin:/bin:/usr/bin:/application/mysql/binPWD=/application/mysqlSHLVL=3MYSQL_HOME=/application/mysql_=/usr/bin/nohup
[[email protected] shell]$ sudo cat /proc/11313/environ |tr ‘\0‘ ‘\n‘
TERM=xterm
OLDPWD=/application/mysql
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/application/mysql/bin
PWD=/application/mysql
SHLVL=3
MYSQL_HOME=/application/mysql
_=/usr/bin/nohup
1.實戰演練
[[email protected] shell]$ var=value
[[email protected] shell]$ echo $var
value
Variable.sh代碼如下:
#!/bin/bash
fruit=apple
count=5
echo "we have $count $fruit(s)"
[[email protected] shell]$ sh variable.sh
we have 5 apple(s)
Export命令就是用來設置環境變量:
[[email protected] shell]$ echo $PATH
/application/mysql/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/application/xtrabackup/bin:/home/cairui/bin
[[email protected] shell]$ export PATH="$PATH:/home/cairui"
[[email protected] shell]$ echo $PATH
/application/mysql/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/application/xtrabackup/bin:/home/cairui/bin:/home/cairui
2.補充內容
length=${#var}
例如:
[[email protected] shell]$ vai=1234567890
[[email protected] shell]$ echo ${#vai}
10
三、使用函數添加環境變量
PATH=/usr/bin;/bin
這意味著只要shell需要執行二進制可執行文件時,它會首先查找/usr/bin,然後是/bin
四、使用shell進行數學運算
在bash shell環境中,可以利用let,[],(())執行基本的算術操作。而在進行高級操作時,expr和bc這兩個工具也會非常有用。
1.實例
#!/bin/bash
#filename:jia.sh
no1=4;
no2=5;
let result=no1+no2
echo $result
[[email protected] shell]$ sh jia.sh
9
自加操作
let no1++
自減操作
let no1--
簡寫形式
let no+=6
let no-=6
它們分別等於let no=no+6和let no=no-6
(2)bc是一個數學高級工具,這個精密計算器包含了大量的選項。
[[email protected] ~]# echo "4*8"|bc
32
no=54
result=’echo “$no*1.5”|bc’
echo $result
81.0
l 設定小數精度。下面,參數scale=2將小數位個數設置為2.
[[email protected] shell]$ echo "scale=2;3/8"|bc
.37
進制轉換。用bc可以將一種進制系統轉換為另一種。(10進制轉換2進制)
#!/bin/bash
#用途:數字轉換
no=100
echo "obase=2;$no" |bc
no=1100100
echo "obase=10;ibase=2;$no" |bc
[[email protected] shell]$ sh shuzizhuanhuan.sh
1100100
100
l 計算平方及平方根
[[email protected] shell]$ echo "sqrt(100)"|bc
10
[[email protected] shell]$ echo "10^10"|bc
10000000000
五、玩轉文件描述符及重定向
文件描述符是與文件輸入、輸出相關聯的整數。它們用來跟蹤已打開的文件。最常見的文件描述符是stdin(標準輸入)、stdout(標準輸出)和stderr(標準錯誤)。
0-----stdin
1-----stdout
2-----stderr
1.實例
[[email protected] shell]$ echo "this is a sample text " >temp.txt
[[email protected] shell]$ cat temp.txt
this is a sample text
[[email protected] shell]$ echo "this is a sample text " >>temp.txt
[[email protected] shell]$ cat temp.txt
this is a sample text
this is a sample text
當命令出現錯誤時,錯誤信息就會被打印出來
[[email protected] shell]$ ls +
ls: cannot access +: No such file or directory(錯誤信息)
2.工作原理
>等同於1>;對於>>也是等同於1>>
(1)將文件重定向到命令
cmd < file
(2)將腳本內部的文本塊進行重定向
#!/bin/bash
cat<<EOF>log.txt
LOG FILE HEADER
this is a test log
function:system statistics
EOF
[[email protected] shell]$ sh log-txt.sh
[[email protected] shell]$ cat log.txt
LOG FILE HEADER
this is a test log
function:system statistics
六、數組和關聯數組
array_var=(1 2 3 4 5 6)#這些值將會存儲在以0為起始索引的連續位置上
另外還可以將數組定義為一組“索引-值”
array_var[0]=”test1”
array_var[1]=”test2”
......
......
......
......
array_var[5]=”test6”
echo $array_var[0]
test1
echo $array_var[*]
test1 test2 test3 test4 test5 test6
打印數組長度
echo ${#array_var[*]}
6
七、使用別名
(1)可以用以下方式創建一個別名
alias new_command=’command sequence’
(2)上述別名只是暫時的。為了使別名永久生效,可以將它放在~/.bashrc文件中
echo ‘alias cmd=”commadn seq”’ >> ~/.bashrc
(3)刪除別名,只需要從~/.bashrc中刪除就可以了
八、獲取終端信息
tput和stty是兩款終端處理工具。
1.實例
l 獲取終端的行數和列數:
tput cols
tput lines
l 打印當前終端名:
tput longname
l 將光標移動到坐標(100,100)處:
tput cup 100 100
l 設置終端背景色:
tputsetb n
其中,n可以在0到7之間取值
l 設置文本樣式為粗體
tput bold
l 設置下劃線的起止:
tput smu1
tput rmu1
l 刪除從當前光標位置到行尾的所有內容:
tputed
l 在輸入密碼時,不應該顯示輸入內容:
#!/bin/bash
#filename:password.sh
echo -e “enter password:”
stty -echo
read password
stty echo
echo
echo password read
九、獲取、設置日期和延遲
很多程序要以不同的格式打印日期、設置日期和時間、根據日期和時間執行操作。延時通常用於在程序執行過程中提供一段等待時間(比如1秒)。例如需要在腳本中對某項任務每隔5秒監視一次,就需要知道如何在程序中加入延時。
1.實例
(1)[[email protected] support-files]$ date
Tue Jun 6 15:27:22 CST 2017
(2)打印紀元時:
[[email protected] support-files]$ date +%s
1496734094
[[email protected] support-files]$ date --date "jan 20 2011" +%A
Thursday
(3)用格式串結合+作為date命令的參數:
[[email protected] support-files]$ date "+%d %b %y"
06 Jun 17
(4)設置時間和日期:
date -s “格式化的日期字符串”
例子:
date -s “21 june 2009 11:01:22”
(5)有時,我們需要檢查一組命令所花費的時間,以下代碼:
#!/bin/bash
#filename:time_take.sh
start=$(date +%s)
commands;
statements;
end=$(date +%s)
difference=$((end - start))
echo time taken to execute commands is $difference seconds
2.工作原理
日期內容 |
格式 |
星期 |
%a(A) |
月 |
%b(B) |
日 |
%d |
固定格式日期(mm、dd、yy) |
%D |
年 |
%y(Y) |
小時 |
%I或%H |
分鐘 |
%M |
秒 |
%S |
納秒 |
%N |
Unix紀元時(以秒為單位) |
%s |
|
|
3.補充內容
在腳本中推遲執行一段時間,可以用sleep;$sleep no_of_seconds.例如,下面的腳本就使用tput和sleep從0開始計數到40:
#!/bin/bash
#filename:sleep.sh
echo -n Count: (echo -n不換行輸出)
tput sc
count=0;
while true;
do
if [ $count -lt 40 ];
then
let count++;
sleep 1;
tput rc
tput ed
echo -n $count;
else exit 0;
fi
done
在上面的例子中,變量count初始化為0,隨後每循環一次便加1.echo語句打印出count的值。用tput sc存儲光標的位置。在每次循環中,通過恢復之前存儲的光標的位置,在終端中打印出新的count的值。恢復光標的命令是tput rc。tput ed清除從當前光標位置到行尾之間的所有內容,使得舊的count值可以被清除並寫入新值。循環內的1秒鐘延遲是通過sleep命令來實現。
十、調試腳本
(1)bash -x script.sh or sh -x script.sh
(2)使用set -x和set +x對腳本進行部分調試。例如:
#!/bin/bash
#filename:debug.sh
for i in {1..6};
do
set -x
echo $i
set +x
done
echo "script executed"
[[email protected] shell]$ sh debug.sh
+ echo 1
1
+ set +x
+ echo 2
2
+ set +x
+ echo 3
3
+ set +x
+ echo 4
4
+ set +x
+ echo 5
5
+ set +x
+ echo 6
6
+ set +x
script executed
在上面的腳本中,只會打印出 echo $i的調試信息。因為使用了-x和+x對調試區域進行了限制。
(3)前面兩種調試都是內建的。他們通常以固定的格式生成調試信息。但是在很多情況下,我們需要以自定義格式顯示調試信息。可以通過傳遞_DEBUG環境變量來建立這類調試風格。
#!/bin/bash
function DEBUG()
{
[ "$_DEBUG" == "on" ] && $@ || :
}
for i in {1..10}
do
DEBUG echo $i
done
~
[[email protected] shell]# _DEBUG=on ./DEBUG.sh
1
2
3
4
5
6
7
8
9
10
我們在每一個需要打印調試信息的語句前加上DEBUG。如果沒有把_DEBUG=on傳遞給腳本,那麽調試信息就不會被打印出來。在bash中,命令“:”告訴shell不要進行任何操作。
十一、函數和參數
1.實例
我們可以創建執行特定任務的函數,也可以創建能夠接受參數的函數。
(1)定義函數:
function fname()
{
statements;
}
或者
fname()
{
statements;
}
(2)只需要使用函數名就可以調用某個函數:
$fname #執行函數
(3)參數可以傳遞給函數,並由腳本進行訪問:
fname arg1 arg2;#傳遞函數
以下是函數fname 的定義。在函數fname中,包含了各種訪問函數參數的方法。
fname()
{
echo $1,$2;訪問參數1和參數2
echo [email protected];以列表的方式一次性打印所有參數
echo “$*”;類似於¥@,但是參數被作為單個實體
return 0;返回值
}
l $1是第一個參數
l $2是第二個參數
l $n是第n個參數
l [email protected]$1” “$2” “$3”等
l “$*”被擴展成”$1c$2c$3”,其中c是IFS的第一個字符
l [email protected]要比$*用的多。
2.補充內容
(1)遞歸函數
f() {echo $1;f hello;sleep 1;}
(2)導出函數
export -f fname
十二、不適用回車鍵來讀取n個字符
read是一個重要的bash命令,它用於從鍵盤或標準輸入中讀取文本。我們可以使用read以交互的形式讀取來自用戶的輸入,不過read能做的可遠遠不止於此。任何編程語言的輸入庫大多都是從鍵盤讀取輸入;但只有當回車鍵按下的時候,才標誌著輸入完畢。而有些遊戲裏只需要按q就能釋放技能。
(1)下面的語句從輸入中讀取n個字符並存入變量variable_name;
read -n number_of_chars variable_name
例如:
read -n 2 var
echo $var
(2)用無回顯的方式讀取密碼:
read -s var
(3)顯示提示信息:
read -p “enter input:” var
(4)在特定時限內讀取輸入:
read -t timeout var
read -t 2 var #在2秒內將鍵入的字符串讀入變量var
(5)用特定的定界符作為輸入行的結束:
read -d delim_char var
read -d “:” var
hello:#var 被設置為hello
十三、運行命令直至執行成功
在日常工作中使用shell時,有時候命令只有滿足某些條件或是某種外部事件(例如文件可以被下載)操作才能成功執行。這種情況下,你可能希望重復執行命令,直到成功為止。
1.實例:
按照以下方式定義函數:
repeat()
{
while true
do
$@ && return
done
}
或者把它放入shell的rc文件,更便於使用:
repeat() {while true;do $@ && return;done}
2.工作原理
我們創建了函數repeat,它包含了一個無限while循環,該循環執行以參數形式(通過$@訪問)傳入函數的命令。如果命令執行成功,則返回,進而無限循環。
3.補充內容
(1)一種更快的做法
repeat() {while :; do $@ && return; done } 比第一種方法快
(2)增加延時
repeat wget -c ........
repeat() {while :; do $@ && return; sleep 30; done}這使得命令每30秒運行一次。
十四、循環
(1)for循環
for var in list;
do
commands;
done
(2)while循環
while condition
do
commands;
done
(3)until循環
它會一直循環,直到給定的條件為真。
x=0;
until [ $x -eq 9 ];
do
let x++; echo $x;
done
十五、比較與測試
1.實戰
(1)if條件
if condition;
then
commands;
fi
(2)else if和else
if condition;
then
commands;
else if condition; then
commands;
else
commands;
fi
(3)算數比較
l 對變量或值進行算數條件判斷:
[ $var -eq 0 ] #當$var等於0時,返回真
[ $var -ne 0 ] #當。。。為非0時,返回真
l -gt:大於
l -lt:小於
l -ge:大於或等於
l -le:小於或等於
(4)字符串比較
使用字符串比較時,最好用雙中括號,因為有時候采用單個中括號會產生錯誤,所以最好避開它們。
l [[$str1=$str2]],相等返回真
l [[$str1==$str2]]檢查字符串是否相等的另一種寫法
l [[$str1 !=$str2]]如果str1和str2不相同,則返回真
l [[$str1 > $str2]]
l [[$str1 < $str2]]
l [[-z $str1]],如果包含的是空字符串,返回真
l [[-n $str]],如果包含的是非空字符串,則返回真
Bash Shell 小試牛刀