Shell Script
目錄
建立指令碼
在建立shell指令碼檔案時,必須在檔案的第一行指定要使用的shell。通常井號(#)用作註釋行,但第一行是個例外
#!/bin/bash
# This script displays the date and who's logged on
date
who
指令碼儲存在名為test1的檔案中,在直接執行指令碼時會出現下面問題:
$ test1
bash: test1: command not found
你要跨過的第一個障礙是讓bash shell能找到你的指令碼檔案,只需採取以下三種作法之一:
- 將shell指令碼檔案所處的目錄新增到PATH環境變數中;
$ PATH=$PATH:.
$ test1
- 作為直譯器引數:直接執行直譯器,其引數就是 shell 指令碼的檔名
/bin/bash test.sh
這種方式執行的指令碼,不需要在第一行指定直譯器資訊,寫了也沒用。
- 在提示符中用絕對或相對檔案路徑來引用shell指令碼檔案(需要修改許可權)
我們採用第二種方式將指令碼檔案的確切位置告訴shell。為了引用當前目錄下的檔案,可以在shell中使用單點操作符。
$ ./test1
bash: ./test1: Permission denied
$
現在shell找到了指令碼檔案,但還有一個問題。shell指明瞭你還沒有執行檔案的許可權。下一步是通過chmod命令賦予檔案屬主執行檔案的許可權
$ chmod u+x test1
$ ./test1
Mon Feb 21 15:38:19 EST 2014
Christine tty2 2014-02-21 15:26
Samantha tty3 2014-02-21 15:26
Timothy tty1 2014-02-21 15:26
user tty7 2014-02-19 14:03 (:0)
user pts/0 2014-02-21 15:21 (:0.0) $
顯示訊息
在echo命令後面加上了一個字串,該命令就能顯示出這個文字字串。echo命令可用單引號或雙引號來劃定文字字串
$ echo This is a test
This is a test
$ echo Let's see if this'll work
Lets see if thisll work
$ echo "This is a test to see if you're paying attention"
This is a test to see if you're paying attention
$ echo 'Rich says "scripting is easy".'
Rich says "scripting is easy".
在指令碼執行中,但如果想把文字字串和命令輸出顯示在同一行中,可以用echo語句的-n引數。
#!/bin/bash
echo -n "The time and date are: "date
$ ./test1
The time and date are: Mon Feb 21 15:42:23 EST 2014
變數
-
建立變數
除了環境變數,shell指令碼還允許在指令碼中定義和使用自己的變數。使用等號將值賦給使用者變數。在變數、等號和值之間不能出現空格。shell指令碼會自動決定變數值的資料型別
var1=10
var2=-57
var3=testing
var4="still more testing"
使用一個定義過的變數,只要在變數名前面加美元符號即可
-
只讀變數
readonly 命令可以將變數定義為只讀變數,只讀變數的值不能被改變,也不能被刪
$ readonly var1=10
$ var=11
-bash: var: 只讀變數
-
刪除變數
$ unset var
-bash: unset: var: 無法反設定: 只讀 variable
$ unset var1
$ echo $var1
$
-
命令替換
從命令輸出中提取資訊,並將其賦給變數,$()格式命令輸出賦給變數。shell會執行命令替換符號中的命令,並將其輸出賦給變數testing
$ testing=$(date)
下面例子中,在指令碼中通過命令替換獲得當前日期並用它來生成唯一檔名 。today變數是被賦予格式化後的date命令的輸出。+%y%m%d格式告訴date命令將日期顯示為兩位數的年月日的組合。
#!/bin/bash
# copy the /usr/bin directory listing to a log file
today=$(date +%y%m%d)
ls /usr/bin -al > log.$today
$ date +%y%m%d
140131
$
重定向輸入和輸出
-
輸出重定向
最基本的重定向將命令的輸出傳送到一個檔案中。bash shell用大於號(>)來完成這項功能:
command > outputfile
之前顯示器上出現的命令輸出會被儲存到指定的輸出檔案中。如果輸出檔案已經存在了,重定向操作符會用新的檔案資料覆蓋已有檔案。
$ date > test6
$ ls -l test6
-rw-r--r-- 1 user user 29 Feb 10 17:56 test6
$ cat test6
Thu Feb 10 17:56:58 EDT 2014
$
雙大於號(>>)命令將輸出追加到已有檔案中
-
輸入重定向
輸入重定向符號是小於號(<):
command < inputfile
wc命令可以對對資料中的文字進行計數。預設情況下,它會輸出3個值: 文字的行數; 文字的詞數; 文字的位元組數。
通過將文字檔案重定向到wc命令,你立刻就可以得到檔案中的行、詞和位元組的計數
$ wc < test6
2 11 60
$
還有另外一種輸入重定向的方法,稱為內聯輸入重定向。這種方法無需使用檔案進行重定向,只需要在命令列中指定用於輸入重定向的資料就可以了。
內聯輸入重定向符號是遠小於號(<<)。除了這個符號,你必須指定一個文字標記來劃分輸入資料的開始和結尾。任何字串都可作為文字標記,但在資料的開始和結尾文字標記必須一致。
command << marker #marker為文字標記符
data #data為輸入給command的資料
marker
在命令列上使用內聯輸入重定向時,shell會用PS2環境變數中定義的次提示符來提示輸入資料。
$ wc << EOF
> test string 1
> test string 2
> test string 3
> EOF
3 9 42
$
管道
有時需要將一個命令的輸出作為另一個命令的輸入。這可以用重定向來實現,只是有些笨拙。通過標準輸出重定向,rpm命令的輸出被重定向到了檔案 rpm.list。命令完成後,rpm.list儲存著系統中所有已安裝的軟體包列表。接下來,輸入重定向將rpm.list檔案的內容傳送給sort命令,該命令按字母順序對軟體包名稱進行排序。
$ rpm -qa > rpm.list
$ sort < rpm.list
abrt-1.1.14-1.fc14.i686
abrt-addon-ccpp-1.1.14-1.fc14.i686
abrt-addon-kerneloops-1.1.14-1.fc14.i686
abrt-addon-python-1.1.14-1.fc14.i686
acl-2.2.49-8.fc14.i686
[...]
我們用不著將命令輸出重定向到檔案中,可以將其直接重定向到另一個命令。這個過程叫作管道連線。在第一個命令產生輸出的同時,輸出會被立即送給第二個命令。資料傳輸不會用到任何中間檔案或緩衝區。
command1 | command2
$ rpm -qa | sort
abrt-1.1.14-1.fc14.i686
abrt-addon-ccpp-1.1.14-1.fc14.i686
abrt-addon-kerneloops-1.1.14-1.fc14.i686
abrt-addon-python-1.1.14-1.fc14.i686
acl-2.2.49-8.fc14.i686
[...]
可以在一條命令中使用任意多條管道
$ rpm -qa | sort | more
可以搭配使用重定向和管道來將輸出儲存到檔案中
$ rpm -qa | sort > rpm.list
數學運算
-
方括號
在bash中,在將一個數學運算結果賦給某個變數時,可以用美元符和方括號($[ operation ])將數學表示式圍起來。bash shell數學運算子只支援整數運算
$ var1=$[1 + 5]
$ echo $var1
6
$ var2=$[$var1 * 2]
$ echo $var2
12
$
-
浮點解決方案
內建的bash計算器,叫作bc。要退出bash計算器,你必須輸入quit
$ bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
12*0.5
6.0
quit
$
浮點運算是由內建變數scale控制的。scale變數的預設值是0。在scale值被設定前,bash計算器的計算結果不包含小數位。在將其值設定成4後,bash計算器顯示的結果包含四位小數。-q命令列選項可以不顯示bash計算器冗長的歡迎資訊。
$ bc -q
3.44 / 5
0
scale=4
3.44 / 5
.6880
quit
$
除了普通數字,bash計算器還能支援變數。
$ bc -q
var1=10
var1 * 4
40
quit
$
在指令碼中使用bc
variable=$(echo "options; expression" | bc)
第一部分options允許你設定變數。如果你需要不止一個變數,可以用分號將其分開。expression引數定義了通過bc執行的數學表示式。
$ cat test9
#!/bin/bash
var1=$(echo "scale=4; 3.44 / 5" | bc)
echo The answer is $var1
$ chmod u+x test9
$ ./test9
The answer is .6880
退出指令碼
shell中執行的每個命令都使用退出狀態碼(exit status)告訴shell它已經執行完畢。退出狀態碼是一個0~255的整數值,在命令結束執行時由命令傳給shell。可以捕獲這個值並在指令碼中使用。Linux提供了一個專門的變數$?來儲存上個已執行命令的退出狀態碼。
0 | 命令成功結束 | $ date Sat Jan 15 10:01:30 EDT 2014 $ echo $? 0 |
1 | 一般性未知錯誤(是給某個命令提供了無效引數) | $ date %t date: invalid date '%t' $ echo $? 1 $ |
2 | 不適合的shell命令 | |
126 | 命令不可執行(沒有許可權) | $ ./myprog.c -bash: ./myprog.c: Permission denied $ echo $? 126 $ |
127 | 沒找到命令 | $ asdfg -bash: asdfg: command not found $ echo $? 127 |
128 | 無效的退出引數 | |
130 | 通過Ctrl+C終止的命令 | |
255 | 正常範圍之外的退出狀態碼 |
預設情況下,shell指令碼會以指令碼中的最後一個命令的退出狀態碼退出。exit命令允許你在指令碼結束時指定一個退出狀態碼。可以在exit命令的引數中使用變數.
$ cat test13
#!/bin/bash
# testing the exit status
var1=10
var2=30
var3=$[$var1 + $var2]
echo The answer is $var3
exit 5
$ chmod u+x test13
$ ./test13
The answer is 40
$ echo $?
5
$
相關文章
- shell script
- shell script的簡單使用
- shell script程式設計小結——附帶例項程式設計
- [20201112]centos 7 rc.local shell script on systemd while booting Linux system.tCentOSWhilebootLinux
- 請說說`<script>`、`<script async>`和`<script defer>`的區別
- Script
- Elasticsearch script sort 排序Elasticsearch排序
- npm script中&&和&NPM
- MySQL Server Startup ScriptMySqlServer
- JavaScript <script>標籤JavaScript
- IDM-Activation-Script
- 熟悉的< script >標籤
- JS 之 script標籤JS
- 淺談script標籤
- IE報錯SCRIPT5011:不能執行已釋放Script的程式碼
- java Script 的if判斷2Java
- [20181219]script使用小技巧.txt
- MySQL5.7: sql script demoMySql
- vue3 script setup 定稿Vue
- Shell:子shell概念
- Script標籤的async和defer
- Flask系列教程(26)——Flask-ScriptFlask
- Script of Narrative Writing from different point of viewView
- Java Script網頁設計案例Java網頁
- [20180321]toad下execute as script的fetch
- gradle中的build script詳解GradleUI
- 解釋nginx.conf.default 中關於fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;NginxAST
- 解決 "Script Error" 的另類思路Error
- PostgreSQL DBA(148) - pgAdmin(Show script for psql command)SQL
- script標籤中的async和defer
- FastCGI sent in stderr: "Primary script unknown" 報錯AST
- C#指令碼引擎CS-ScriptC#指令碼
- FindBugs Security JSP 無法識別 jsp 頁面<script>jstl</script>程式碼中的 xss 漏洞問題JS
- shell——shell輸入輸出
- Shell程式設計-11-子Shell和Shell巢狀程式設計巢狀
- Shell
- 說一說 HTML 中的 script 標籤HTML
- Nodejs 呼叫 R 指令碼 / Nodejs Call R ScriptNodeJS指令碼