Shell基礎快速入門 瞭解shell運行原理

来源:https://www.cnblogs.com/gavinpan/archive/2019/07/25/11236006.html
-Advertisement-
Play Games

Shell簡介 Shell 是一個用 C 語言編寫的程式,它是用戶使用 Linux 的橋梁。Shell 既是一種命令語言,又是一種程式設計語言。 Shell 是指一種應用程式,這個應用程式提供了一個界面,用戶通過這個界面訪問操作系統內核的服務。 Ken Thompson 的 sh 是第一種 Unix ...


Shell簡介

Shell 是一個用 C 語言編寫的程式,它是用戶使用 Linux 的橋梁。Shell 既是一種命令語言,又是一種程式設計語言。

Shell 是指一種應用程式,這個應用程式提供了一個界面,用戶通過這個界面訪問操作系統內核的服務。

Ken Thompson 的 sh 是第一種 Unix Shell,Windows Explorer 是一個典型的圖形界面 Shell。

Shell運行原理

Linux嚴格意義上是一個操作系統,我們稱為核心,但我們一般的用戶是不能直接使用核心的,而是通過外殼程式。也就是shell,對比Windows,圖形界面就是外殼程式。shell的簡單定義就是命令行解釋器,功能是將使用者的命令翻譯給核心處理,同時將核心處理的結果翻譯給使用者。可以看出shell主要是對我們的指令進行解析,解析指令給Linux內核。反饋結果在通過內核運行出結果,通過shell解析給用戶。

shell在解釋命令的時候並不是自己親自執行,而是派生子進程讓子進程去完成這項工作,這樣的好處是把風險交給別人,當指令的執行出現問題時不會影響到shell(影響到其他指令的執行)。shell不可以掛,shell 一旦掛就沒有什麼可以解釋命令了。對我們而言shell為了保證自己風險最低,通過創建子進程進行命令行的解釋工作。而shell自己只要去等就可以了。

Shell 腳本

Shell 腳本(shell script),是一種為 shell 編寫的腳本程式。 業界所說的 shell 通常都是指 shell 腳本,但讀者朋友要知道,shell 和 shell script 是兩個不同的概念。

Shell腳本解釋器

Linux的Shell腳本解釋器種類眾多,一個系統可以存在多個shell腳本解釋器,可以通過cat /etc/shells 命令查看系統中安裝的shell腳本解釋器。

/bin/sh

/bin/bash

/bin/rbash

bash由於易用和免費,在日常工作中被廣泛使用。同時,Bash也是大多數Linux系統預設的Shell腳本解釋器。

shell腳本頭,#!/bin/sh與#!/bin/bash的區別.

GNU/Linux操作系統中的/bin/sh本是bash (Bourne-Again Shell)的符號鏈接,但鑒於bash過於複雜,有人把bash從NetBSD移植到Linux並更名為dash Debian Almquist Shell),並建議將/bin/sh指向它(軟鏈),以獲得更快的腳本執行速度。Dash Shell 比Bash Shell小的多,符合POSIX標準。

sh一般設成bash的軟鏈
在一般的linux系統當中(如redhat),使用sh調用執行腳本相當於打開了bash的POSIX標準模式
也就是說 /bin/sh 相當於 /bin/bash --posix
sh跟bash的區別,實際上就是bash有沒有開啟posix模式的區別

第一個shell腳本

新建一個文件 test.sh,擴展名為 sh(sh代表shell),擴展名並不影響腳本執行,見名知意就好。

運行 Shell 腳本有兩種方法:

1、作為可執行程式

cd 到相應目錄:

chmod +x ./test.sh #使腳本具有執行許可權 ./test.sh #執行腳本

註意,一定要寫成 ./test.sh,而不是 test.sh,運行其它二進位的程式也一樣,直接寫 test.sh,linux 系統會去 PATH 里尋找有沒有叫 test.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,你的當前目錄通常不在 PATH 里,所以寫成 test.sh 是會找不到命令的,要用 ./test.sh 告訴系統說,就在當前目錄找。

2、作為解釋器參數

這種運行方式是,直接運行解釋器,其參數就是 shell 腳本的文件名,如:

/bin/sh test.sh

Shell變數

語法規則:變數名=變數值 my_name="Gavin Pan"

