天天看點

Linux下shell程式設計基礎整理

變量定義和使用等基礎、指令代換,算數代換、轉義字元、單雙引号等

條件判别式

分支:if、case

循環:while、for

指令行參數:位置參數和特殊變量、輸入輸出、重定向

函數

shell腳本調試

正規表達式

grep、find

sed、awk基礎

在C語言中使用正則

以上整理總結

(友善refer)

$變量名

:取變量的值

${變量名}

:取變量的值,這個更安全,推薦這個,用大括号的

$(指令)

:取指令執行結果

$((變量名))

:對變量執行算數運算 =

$[]

  • 一些基礎、shell腳本的建立和啟動
    Linux下shell程式設計基礎整理
    Linux下shell程式設計基礎整理
    Linux下shell程式設計基礎整理

== 跟做第一遍筆記(20200406 follow 黑馬程式員 linux shell課程

變量定義和使用

學習一門新語言要掌握的内容及順序:

shell 文法:

  • 資料類型:隻有一種,就是字元串string
  • 變量:全局變量,局部變量

    如VAR=10,直接定義變量名就行了,不需要類型修飾符修飾,提一嘴這個10并不是整數而是一個字元串,另外shell中變量名等于變量值的等号左右是沒有空格的,不允許有空格否則會被

  • 控制語句:if、else、switch case、for、while…
  • 函數:
  • 面向對象程式設計:如何實作繼承、重載、封裝、多态… shell不支援面向對象
  • 架構:這邊先pass

加$表示取變量名的值,比如

env | grep $ VAR

會找出環境變量中有10的變量

export 變量名

:将本地變量導出為環境變量

unset

删除已定義的環境變量或本地變量

Linux下shell程式設計基礎整理

檔案名替換(Globbing) —— 通配符:

“*” 比對0個或多個任意字元

“?” 比對一個任意字元

" [若幹字元] "比對方括号中任意一個字元的一次出現

指令代換

由" ’ "反引号括起來的也是一條指令,shell先執行該指令,然後将輸出結果立刻代換到目前指令行中

sasha$ DATE = 'date'
sasha$ echo $DATE
           

就定義一個變量存放date指令的輸出

指令代換也可以用$()表示

$變量名

:取變量的值

${變量名}

:取變量的值,這個更安全,推薦這個,用大括号的

$(指令)

:取指令執行結果

$((變量名))

:對變量執行算數運算 =

$[]

算數代換:

$(())

用于算數計算,(())中的shell變量取值将轉換成整數,同樣含義的

$[]

等價,

$[base#n]

:base表示進制,n按照base進制解釋,但後面再有運算符那個數按十進制解釋

轉義字元:

如 \,反斜杠

輸出是$PATH,本來 $ PATH的意思是取PATH變量的值,但是因為在轉移字元後面是以就直接變成一個單純的$

Linux下shell程式設計基礎整理
Linux下shell程式設計基礎整理

單引号,雙引号:

都是用來擴字元串的,但是雙引号可以将字元串變量展開,而單引号不能,用單引号括起來的字元串變量不管裡面再放$還是再放{},都還是當作字元串輸出,并不會取值什麼的

shell腳本文法

條件判别表達式,真是0,假是1

Linux下shell程式設計基礎整理
echo $?
#檢視上一條指令傳回的結果
           
Linux下shell程式設計基礎整理

-eq 等于, -gt 大于, -lt小于,-ge大于等于,-le小于等于 (隻能用在整數之間),非數字就用[

注意一下[就是一個符号,不能在[後面緊挨着數

檔案類型判别符:-d目錄檔案,-f普通檔案,-p管道,-l軟連接配接,-c字元裝置,-s socket

字元串判别是否為空:-z 為空,-n不空

判斷是否相等:!=不等,=相等

邏輯與或非:👇

Linux下shell程式設計基礎整理

示例:👇👇👇,

Linux下shell程式設計基礎整理

分支語句 if /case

  • if語句
    Linux下shell程式設計基礎整理
    ok的,寫到shell檔案中看看
    Linux下shell程式設計基礎整理
    Linux下shell程式設計基礎整理
    寫shell檔案
    Linux下shell程式設計基礎整理

    然後儲存退出,給檔案授權,然後運作就可

    else和elif的話就直接正常加就可

    Linux下shell程式設計基礎整理
    例子:其中read指令是等待使用者輸入字元串,這個指令去接收
    Linux下shell程式設計基礎整理
    Linux下shell程式設計基礎整理
  • case語句:兩個分号表示break
    Linux下shell程式設計基礎整理
    例子:
    Linux下shell程式設計基礎整理

起個伺服器?…d檔案表示它是一個守護程序?想讓守護程序運作的話就得讓他執行起來……配置檔案對應一個可執行程式……

對于一個伺服器的啟動和停止在檔案中用的就是case語句,start)了怎麼樣,stop)了怎麼樣,reload)了怎麼樣,restart)了怎麼樣,編寫shell腳本管理伺服器就是這個意思

循環

  • for /do/ done

    shell中的for是周遊👇,

    Linux下shell程式設計基礎整理
  • while /do /done

    例子:在有限次數内将密碼輸對,有限次數就設定一個COUNTER,每做一次循環就加1,

    COUNTER = $ ((COUNTER+1))

    Linux下shell程式設計基礎整理
    執行個體👇
    Linux下shell程式設計基礎整理
    定義一個計數,讀鍵盤輸入的密碼,開始循環,循環條件是密碼不正确并且輸入次數在3次之内,循環内語句提示資訊并再次讀取密碼
#! /bin.bash
COUNTER= 1;
echo "輸入密碼:"
read passwd
while[passwd != "123456" a COUNTER-lt 3]; do
	echo "再試一次:"
	read passwd
	COUNTER = $[COUNTER+1]
done
           

注意while内循環使用用[]括起來的,不是(),并且[]結束要加;

小于是lt,小于等于是le

  • break 和continue

    continue和C中無差別,就是跳過本次循環,break和C中的差別是在shell中break可以指定跳出幾層循環,用break[n]

指令行參數

位置參數和特殊變量

Linux下shell程式設計基礎整理

輸入輸出:

  • echo

    -n不換行; -e解析轉義符; 預設是換一行

  • 管道:通過一個 | 把一個指令的輸出傳遞給另一個指令做輸入
  • tee:把結果輸出到标準輸出,另一個副本輸出到相應檔案
    Linux下shell程式設計基礎整理
    就是向螢幕輸出一份,向檔案輸出一份,就是多了個副本

檔案重定向

Linux下shell程式設計基礎整理

cmd就是輸出的一個指令,2是标準出錯,

cmd>file 2>&1

之後,使用者是看不到報錯資訊的,它把資訊存到指定的檔案中了,舉例:

rm abcdefg.mp3>errfile 2>&1

删除失敗的話會将錯誤資訊放到檔案中

cmd<file1>file2

:cat從file1讀向file2發送,file1成了cat的标準輸入

函數

函數名(){函數體} 這樣就ok了,不需要參數也沒有傳回值,小括号表示這是一個函數,大括号裡面就是函數體

Linux下shell程式設計基礎整理

關于傳參: 函數名 參數1參數2 參數3……

Linux下shell程式設計基礎整理

執行個體:

Linux下shell程式設計基礎整理

is_directory是函數名,第一行

DIR_NAME = $1

是将傳入的第一個參數保留下來,

$1

是表示傳入的參數

for開始那一行是函數調用,前面的就是函數定義,在執行這個腳本的時候是直接跳過定義直接到調用這邊的。

看for循環,先周遊參數,然後調用函數,其中

$DIR

就是傳入的參數,$1傳給DIR_NAME,判斷是不是目錄……

shell腳本調試

Linux下shell程式設計基礎整理

-x比較常用,通篇調試可以在運作腳本的時候指令行中提供參數

$ sh -x ./script.sh

或者直接在shell腳本第一行

#!/bin/sh

後直接加上-x成為

#!/bin/sh -x

,選擇區塊調試 就将要調試的代碼用

set -x 代碼塊 set +x

括起來,

set -x

表示啟動-x參數,另一個表示禁用

-n可用于檢查文法上的錯誤

正規表達式

1. 基礎了解正規表達式

Linux下shell程式設計基礎整理
Linux下shell程式設計基礎整理
Linux下shell程式設計基礎整理

2. 基本文法

Linux下shell程式設計基礎整理
Linux下shell程式設計基礎整理

. 比對一個字元

*比對多個字元

[]指定範圍内的字元

^除[]内的字元外

-在[]内表示範圍

{N}精确比對N次前一串,{N,}至少比對N次,{,M}緊跟前面的單元至多比對M次,{N,M}至少N次最多M次

== 再次注意grep找的是包含某一模式的行,而不是完全比對某一模式的行==

Linux下shell程式設計基礎整理

^表示開頭,$表示結尾

<單詞開頭, >單詞結尾

\b單詞開頭或結尾,\B非單詞開頭或結尾

Linux下shell程式設計基礎整理

3,Basic和Extend正則的差別:

Basic的?+[]{}表示普通字元,如果要表達特殊含義要加轉義符

**4,其他符号:**待補充,用到再說,現在看了也記不住的

grep, find

grep

Linux下shell程式設計基礎整理
  • grep格式及主要參數
    Linux下shell程式設計基礎整理
    Linux下shell程式設計基礎整理

    用grep的話要對{}進行轉義,當然是grep -E就不用了

    例子👇👇

    Linux下shell程式設計基礎整理
    表示在目前檔案下查找有"8.8.8.8"的檔案行,

    -r

    表示在目前位置進行遞歸查詢,找到了就把檔案名傳回出來,下一行

    -h

    表示不顯示檔案名,

    -l

    -n

    同理用法
    Linux下shell程式設計基礎整理
    Linux下shell程式設計基礎整理

find

Linux下shell程式設計基礎整理
Linux下shell程式設計基礎整理

-maxdepth

确定搜尋的層級,因為find預設是遞歸搜尋

管道在find中不生效,用exec指令

Linux下shell程式設計基礎整理

-ok

可以了解為互動版的exec

Linux下shell程式設計基礎整理

★★★關于**

-xargs

**

Linux下shell程式設計基礎整理

基本是與find指令一起使用的,用來處理find出來的檔案,這個功能其實exec也能實作,但是exec是将find出來的所有指令一次性進行處理,但是有些系統可能不支援這麼長的參數,是以用xargs來進行分批處理。

xargs可以和管道一起使用

有一個小trick:find指令找出來的是一個結果集,xargs是根據結果集中的空格來區分一個個結果的,是以萬一有一個結果中内部有一個空格,xargs可能就會将一個結果讀成兩個結果産生錯誤,這時候我們就需要手動的改一個替代空格的結果結束标記 ,用到了

print

,可以這麼寫

find ./ -type -print0 | xargs -0 ls -lh {} \;

,但是print後面不能随便改數字比如改成1這是不允許的,就是隻能用

print0

sed, awk

sed

跟vi使用差不多:在vi下查找用

/xxx

,替換

:%s/xxx/yyyy

(查找xxx替換成yyyy,但是這個是隻替換首行中的xxx),如果想替換所有的xxx,就要

:%s/xxx/yyyy/g

g表示全局,如果替換要限制範圍

:13,24s/xxx/yyyy/g

(看來vi也得去系統學一下)

回到sed:

Linux下shell程式設計基礎整理

sed是預設将目前檔案讀出來放到緩沖區中,原來的檔案是不改變的,靜默輸出不顯示執行結果要是再傳回原檔案去看會發現其實檔案是沒有變化的

加參數

-i

就會成為直接修改源檔案,經過腳本指令處理後的内容将被輸出至源檔案,要慎用,

例子:👇s/the/this/,最後一個斜杠是終止符,不要忘了,s表示是替換,在test.txt中将所有the替換成this

sed 's/the/this/' test.txt

Linux下shell程式設計基礎整理

丢丢補充:&就是選出來的自己

Linux下shell程式設計基礎整理
Linux下shell程式設計基礎整理
Linux下shell程式設計基礎整理

用這個

sed 's/<[^>]*>//g' myregex.html

小小筆記:

Linux下shell程式設計基礎整理

awk

sed是更改行,awk更改列

Linux下shell程式設計基礎整理

例子👇:根據庫存量确定是否要補貨

Linux下shell程式設計基礎整理

注意:awk後面是用單引号括起來的,是以在單引号裡面要用雙引号

input | awk 'pattern{action}'
#或者是
awk 'pattern{action}'sh檔案
           

加BEGIN和END的例子:

Linux下shell程式設計基礎整理

分隔符除了

awk 'BEGIN {FS = ":'}{print $1;} /etc/passwd

