shell是乙個命令直譯器,它在作業系統的最外層,負責直接與使用者對話,把使用者的輸入解釋給作業系統,並處理各種各樣的作業系統的輸出結果,輸出到螢幕返回給使用者。這種對話方式可以是互動的方式(從鍵盤輸入命令,可以立即得到shell的回應),或非互動(指令碼的方式)。
當命令或語句不在命令列執行,而是通過乙個程式檔案執行時,該程式就被稱為shell指令碼或shell程式,shell程式類似dos系統下的批處理程式(*.bat)。使用者可以在shell指令碼中敲入一系列的命令或命令語句。這些命令、變數和流程控制語句等有機的結合起來就形成了乙個功能強大的shell指令碼。
有dash和bash兩種,但dash沒有bash功能全面,所以通常使用bash。
可以通過命令來檢視系統中的指令碼直譯器: ls -l /bin/*sh
重點:指令碼開頭的第一行(如果不是第一行,#就是注釋了),指定由哪乙個直譯器來執行指令碼中的檔案如:#!/bin/bash
「#!」 符號是指定乙個檔案型別的特殊標記,它告訴linux系統這個檔案執行的需要指定乙個直譯器。
「#!」 符號後跟的是乙個路徑名,這個路徑名指明了直譯器在系統中的位置。
當shell指令碼執行時,它會先查詢系統環境變數env,該變數指定了環境檔案(載入順序通常是/etc/profile、~ /.bash_profile、~/.bashrc、/etc/bashrc等),在載入了上述環境變數檔案後,shell就開始執行shell指令碼中的內容。(所以在開發的時候,有時候想定義的全域性變數時,可以不在指令碼定義,而在環境變數中定義)
shell指令碼是從上至下、從左至右依次執行每一行的命令及語句的,即執行完了乙個命令後再執行下乙個,如果在shell指令碼中遇到子指令碼(即指令碼巢狀)時,就會先執行子指令碼的內容,完成後再返回父指令碼繼續執行父指令碼內後續的命令及語句。
通常情況下,在執行shell指令碼時,會向系統核心請求啟動乙個新的程序,以便在該程序中執行指令碼的命令及子shell指令碼,基本流程如圖:
shell指令碼的執行通常可以採用以下幾種方式:
1)bash script-name或sh script-name
這是當指令碼檔案本身沒有可執行許可權(即檔案許可權屬性x位為-號)時常使用的方法,或者指令碼檔案開頭沒有指定直譯器時需要使用的方法;
舉例說明:
[root@localhost ~
]# vim test.sh
echo 'this is a shell scripts!'
[root@localhost ~
]# sh test.sh //指定直譯器sh執行。sh是bash的軟連線。推薦用bash方式,防止後面版本公升級後不一樣。
this is a shell scripts!
[root@localhost ~
]# bash test.sh //指定直譯器bash執行。
this is a shell scripts!
2)path/script-name或./script-name指在當前路徑下執行指令碼(指令碼需要有執行許可權),需要將指令碼檔案的許可權先改為可執行(即檔案許可權屬性加x位),具體方法為chmod+x script-name。然後通過指令碼絕對路徑或相對路徑就可以直接執行指令碼了;
舉例說明:
[root@localhost ~
]# .
/test.sh
-bash:
./test.sh: 許可權不夠
[root@localhost ~
]# chmod u+x test.sh
[root@localhost ~
]# .
/test.sh
this is a shell scripts!
這種方法比較麻煩一些!每次編寫完指令碼都必須給指令碼乙個執行的許可權,否則將會提示「許可權不夠」的錯誤。
3)source script-name或.script-name
這種方法通常是使用source或「.」(點號。點號後是空格)讀入或載入指定的shell指令碼檔案(如san.sh),然後,依次執行指定的shell指令碼檔案san.sh中的所有語句。這些語句將在當前父shell指令碼father.sh程序中執行(其他幾種模式都會啟動新的程序執行子指令碼)。因此,使用source或「.」可以將san.sh自身指令碼中的變數值或函式等的返回值傳遞到當前父shell指令碼father.sh中使用。
舉例說明:
重點:通常,當前執行的視窗是乙個shell,執行指令碼的是另乙個shell。
[root@localhost ~
]# echo 'user=`whoami`'
> test2.sh
[root@localhost ~
]# cat test2.sh
user=`whoami`
[root@localhost ~
]# sh test2.sh //用sh或者bash執行,系統會啟動新的程序執行子指令碼,執行完就返回父shell,變數或函式無法保留。
[root@localhost ~
]# echo $user //所以,輸出變數$user 是空
[root@localhost ~
]# . test2.sh //通過source或「.」載入執行過的指令碼,系統不會新建程序執行子shell,都是在當前shell中執行指令碼,因此在指令碼結束之後,指令碼中的變數(包括函式)值在當前shell中依然存在.
[root@localhost ~
]# echo $user //因為執行 user=`whoami`時,變數$user被保留下來了,所以輸出root
root
本人親自嘗試得出的結論有三點:
1.子shell指令碼會直接繼承父shell指令碼的變數、函式(就好像是兒子隨父親姓,基因也會繼承父親的)等,反之則不可以;
2.如果希望反過來繼承(就好像是讓父親隨兒子姓,讓父親的基因也繼承兒子的),就要用source或「.」在父shell指令碼中事先載入子shell指令碼;
3.通過source或「.」載入執行過的指令碼,由於是在當前shell中執行指令碼,因此在指令碼結束之後,指令碼中的變數(包括函式)值在當前shell中依然存在,而sh和bash執行指令碼都會啟動新的子shell執行,執行完後退回到父shell。因此,變數(包括函式)值等無法保留。在進行shell指令碼開發時,如果指令碼中有引用或執行其他指令碼的內容或配置檔案的需求時,最好用「.」或source先載入該指令碼或配置檔案,處理完之後,再將它們載入到指令碼的下面,就可以呼叫source載入的指令碼及配置檔案中的變數及函式等內容了。
4)sh舉例說明:
[root@localhost ~
]# ll test.sh
-rw-r--r--
.1 root root 32
8月 2603:
09 test.sh
[root@localhost ~
]# sh
this is a shell scripts!
[root@localhost ~
]# cat test.sh|bash
this is a shell scripts!
1.指令碼檔案開頭指定指令碼直譯器;
#/bin/sh或#!
/bin/bash
#date: 21:30 2013-07-20
#author: created by guomaoqiu
#mail: [email protected]
#function: this scripts function is ......
#shell version: gnu bash, version 3.2.25(1)-release
3.指令碼檔案中不用中文注釋;
盡量用英文注釋,防止本機或切換系統環境後中文亂碼的困擾.
4.指令碼檔案以.sh為副檔名;
例如:script-name.sh
5.**書寫優秀習慣;
5.1成對內容的一次性寫出來,防止遺漏。如
、、''、``、""
5.2[
]中括號兩端要有空格,書寫時即可留出空格[
],然後再退格書寫內容。
5.3流程控制語句一次性書寫完,再新增內容,如:
#if語句格式一次性完成:
if 條件內容
then
內容fi#for迴圈格式一次性完:
fordo
內容done
case 等語句也是一樣。
6.通過縮排讓**易讀;(即該有空格的地方就要有空格) Shell程式設計以及一些概念
shell解析器 解析shell指令碼,檢視 cat etc shellscentos預設的解析器是 bash 列印系統預設的shell解析器 echo shell shell是什麼是命令,類似windows的dos命令 又是一門程式語言,裡面含有變數 函式 邏輯控制語句等 shell指令碼是什麼s...
Shell學習計畫 Shell 概念篇
shell是運維開發最重要的一項語言!幾乎所有的運維崗位都要求會shell語言,會用shell執行一些簡單的任務,做一些自動化運維相關的工作。shell既是一種命令語言,又是一種程式語言,是使用者使用linux的橋梁。shell是指一種應用程式,這個應用程式提供了乙個介面,使用者通過這個介面訪問作業...
Shell程式設計 shell特性
linux會預設記錄1000條歷史記錄,可通過 echo histsize 檢視,如果講histsize更改為2000,那麼會預設儲存2000條。1000條記錄儲存在家目錄的 bash history 中,僅當使用者正常退出當前shell時,當前shell中執行的命令才會儲存到 bash histo...