註意,變數名和等號之間不能有空格,這可能和你熟悉的所有編程語言都不一樣。同時,變數名的命名規則與其他語言差不多,不能使用bash里的關鍵字(可用help命令查看保留關鍵字)。

1.變數類型

局部變數:局部變數在腳本或命令中定義,僅在當前shell實例中有效,其他shell啟動的程式不能訪問局部變數。

環境變數:所有的程式,包括shell啟動的程式,都能訪問環境變數,有些程 序需要環境變數來保證其正常運行。可以用過set命令查看當前環境變數。

shell變數:由shell程式設置的特殊變數。shell變數中有一部分是環境變數,有一部分是局部變數,這些變數保證了shell 的正常運行。

2.定義變數

my_name="Gavin Pan"

3.引用變數

echo $my_name
echo ${my_name}
#引用一個定義過的變數,只要在變數名前面加$即可,變數名外面的花括弧是可選的,加不加都行,加花括弧是為了幫助解釋器識別變數的邊界。

4.重新定義變數

my_name = "Gavin"

my_name="Gavin Pan"

5.只讀變數

使用readonly 命令將變數變成只讀變數

my_name = "Gavin"
readonly my_name
my_name="Gavin Pan"

6.刪除變數

my_name="Gavin"
unset my_name
echo $my_name

使用unset命令可以刪除變數,變數被刪除後不能再次使用,同時unset命令不能刪除只讀變數。

Shell字元串

字元串是shell編程中最常用最有用的數據類型(除了數字和字元串,也沒啥其它類型好用了),字元串可以用單引號,也可以用雙引號,也可以不用引號。單雙引號的區別跟PHP類似。

str1='hello Gavin'
str2="hello Gavin"
str3="hello \"$my_name\"
echo str1 #hello Gavin
echo str2 #hello Gavin
echo str3 #hello "Gavin Pan"

雙引號的優點:可以有變數,可以轉義字元。

字元串相關操作