之外還可以

sudo awk -F: '{print}' /etc/password

-F是awk設定分隔符的參數,參數值是冒号

内建變量:像shell的環境變量一樣,有些awk變量是預定義的,是有特殊含義的

awk常用的内建變量有:

Linux下shell程式設計基礎整理
Linux下shell程式設計基礎整理

在C語言中使用正則

C語言中使用正規表達式常用的函數有

regcomp()、regexec()、regfree()、regerror()

一般分為三個步驟:

編譯正規表達式 regcomp() 、 比對正規表達式 regexec() 、 釋放正規表達式 regfree()

  1. 在C或C++中不能直接把 shell的正則表示給編譯器,編譯器隻會把正規表達式看成是特殊字元,是以我們需要将正規表達式表示成C文法能夠識别的内容,考慮到結構體struct,因為正規表達式有可能比較複雜,而結構體可以表示所有的複雜資料類型,是以在在C或C++中執行比對語句之前先要把正規表達式做一個編譯,把正規表達式編譯成C或者C++認識的資料形式,就用到了

    regcomp()

    :(當然相應頭檔案是不能忘的,要用的時候man一下吧
    Linux下shell程式設計基礎整理
  2. regexec()

    -regmatch_t是一個結構體資料類型
    Linux下shell程式設計基礎整理
  3. regfree()

    Linux下shell程式設計基礎整理
    #### 執行個體👇👇👇
#include<sys/types.h>
#include<regex.h>
#include<stdio.h>

int main(int argc, char** argv)
{
	if(argc!=3){
		printf("Usage: %s RegexString Text\n",argv[0]);
		return 1;
	}
	const char* pregexstr = argv[1];//正規表達式
	const char* ptext = argvv[2]; //待比對的字元串
	regex_t oregex;//編譯後的結構體
	int nerrcode = 0;
	char szerrmsg[1024] = {0};//儲存錯誤資訊的數組
	size_t unerrmsglen = 0;
	
	if((nerrcode = regcomp(&oregex, pregexstr,REG_EXTEND|REG_NPSUB)) == 0)//編譯正規表達式
	{
		if(nerrcode = regexec(&oregex, ptext, 0, NULL,0)) == 0)//執行比對
		{
			printf("%s matched %s\n",ptext, pregexstr);
			return 0;
		}
	}
	//如果比對失敗
	unerrmsglen = regerror(nerrcode, &oregex, szerrmsg,sizeof(szerrmsg)-1;//編譯錯誤,存到szerrmsg中錯誤描述
	unerrmsglen = unerrmsglen<sizeof(szerrmsg)?unerrmsglen:sizeof(szerrmsg)-1;//錯誤資訊較長情況
	szerrmsg[unerrmsglen] = '\0';
	printf("Regex error MSG: %s \n",szerrmsg);
}

regfree(&oregex);
return 1;//非正常退出
           

儲存之後編譯一下

make regex

然後輸入參數運作:

./regex "正規表達式" "待比對的字元串"

以上整理總結

嗯……まだあした…ハハハハハ