介紹Bash以前首先介紹Shell,shell是一個程序,能夠稱之爲殼程序,用於用戶與操做系統進行交互。用來區別與核,至關因而一個命令解析器,Shell有不少中,這裏列出其中幾種 :html
Bourne SHell(sh)node
Bourne Again SHell(bash)linux
C SHell(csh)es6
KornSHell(ksh)shell
各個shell的功能都差不太多,在某些語法的下達下面有些區別,Linux預設就是bash。vim
簡單點說,直接把shell和bash先理解爲一個東西好了,就是Linux中的那個終端窗口(Terminal),也就是那個小黑框,下面的例子都是在Linux的終端窗口中運行的。api
變量
變量賦值bash
基本形式爲變量=變量值,注意等號左右不能有空格,變量均爲文本形式,如;app
var1=World
對於有空格的變量值,用單引號或雙引號包圍,如:socket
var2='abc bcd'
能夠將某個命令輸出的文本直接賦予某個變量,命令須要反引號包圍,如:
var3=`date`
變量之間能夠賦值,須要使用$符號說明是變量,如:
var4=$var1
可使用read關鍵字接收數據至某個變量,如:
read name
變量引用
變量引用是指將變量翻譯爲變量中存儲的文本,基本形式爲$變量。
經過echo命令顯示變量,如:
echo $var3
2019年 11月 10日 星期日 19:12:55 CST
經過echo顯示時,能夠直接與附加文本相連,如:
echo Hello$var1
HelloWorld
當附加文本尾隨變量名形成歧義時,添加大括號,如;
echo ${var4}IsGood
WorldIsGood
能夠在雙引號內使用變量,但在單引號內只能被看成文本,如:
echo "Hello $var1"
Hello World
echo 'Hello $var1'
Hello $var1
數學運算
在bash中,數字和運算符均被看成文本,數學運算需藉助雙大括號$(()):
result=$((1+2)) echo $result
3
支持的運算符有:加+、減-,乘*,除/,求餘%,乘方**,其中乘方的優先級最高,示例:
echo $((2+5*2**(5-3)/2))
返回代碼
在Linux中,每一個可執行程序運行完後會有一個整數的返回值,可使用$?變量來接收,對於簡單的foo.c程序:
int main(void) { int a=1; return 0; }
使用gcc編譯器編譯,並執行:
gcc foo.c ./a.out echo $
0
若是程序運行異常,將返回非0值,如刪除一個不存在的文件:
rm none_exist.file
rm: cannot remove 'none_exist.file': No such file or directory
echo $?
1
在執行多條指令時,可讓後一個程序的運行參考前一個程序的返回代碼,如:
首先新建一個文件並查看確認:
touch demo.file; ls
成功刪除的狀況,使用&&符號鏈接:
rm demo.file && echo "rm succeed"
rm succeed
不成功刪除的狀況,使用||符號鏈接:
rm demo.file || echo "rm failed"
rm: cannot remove 'demo.file': No such file or directory rm failed
bash腳本
腳本示例
使用vim編輯器編輯test.sh文件,內容以下:
#!/bin/bash echo "Information of xxpcb's computer:" > log # 顯示CPU相關信息 echo "------lscpu---------------------" >> log lscpu >> log # 顯示Linux系統詳情(unix name) echo "------uname -a------------------" >> log uname -a >> log # 顯示內存使用狀況 echo "------free -h-------------------" >> log free -h >> log
該文件的做用是將一些計算機信息保存到所在目錄的log文件中。
使用sh test.sh執行bash腳本。
使用cat log命令查看log文件信息:
Information of xxpcb's computer: ------lscpu--------------------- Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 4 On-line CPU(s) list: 0-3 Thread(s) per core: 1 Core(s) per socket: 4 Socket(s): 1 NUMA node(s): 1 Vendor ID: GenuineIntel CPU family: 6 Model: 60 Model name: Intel(R) Core(TM) i5-4590 CPU @ 3.30GHz Stepping: 3 CPU MHz: 1512.460 CPU max MHz: 3700.0000 CPU min MHz: 800.0000 BogoMIPS: 6596.30 Virtualization: VT-x L1d cache: 32K L1i cache: 32K L2 cache: 256K L3 cache: 6144K NUMA node0 CPU(s): 0-3 Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt dtherm ida arat pln pts md_clear flush_l1d ------uname -a------------------ Linux deeplearning 5.0.0-29-generic #31~18.04.1-Ubuntu SMP Thu Sep 12 18:29:21 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux ------free -h------------------- total used free shared buff/cache available Mem: 15G 939M 12G 29M 2.2G 14G Swap: 11G 0B 11G
能夠看出CPU型號:i5-4590 CPU,Linux版本:Ubuntu18.04,內存容量:15G。
## 腳本參數
bash腳本在運行時,也能夠攜帶參數,在腳本中經過變量的形式接收,如test_arg.sh內容以下:
#!/bin/bash echo $0 echo $1 echo $2
其中$0是命令的第一部分,$1纔是第一個參數,如運行:
./test_arg.sh hello world
./test_arg.sh hello world
利用傳入的參數能夠令腳本的使用更加靈活,對於上面的test.sh文件,可使用參數指定保存的文件:
#!/bin/bash echo "Information of xxpcb's computer:" > $1 # 顯示CPU相關信息 echo "------lscpu---------------------" >> $1 lscpu >> $1 # 顯示Linux系統詳情(unix name) echo "------uname -a------------------" >> $1 uname -a >> $1 # 顯示內存使用狀況 echo "------free -h-------------------" >> $1 free -h >> $1
在執行時,能夠指定將信息輸出到output.file文件:
sh test.sh output.file
腳本的返回值
與可執行程序相似,腳本也能夠有返回值,按照慣例正常狀況返回0,在腳本末尾使用exit命令設置返回值,如hello_world.sh:
#!/bin/bash echo Hello echo World exit 0
注意,末尾手動添加exit 0並沒必要要,腳本正常運行其實會自動返回代碼0。執行示例:
sh hello_world.sh
Hello World
echo $?
0
注意,若是在腳本中間出現exit,則腳本提早退出,並返回該exit命令給出的代碼值。
函數
腳本中也可使用相似函數的結構,而且一樣可使用傳入的參數:
#!/bin/bash # 定義函數my_info function my_info() { lscpu >> $1 uname -a >> $1 free -h >> $1 } # 函數調用 my_info output.file
注意:函數定義時,關鍵字function和大括號{}爲函數提示,於是能夠省略function關鍵字。
跨腳本調用
使用source命令能夠實現函數的跨腳本調用。source命令的做用是在同一個進程中執行另外一個文件中的bash腳本。
例若有my_info.sh(內容如上)和app.sh:
#!/bin/bash source my_info.sh my_info output.file
運行app.h,執行到source命令所在行時,就會執行my_info.sh腳本。所以在app.h中使用my_info函數。
注:
/bin/sh與/bin/bash的細微區別(參考:http://www.javashuo.com/article/p-dmoqdoxb-ca.html)
在shell腳本的開頭每每有一句話來定義使用哪一種sh解釋器來解釋腳本。
目前研發送測的shell腳本中主要有如下兩種方式:
#!/bin/sh
值得注意的是:
sh通常設成bash的軟鏈
在通常的linux系統當中(如redhat),使用sh調用執行腳本至關於打開了bash的POSIX標準模
因此,sh跟bash的區別,實際上就是bash有沒有開啓posix模式的區別