#拼接字元串
a="a"
b="b"
c=$a$b 或者 c="$a $b"
獲取字元串長度
str="abcdefg"
echo ${#str} #output 7
提取字元串
echo ${str:1:3} #output bcd
以上例子表示從字元串的第二個數字往後截取3個字元
查找字元串
echo `expr index "$str" cb` #output 2
註意: 以上腳本中 ` 是反引號,而不是單引號 ',不要看錯了哦。
查找字元 c 或 b 的位置(哪個字母先出現就計算哪個)

shell 數組

在 Shell 中,用括弧來表示數組,數組元素用"空格"符號分割開。定義數組的一般形式為: 數組名=(值1 值2 ... 值n) 例如:

array_name=(value0 value1 value2 value3)
或者
array_name=(
value0
value1
value2
value3
)
還可以單獨定義數組的各個分量:
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen

可以不使用連續的下標,而且下標的範圍沒有限制。 讀取數組 讀取數組元素值的一般格式是: ${數組名[下標]} 例如:

valuen=${array_name[n]}
使用 @ 符號可以獲取數組中的所有元素,例如:
echo ${array_name[@]}
獲取數組的長度
獲取數組長度的方法與獲取字元串長度的方法相同,例如:
取得數組元素的個數
length=${#array_name[@]}
或者
length=${#array_name[*]}
取得數組單個元素的長度
lengthn=${#array_name[n]}

shell參數傳遞

echo "Shell 傳遞參數實例!";
echo "執行的文件名:$0";
echo "第一個參數為:$1";
echo "第二個參數為:$2";
echo "第三個參數為:$3";
執行結果如下
$ chmod +x test.sh 
$ ./test.sh 1 2 3
Shell 傳遞參數實例!
執行的文件名:./test.sh
第一個參數為:1
第二個參數為:2
第三個參數為:3

shell特殊字元

$# 傳遞到腳本的參數個數 $* 以一個單字元串顯示所有向腳本傳遞的參數 $$ 腳本運行的當前進程ID號 $! 後臺運行的最後一個進程的ID號 $@ 與$*相同,但是使用時加引號,併在引號中返回每個參數 $? 顯示最後命令的退出狀態。0表示沒有錯誤,其他任何值表明有錯誤

$*和$@區別: 相同點:都表示傳遞給腳本的所有參數。 不同點:不被” “包含時,$和$@都以$1 $2… $n 的形式組成參數列表。 被” “包含時,”$” 會將所有的參數作為一個整體,以”$1 $2 … $n” 的形式組成一個整串;”$@” 會將各個參數分開,以”$1” “$2” … “$n” 的 形式組成一個參數列表。

shell 基本運算符

算數運算符

原生bash不支持簡單的數學運算,但是可以通過其他命令來實現,例如 awk 和 expr,expr 最常用。

expr 是一款表達式計算工具,使用它能完成表達式的求值操作。

a=1
b=2
val=`expr $a + $b`

需要註意的是運算符左右要有空格,特殊記住乘號前面要叫\,其他的沒什麼區別。

關係運算符

關係運算符只支持數字,不支持字元串,除非字元串的值是數字。

-eq 檢測兩個數是否相等,相等返回 true。 [ $a -eq $b ] 返回 false。 -ne 檢測兩個數是否不相等,不相等返回 true。 [ $a -ne $b ] 返回 true。 -gt 檢測左邊的數是否大於右邊的,如果是,則返回 true。 [ $a -gt $b ] 返回 false。 -lt 檢測左邊的數是否小於右邊的,如果是,則返回 true。 [ $a -lt $b ] 返回 true。 -ge 檢測左邊的數是否大於等於右邊的,如果是,則返回 true。 [ $a -ge $b ] 返回 false。 -le 檢測左邊的數是否小於等於右邊的,如果是,則返回 true。 [ $a -le $b ] 返回 true。

布爾運算符

! 非運算,表達式為 true 則返回 false,否則返回 true。 [ ! false ] 返回 true。 -o 或運算,有一個表達式為 true 則返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。 -a 與運算,兩個表達式都為 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。

邏輯運算符

&& 邏輯的 AND [[ $a -lt 100 && $b -gt 100 ]] 返回 false || 邏輯的 OR [[ $a -lt 100 || $b -gt 100 ]] 返回 true

字元串運算符

= 檢測兩個字元串是否相等,相等返回 true。 [ $a = $b ] 返回 false。 != 檢測兩個字元串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。 -z 檢測字元串長度是否為0,為0返回 true。 [ -z $a ] 返回 false。 -n 檢測字元串長度是否為0,不為0返回 true。 [ -n "$a" ] 返回 true。 $ 檢測字元串是否為空,不為空返回 true。 [ $a ] 返回 true。

a="abc"
b="efg"

if [ $a = $b ]
then
   echo "$a = $b : a 等於 b"
else
   echo "$a = $b: a 不等於 b"
fi
if [ $a != $b ]
then
   echo "$a != $b : a 不等於 b"
else
   echo "$a != $b: a 等於 b"
fi
if [ -z $a ]
then
   echo "-z $a : 字元串長度為 0"
else
   echo "-z $a : 字元串長度不為 0"
fi
if [ -n "$a" ]
then
   echo "-n $a : 字元串長度不為 0"
else
   echo "-n $a : 字元串長度為 0"
fi
if [ $a ]
then
   echo "$a : 字元串不為空"
else
   echo "$a : 字元串為空"
fi

執行腳本,輸出結果如下所示:

abc = efg: a 不等於 b
abc != efg : a 不等於 b
-z abc : 字元串長度不為 0
-n abc : 字元串長度不為 0
abc : 字元串不為空

文件測試運算符

-b file 檢測文件是否是塊設備文件,如果是,則返回 true。 [ -b $file ] 返回 false。 -c file 檢測文件是否是字元設備文件,如果是,則返回 true。 [ -c $file ] 返回 false。 -d file 檢測文件是否是目錄,如果是,則返回 true。 [ -d $file ] 返回 false。 -f file 檢測文件是否是普通文件(既不是目錄,也不是設備文件),如果是,則返回 true。 [ -f $file ] 返回 true。 -g file 檢測文件是否設置了 SGID 位,如果是,則返回 true。 [ -g $file ] 返回 false。 -k file 檢測文件是否設置了粘著位(Sticky Bit),如果是,則返回 true。 [ -k $file ] 返回 false。 -p file 檢測文件是否是有名管道,如果是,則返回 true。 [ -p $file ] 返回 false。 -u file 檢測文件是否設置了 SUID 位,如果是,則返回 true。 [ -u $file ] 返回 false。 -r file 檢測文件是否可讀,如果是,則返回 true。 [ -r $file ] 返回 true。 -w file 檢測文件是否可寫,如果是,則返回 true。 [ -w $file ] 返回 true。 -x file 檢測文件是否可執行,如果是,則返回 true。 [ -x $file ] 返回 true。 -s file 檢測文件是否為空(文件大小是否大於0),不為空返回 true。 [ -s $file ] 返回 true。 -e file 檢測文件(包括目錄)是否存在,如果是,則返回 true。 [ -e $file ] 返回 true。

file="/test.sh"
if [ -r $file ]

shell 流程式控制制

if condition
then
	command
fi
if condition
then
command
else
commandN
fi
if condition
then
command
elif confition2
then
command2
else
cpmmandN
fi
for loop in 1 2 3 4 5
do
echo $loop
done
while condition
do
command
done
until condition
do
command
done
與while正好相反
echo '輸入 1 到 4 之間的數字:'
echo '你輸入的數字為:'
read aNum
case $aNum in
    1)  echo '你選擇了 1'
    ;;
    2)  echo '你選擇了 2'
    ;;
    3)  echo '你選擇了 3'
    ;;
    4)  echo '你選擇了 4'
    ;;
    *)  echo '你沒有輸入 1 到 4 之間的數字'
    ;;
esac

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 今天,我們宣佈推出 .NET Core 3.0 Preview 7 。我們的工作已經從創建新功能過渡到打磨版本。預計剩餘的預覽版會聚焦在版本質量上。 ...
  • 問題: 部署在Azure環境Web應用程式的JSON文件,直接通過瀏覽器或Web應用訪問出現 404 的錯誤信息。 以下通過Firfox瀏覽器直接訪問JSON文件返回的提示錯誤信息: “HTML 文檔的字元編碼未聲明。如果該文件包含 US-ASCII 範圍之外的字元,該文件將在某些瀏覽器配置中呈現為 ...
  • 打開UBF,新建項目-》實體項目 輸入名稱後,點擊確定,第二步:修改名稱以在後期作為文件夾區分 第三步:創建實體 第四步:添加U9基礎對象引用 拖動到解決方案的Reference 第五步:右鍵構造 ...
  • 一、前言 項目中需要提供一個視頻介紹,使用戶能夠快速、方便的瞭解如何使用產品以及註意事項。 前臺使用Vue+Element UI中的el-upload組件實現視頻上傳及進度條展示,後臺提供視頻上傳API並返回URL。 二、具體實現 1、效果圖展示 2、HTML代碼 3、JS代碼 4、後臺代碼 三、總 ...
  • TCP/IP四層模型分為: 應用層,傳輸層(只關註起點(發送者)和終點(接收者)),網路層(規划出一條或幾條路線),數據鏈路層(關註兩個相鄰點之間怎麼傳輸) 設備驅動程式及 網路介面負責 一、應用層: 1、HTTP協議(主要協議):HTTP是超文本傳輸協議,是當前最流行也是最典型的應用層協議 HTT ...
  • 前言 我在學習WPF的早期,對依賴屬性理解一直都非常的不到位,其惡果就是,我每次在寫依賴屬性的時候,需要翻過去的代碼來複制黏貼。 相信很多朋友有著和我相同的經歷,所以這篇文章希望能幫助到那些剛剛開始學依賴屬性的朋友。 那些[討厭]的依賴屬性的講解文章 初學者肯定會面臨一件事,就是百度,谷歌,或者MS ...
  • 之前我們詳細介紹過分佈視圖(partial view),在有一些更加複雜的場景下,.net core為我們提供了更加強大的組件 view component. 可以認為view component是partial view的替代品。 我認為view component是 .net core中非常重要 ...
  • 用於顯示文件的狀態信息。stat命令的輸出信息比ls命令的輸出信息要更詳細。# stat -L 支持符號鏈接 -f 顯示文件系統狀態而非文件狀態 -t 簡潔模式,只顯示摘要信息 --help 顯示幫助 --version 顯示版本 欄位 說明 例子 ls(-l) st_atime 文件數據的最後存取... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...