Linux實戰教學筆記17:精簡shell基礎

来源:http://www.cnblogs.com/chensiqiqi/archive/2017/02/25/6442373.html
-Advertisement-
Play Games

第十七節 精簡shell基礎 標簽(空格分隔): Linux實戰教學筆記 1,前言 1.1 為什麼學習shell編程 Shell腳本語言是實現Linux/UNIX系統管理及自動化運維所必備的重要工具,Linux/UNIX系統的底層及基礎應用軟體的核心大部分涉及Shell腳本的內容。每一個合格的Lin ...


第十七節 精簡shell基礎

標簽(空格分隔): Linux實戰教學筆記


1,前言

1.1 為什麼學習shell編程

Shell腳本語言是實現Linux/UNIX系統管理及自動化運維所必備的重要工具,Linux/UNIX系統的底層及基礎應用軟體的核心大部分涉及Shell腳本的內容。每一個合格的Linux系統管理員或運維工程師,都需要熟練的編寫Shell腳本語言,並能夠閱讀系統及各類軟體附帶的Shell腳本內容。只有這樣才能提升運維人員的工作效率,適應日益複雜的工作環境,減少不必要的重覆工作,從而為個人的職場發展奠定較好的基礎。

1.2 學好Shell編程所需的基礎知識

  • 能夠熟練使用vim編輯器,熟悉SSH終端
  • 有一定的Linux命令基礎,至少需要掌握80個以上Linux常用命令,並能夠熟練使用它。
  • 要熟練掌握Linux正則表達式及三劍客命令(grep,sed,awk)

1.3 如何學好Shel編程

  • 學好Shel編程的核心:多練-->多思考-->再練-->再思考,堅持如此迴圈即可!
  • 新手大忌:不可拿來主義,可以模仿,但是要自己嚼爛了吃下去,否則會鬧肚子。
  • 格言:你覺得會了並不一定會了,你認為對的並不一定對的。

大家要勤動手,自行完成學習筆記和代碼的書寫。通過每一個小目標培養自己的興趣以及成就感

2,Shell腳本入門

2.1 什麼是Shell

  • Shell是一個命令解釋器,它在操作系統的最外層,負責直接與用戶對話,把用戶的輸入解釋給操作系統,並處理各種各樣的操作系統的輸出結果,輸出屏幕返回給用戶。
  • 這種對話方式可以是:
    1)交互的方式:從鍵盤輸入命令,通過/bin/bash的解釋器,可以立即得到shell的回應
    2)非交互的方式:腳本

下圖黃色部分就是命令解釋器shell

屏幕快照 2017-02-24 下午1.35.04.png-226.5kB

Shell的英文意思是貝殼的意思,命令解釋器Shell像一個貝殼一樣包住系統核心。

Shell執行命令分為兩種方式:

  • 內置命令:如講過的cd,pwd,exit和echo等命令,當用戶登錄系統後,shell以及內置命令就被系統載入記憶體,並且一直運行。
  • 一般命令:如ls,磁碟上的程式文件-->調入-->執行命令

2.2 什麼是Shell 腳本

當linux命令或語句不在命令行下執行(嚴格說,命令行也是shell),而是通過一個程式文件執行時,該程式就被稱為Shell腳本或Shell程式
用戶可以在Shell腳本中敲入一系列的命令及語句組合。這些命令,變數和流程式控制制語句等有機的結合起來就形成一個功能強大的Shell腳本。

首先先帶領大家寫一個清空/var/log/messages日誌的腳本

我們需要先想明白幾個問題:
1)日誌文件在哪?
/var/log/messages
2)用什麼命令可以清空文件?
> 重定向
3)寫一個簡單的shell腳本。

#!/bin/env bash
# -*- coding:utf-8 -*-
# author:Mr.chen

cd /var/log/
>messages

4)怎樣執行腳本?
[root@chensiqi1 ~]# sh /server/scripts/chensiqi.sh

有沒有考慮到:

  • 有沒有腳本放在統一的目錄

/server/scripts目錄下

  • 許可權:用哪個用戶執行文件

需要對用戶做判斷

  • 清空錯文件怎麼辦,該如何辦?

  • 錯誤提示:有沒有成功知不知道?

  • 腳本的通用性

範例:包含命令,變數和流程式控制制的清空/var/log/messages日誌的shell腳本

[root@chensiqi1 ~]# mkdir -p /server/scripts #要有規範的存放腳本目錄
[root@chensiqi1 ~]# vim /server/scripts/chensiqi.sh 
[root@chensiqi1 ~]# cd /server/scripts/
[root@chensiqi1 scripts]# cat /server/scripts/clear_log.sh 
#!/bin/env bash
# -*- coding:utf-8 -*-
# author:Mr.chen

LOG_DIR=/var/log



if [ $UID -ne 0 ]  #root用戶的UID是0
then
    echo "Must be root to run this script"
    exit 1   #退出腳本,返回值1
fi

cd $LOG_DIR 2>/dev/null || {
    echo "Cannot chage to necessary directory."
    exit 1
}     #如果第一個語句執行失敗,那麼執行||後邊的
cat /dev/null > messages && echo "Logs cleaned up." #打開一個空文件然後重定嚮日志文件做為清空處理
exit 0

清空日誌的三種方法:

echo >test.log
>test.log
cat /dev/null >test.log
#清空內容,保留文件

小結:

  • Shell就是命令解釋器。==>翻譯官
  • Shell腳本==>命令放在腳本里

2.3,Shell腳本在運維工作中的作用地位

Shell腳本擅長處理純文本類型的數據,而Linux中幾乎所有的配置文件,日誌文件等都是純文本類型文件。

3,Shell腳本的建立和執行

3.1 Shell腳本的建立

推薦使用vim編輯器編輯腳本,可以事先做個別名。

[root@chensiqi1 scripts]# echo "alias vi=vim">>/etc/profile
[root@chensiqi1 scripts]# source /etc/profile

3.1.1腳本開頭第一行

規範的Shell腳本第一行會指出由哪個程式(解釋器)來執行腳本中的內容。在linux bash編程中一般為:

#!/bin/bash
或
#!/bin/sh

其中開頭的“#!”又稱為幻數,在執行Shell腳本的時候,內核會根據“#!”後的解釋器來確定哪個程式解釋腳本中的內容。註意:這一行必須在每個腳本頂端的第一行,如果不是第一行則為腳本註釋行。

3.1.2 sh和bash的區別

[root@chensiqi1 scripts]# ll /bin/sh
lrwxrwxrwx. 1 root root 4 Dec 23 20:25 /bin/sh -> bash
#sh是bash的軟鏈接,推薦標準寫法#!/bin/bash

可以看一下系統自帶的腳本的寫法

head -1 /etc/init.d/*

3.1.3 bash版本

[root@chensiqi1 scripts]# bash --version
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

3.1.4 bash漏洞【破殼漏洞】

如果是比較老的系統,需要註意shell的版本太低,有漏洞,需要升級shell

[root@chensiqi1 scripts]# yum -y update bash
#驗證方法
[root@chensiqi1 scripts]# env x='(){ :;};echo be careful' bash -c "echo this is a test"
this is a test
如果返回2行
    be careful
    this is a test
這樣的結果的話,請儘快升級

3.1.5 不同語言腳本的開頭寫法

#!/bin/sh
#!/bin/bash
#!/usr/bin/awk
#!/bin/sed
#!/usr/bin/tcl
#!/usr/bin/expect
#!/usr/bin/perl
#!/usr/bin/env python

如果腳本開頭不指定解釋器,就要用對應的解釋器執行腳本。例如bash test.sh和python.test.py

要求:養成一個好習慣,開頭加上相應的解釋器標識。

3.1.6 腳本註釋

在Shell腳本中,跟在#後面的內容表示註釋。註釋部分不會被執行,僅給人看。註釋可以自成一行,也可以跟在命令後面,與命令同行。要養成寫註釋的習慣,方便自己與他人。

最好不用中文註釋,因為在不同字元集的系統會出現亂碼。

3.2 Shell腳本的執行

3.2.1 Shell腳本執行的四種方式

1)bash scripts-name或sh script-name(推薦使用)

這種方法是當腳本本身沒有可執行許可權時常使用的方法。

2)path /script-name 或./scripts-name(全路徑或當前路徑執行腳本)
這種方法首先需要給腳本文件可執行許可權。

3)source scripts-name或. scripts-name #註意“.”點號,且點號後有空格。
source 或.在執行這個腳本的同時,可以將腳本中的函數和變數載入到當前Shell。不會產生子shell。又有點像nginx的include功能。

3.3 Shell腳本開發的規範和習慣

1)開頭指定腳本解釋器
2)開頭加版本版權等信息,可配置~/.vimrc文件自動添加
3)腳本不要用中文註釋,儘量用英文註釋
4)腳本以.sh為擴展名
5)放在統一的目錄
6)代碼書寫優秀習慣
a,成對的內容一次性寫出來,防止遺漏,如[],'',""等
b,[]兩端要有空格,先輸入[]退格,輸入2個空格,再退格寫。
c,
流程式控制制語句一次書寫完,再添加內容。

if 條件
    then
      內容
fi

d,通過縮進讓代碼易讀
f,腳本中的引號都是英文狀態下的引號,其他字元也是英文狀態。

好的習慣可以讓我們避免很多不必要的麻煩,提高工作效率。

4,Shell環境變數

4.1 什麼是變數

變數就是用一個固定的字元串(也可能是字元數字等的組合),替代更多更複雜的內容,這個內容里可能還會包含變數和路徑,字元串等其他內容。變數的定義是存在記憶體中。

x=1
y=2

4.2 變數類型

變數分為兩類:
1)環境變數(也可稱為全局變數);可以在創建他們的Shell及派生出來的子shell中使用。環境變數又可以分為自定義環境變數和bash內置的環境變數。

2)局部變數(普通變數):只能在創建他們的shell函數或shell腳本中使用,還記得前面的$user?我們創建的一般都是普通變數。

4.2.1 環境變數

  • 環境變數用於定義Shell的運行環境,保證Shell命令的正確執行,Shell通過環境變數來確定登錄用戶名,命令路徑,終端類型,登錄目錄等,所有的環境變數都是全局變數,可用於所有子進程中,包括編輯器,shell腳本和各類應用。但crond計劃任務除外,還需要重新定義環境變數。
  • 環境變數可以在命令行中設置,但用戶退出時這些變數值也會丟失,因此最好在用戶家目錄下的.bash_profile文件中或全局配置/etc/bashrc,/etc/profile文件或者/etc/profile.d/目錄中定義。將環境變數放入profile文件中,每次用戶登錄時這些變數值都將被初始化。
  • 通常,所有環境變數均為大寫。環境變數應用於用戶進程前,都應該用export命令導出。例如:export chensiqi=1
  • 有一些環境變數,比如HOME,PATH,SHELL,UID,USER等,在用戶登錄之前就已經被/bin/login程式設置好了。通常環境變數定義並保存在用戶家目錄下的.bash_profile或/etc/profile文件中。
#顯示環境變數
[root@chensiqi1 scripts]# echo $HOME
/root
[root@chensiqi1 scripts]# echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
[root@chensiqi1 scripts]# echo $SHELL
/bin/bash
[root@chensiqi1 scripts]# echo $UID
0
[root@chensiqi1 scripts]# echo $USER
root
[root@chensiqi1 scripts]# env #查看系統環境變數
HOSTNAME=chensiqi1
SELINUX_ROLE_REQUESTED=
TERM=xterm-256color
SHELL=/bin/bash
HISTSIZE=500
SSH_CLIENT=192.168.197.1 49592 22
SELINUX_USE_CURRENT_RANGE=
OLDPWD=/root
SSH_TTY=/dev/pts/1
LC_ALL=C
USER=root
#中間省略部分內容....
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/server/scripts
LANG=zh_CN.UTF-8
SELINUX_LEVEL_REQUESTED=
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
LOGNAME=root
CVS_RSH=ssh
SSH_CONNECTION=192.168.197.1 49592 192.168.197.133 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
G_BROKEN_FILENAMES=1
_=/bin/env
#當前終端變數
[root@chensiqi1 scripts]# echo $PS1
[\u@\h \W]\$

4.2.1 局部變數

定義局部變數

局部變數在用戶當前的shell生存期的腳本中使用。例如,局部變數chensiqi取值為chensiqi098,這個值只在用戶當前shell生存期中有意義。如果在shell中啟動另一個進程或退出,局部變數chensiqi值將無效。

普通字元串變數定義

變數名=value
變數名=‘value’
變數名=“value”

shell中變數名及變數內容的要求

  • 一般是字母,數字,下劃線組成,且以字母開頭。如chensiqi,chensiqi123,chensiqi-training。變數的內容,可以使用單引號或雙引號印起來,或不加引號。

  • 雖然變數可以以下劃線開頭,但類似這種變數都是比較特殊的,都是系統自己用的。我們儘量少用。

[root@chensiqi1 scripts]# _123=eeee
[root@chensiqi1 scripts]# echo $_123
eeee

普通字元串變數定義測試

[root@chensiqi1 scripts]# a=192.168.1.2
[root@chensiqi1 scripts]# b='192.168.1.2'
[root@chensiqi1 scripts]# c="192.168.1.2"
[root@chensiqi1 scripts]# echo "a=$a"
a=192.168.1.2
[root@chensiqi1 scripts]# echo "b=$b"
b=192.168.1.2
[root@chensiqi1 scripts]# echo "c=${c}"
c=192.168.1.2
[root@chensiqi1 scripts]# a=192.168.1.2-$a
[root@chensiqi1 scripts]# b='192.168.1.2-$a'
[root@chensiqi1 scripts]# c="192.168.1.2-$a"
[root@chensiqi1 scripts]# echo "a=$a"
a=192.168.1.2-192.168.1.2
[root@chensiqi1 scripts]# echo "b=$b"
b=192.168.1.2-$a
[root@chensiqi1 scripts]# echo "c=${c}"
c=192.168.1.2-192.168.1.2-192.168.1.2

把一個命令做為變數

[root@chensiqi1 scripts]# ls
chensiqi.sh  clear_log.sh
[root@chensiqi1 scripts]# CMD=`ls`
[root@chensiqi1 scripts]# echo $CMD
chensiqi.sh clear_log.sh
[root@chensiqi1 scripts]# CMD1=$(pwd)
[root@chensiqi1 scripts]# echo $CMD1
/server/scripts
變數名=`ls` <==反引號
變數名=$(ls)

小結:

1)CMD=ls的ls兩側的符號是鍵盤tab鍵上面的,不是單引號。
2)在變數名前加$,可以取得此變數的值,使用echo或printf命令可以顯示變數的值,$A和$(A)寫法不同,效果一樣,推薦後面的寫法。
3)${WEEK}DAY若變數和其他字元組成新的變數就必須給變數加上大括弧{}.
4)養成將所有字元串變數用雙引號括起來使用的習慣,減少編程遇到的怪異錯誤。“$A”和“${A}”

4.3 變數名及變數內容定義小結

  1. 變數名只能由字母,數字,下劃線組成,且以字母開頭。

  2. 規範的變數名寫法定義:見名知意
    a,ChensiqiAge=1 <==每個單詞首字母大寫
    b,chensiqi_age=1 <==每個單詞之間用“-”
    c,chensiqiAgeSex=1 <==駝峰語法:首個單詞字母小寫,其餘單詞首字母大寫

  3. =號的知識,a=1中的等號是賦值的意思,比較是不是相等為“==”
  4. 列印變數,變數名前接$符號,變數名後接字元的時候,要用大括弧括起來

[root@chensiqi1 ~]# word="big"
[root@chensiqi1 ~]# echo ${word}ger
bigger
[root@chensiqi1 ~]# echo $wordger

[root@chensiqi1 ~]# 
  1. 註意變數內容引用方法,一般為雙引號,簡單連續字元可以不加引號,希望原樣輸出,使用單引號。
  2. 變數內容是命令,要用反引號``或者$()把變數括起來使用

5,Shell特殊變數

5.1 位置變數

$0 獲取當前執行的shell腳本的文件名,如果執行腳本帶路徑那麼就包括腳本路徑。

$n 獲取當前執行的shell腳本的第n個參數值,n=1..9,當n為0時表示腳本的文件名,如果n大於9用大括弧括起來{10},參數以空格隔開。

$# 獲取當前執行的shell腳本後面接的參數的總個數
$0 獲取當前執行的shell腳本的文件名,包括路徑
[root@chensiqi1 scripts]# cat chensiqi.sh
#!/bin/bash

echo $0

[root@chensiqi1 scripts]# sh chensiqi.sh 
chensiqi.sh
[root@chensiqi1 ~]# sh /server/scripts/chensiqi.sh 
/server/scripts/chensiqi.sh
#參觀系統腳本使用$0

[root@chensiqi1 ~]# grep -i usage /etc/init.d/crond
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
[root@chensiqi1 ~]# /etc/init.d/crond
Usage: /etc/init.d/crond {start|stop|status|restart|condrestart|try-restart|reload|force-reload}
$n  $1 $2...$n命令腳本後面的參數的內容$1第一個參數$2是第二個參數....
[root@chensiqi1 scripts]# echo \${1..15}
$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
[root@chensiqi1 scripts]# cat chensiqi.sh
#!/bin/bash

echo $0
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}
[root@chensiqi1 scripts]# sh chensiqi.sh {a..z}
chensiqi.sh
a b c d e f g h i j k l m n o
$# 獲取當前shell命令行中參數的總個數,用於判斷傳參的參數個數是否符合要求
[root@chensiqi1 scripts]# cat chensiqi.sh 
#!/bin/bash


echo $0
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}
echo $#
[root@chensiqi1 scripts]# sh chensiqi.sh
chensiqi.sh

0
[root@chensiqi1 scripts]# sh chensiqi.sh ee tt
chensiqi.sh
ee tt
2

5.2 進程狀態變數

$? 獲取執行上一個指令的返回值(0為成功,非零為失敗)
查找方法man bash,然後搜索Special Parameters

5.2.1 $?測試

[root@chensiqi1 scripts]# echo $?
0
[root@chensiqi1 scripts]# cd /rrr
-bash: cd: /rrr: No such file or directory
[root@chensiqi1 scripts]# echo $?
1
$?返回值參考
0 表示運行成功
2 許可權拒絕
1~125 表示運行失敗,腳本命令,系統命令錯誤或參數傳遞錯誤;
126 找到該命令,但無法執行
127 未找到要運行的命令
128 命令被系統強制結束

生產環境:
1)用於判斷命令,腳本或函數等程式是否執行成功。
2)若在腳本中調用執行“exit數字”,則會返回這個數字給“$?”變數
3)如果在函數中使用“return 數字”,則會以函數返回值的形式傳給“$?”.

#!/bin/bash

/etc/init.d/network restart >/dev/null 2>&1
if [ $? -ne 0 ]
then
    echo "Mynetwork is bad!"
    exit 1
fi

6,變數的數值計算

6.1 (())用法(常用於簡單的整數運算)

算數運算符號

運算符 意義
++ -- 增加及減少,可前置也可放在結尾
+ - ! ~ 一元運算的正負號,非,邏輯與位的取反
* / % 乘法,除法,取餘
+ - 加法,減法
< <= > >= 比較符號
== 1+= 相等,不相等
<< >> 向左移動,向右移動
& 位的AND
^ 位的異或
\
&& 位的AND
\ \
?: 條件表達式
= += -= *=等 賦值運算符
** 冪運算

使用方法:

[root@chensiqi1 scripts]# ((a=1+2**3-4%3))
[root@chensiqi1 scripts]# echo $a
8
[root@chensiqi1 scripts]# b=$((1+2**3-4%3))
[root@chensiqi1 scripts]# echo $b
8
[root@chensiqi1 scripts]# echo $((1+2**3-4%3))
8

小結:
1)“(())”在命令行執行時不需要$符號,但是輸出需要$符號
2)“(())”里所有字元之間有無或多個空格沒有任何影響

一個比較繞的知識點:

[root@chensiqi1 scripts]# a=8
[root@chensiqi1 scripts]# echo $a
8
[root@chensiqi1 scripts]# echo $((a+=1))  #相當於a=a+1
9
[root@chensiqi1 scripts]# echo $((a++)) #a在前,先輸出a的值,在加1
9
[root@chensiqi1 scripts]# echo $a
10
[root@chensiqi1 scripts]# echo $((a--))
10
[root@chensiqi1 scripts]# echo $a
9
[root@chensiqi1 scripts]# echo $((++a))
10
[root@chensiqi1 scripts]# echo $a
10
[root@chensiqi1 scripts]# echo $((--a))
9
[root@chensiqi1 scripts]# echo $a
9

記憶方法:++,--

變數a在前,表達式的值為a,然後a自增或自減,變數a在符號後,表達式值自增或自減,然後a值自增或自減。

數值判斷:

[root@chensiqi1 scripts]# echo $((3>2))
1
[root@chensiqi1 scripts]# echo $((3<2))
0

6.2 練習:實現一個計算器

結合前邊的知識:

方法一:

[root@chensiqi1 scripts]# cat calculator.sh 
#!/bin/env bash


echo $(($1))
[root@chensiqi1 scripts]# sh calculator.sh 3+2
5
[root@chensiqi1 scripts]# sh calculator.sh 3**2
9
[root@chensiqi1 scripts]# cat calculator.sh 
#!/bin/env bash


echo $(($1$2$3))
[root@chensiqi1 scripts]# sh calculator.sh 3 - 2
1

方法二:傳參並計算

[root@chensiqi1 scripts]# cat calculator.sh 
#!/bin/env bash

a=6
b=2
echo "a-b =$(($a - $b))"
echo "a+b =$(($a + $b))"
echo "a*b =$(($a * $b))"
echo "a/b =$(($a / $b))"
echo "a**b =$(($a ** $b))"
echo "a%b =$(($a % $b))"
[root@chensiqi1 scripts]# sh calculator.sh 
a-b =4
a+b =8
a*b =12
a/b =3
a**b =36
a%b =0

#傳參數

[root@chensiqi1 scripts]# cat calculator.sh 
#!/bin/env bash

a=$1   #不需要把後面的$a,$b都改
b=$2
echo "a-b =$(($a - $b))"
echo "a+b =$(($a + $b))"
echo "a*b =$(($a * $b))"
echo "a/b =$(($a / $b))"
echo "a**b =$(($a ** $b))"
echo "a%b =$(($a % $b))"

[root@chensiqi1 scripts]# sh calculator.sh 3 8
a-b =-5
a+b =11
a*b =24
a/b =0
a**b =6561
a%b =3

6.2 $[]的用法

[root@chensiqi1 scripts]# echo $[2+3]
5
[root@chensiqi1 scripts]# echo $[2*3]
6

7,腳本中定義變數

7.1 腳本中直接賦值

[root@chensiqi1 scripts]# cat calculator.sh 
#!/bin/env bash

a=6
b=2
echo "a-b =$(($a - $b))"
echo "a+b =$(($a + $b))"
echo "a*b =$(($a * $b))"
echo "a/b =$(($a / $b))"
echo "a**b =$(($a ** $b))"
echo "a%b =$(($a % $b))"

7.2 命令行傳參

[root@chensiqi1 scripts]# cat calculator.sh 
#!/bin/env bash

a=$1   #不需要把後面的$a,$b都改
b=$2
echo "a-b =$(($a - $b))"
echo "a+b =$(($a + $b))"
echo "a*b =$(($a * $b))"
echo "a/b =$(($a / $b))"
echo "a**b =$(($a ** $b))"
echo "a%b =$(($a % $b))"

8,條件測試

什麼是條件測試呢?
簡單理解,判斷某些條件是否成立,成立執行一種命令,不成立執行另外一種命令。

8.1 條件測試語法

格式:[ <測試表達式> ] 大家要掌握著一種,註意測試表達式兩邊要留空格

8.2 測試表達式

好習慣:先敲一對[],然後退格輸入2個空格[],最後再回退一個空格開始輸入[ -f file ]

[root@chensiqi1 ~]# [ -f /etc/hosts ] && echo 1 || echo
1
[root@chensiqi1 ~]# [ -f /etc/hosts1 ] && echo 1 || echo 0
0
[root@chensiqi1 ~]# [ ! -f /etc/hosts1 ] && echo 1 || echo 0
1
#在做測試判斷時,不一定用上面的方法,用下麵的寫一半方法更簡潔
[root@chensiqi1 ~]# [ -f /etc/hosts ] && echo 1
1
[root@chensiqi1 ~]# [ -f /etc/hosts1 ] || echo 0
0
#系統腳本
[root@chensiqi1 ~]# vi /etc/init.d/nfs
....
    [ -x /usr/sbin/rpc.nfsd ] || exit 5
    [ -x /usr/sbin/rpc.mountd ] || exit 5
    [ -x /usr/sbin/exportfs ] || exit 5

8.3 常用文件測試操作符號

常用文件測試操作符號 說明
-f文件,英文file 文件存在且為普通文件則真,即測試表達式成立
-d文件,英文directory 文件存在且為目錄文件則真,即測試表達式成立
-s文件,英文size 文件存在且文件大小不為0則真,即測試表達式成立。
-e文件,英文exist 文件存在則真,即測試表達式成立。只要有文件就行,區別-f
-r文件,英文read 文件存在且可讀則真,即測試表達式成立
-w文件,英文write 文件存在且可寫則真,即測試表達式成立
-x文件,英文executable 文件存在且可執行則真,即測試表達式成立。
-L文件,英文link 文件存在且為鏈接文件則真,即測試表達式成立
f1 -nt f2,英文newer than 文件f1比文件f2新則真,即測試表達式成立,根據文件修改時間計算。
f1 -ot f2,英文older than 文件f1比文件f2舊則真,即測試表達式成立,根據文件修改時間計算

8.4 字元串測試操作符

字元串測試操作符的作用:比較兩個字元串是否相同,字元串長度是否為零,字元串是否為NULL。Bash區分零長度字元串和空字元串。
|常用字元串測試操作符|說明|
|--|--|
|-z "字元串"|若串長度為0則真,-z理解為zero|
|-n “字元串”|若串長度不為0則真,-n理解為no zero|
|“串1”=“串2”|若串1等於串2則真,可以使用“==”代替“=”|
|“串1”!="串2"|若串1不等於串2則真,但不能使用“!==”代替“!=”|

特別註意,以上表格中的字元串測試操作符號務必要用“”引起來。[ -z "$string"]字元串比較,比較符號兩端最好有空格,參考系統腳本。

[ "$password" = "john" ]

提示:
[,"password",=,"join",]之間必須存在空格
[root@chensiqi1 ~]# sed -n '30,31p' /etc/init.d/network
# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 6

8.5 整數二元比較操作符

在[]中使用的比較符 說明
-eq equal等於
-ne not equal不等於
-gt greater than大於
-ge greater equal大於等於
-lt less than小於
-le less equal小於等於

在[]中可以用>和<,但需要用\轉義,雖然不報錯,但結果不對。但還是不要混用!

8.6 邏輯操作符

在[]中使用的邏輯操作符 說明
-a 與and,兩端都為真則真
-o 或or,有一個真就真
非not,相反則為真

小結:
1)多個[]之間的邏輯操作符是&&或||
2)&&前面成功執行後面
3)||前面不成功執行後面

8.7 其他

有的時候用[]比if要簡單

[ -f "$file" ] && echo 1 || echo 0
if [ -f "file" ];then echo 1;else echo 0;fi

9,if條件語句

9.1 if單分支條件語句

if [ 條件 ]
    then
        指令
fi
或
if [ 條件 ];then
    指令
fi

提示:分號相當於命令換行,上面兩種語法等同

特殊寫法:if [ -f "$file1" ];then echo 1;fi
相當於[-f "$file1" ] && echo 1

9.1.1 輸入2個數字,比較大小

#!/bin/bash

#no1
if [ $# -ne 2 ]
        then
                echo "USAGE $0 num1 num2"
                exit 1
fi
a=$1
b=$2
if [ $a -lt $b ];then
        echo "yes,$a less than $b"
        exit
fi
if [ $a -eq $b ];then
        echo "yes,$a equal $b"
        exit
fi
if [ $a -gt $b ];then
        echo "yes,$a greater than $b"
        exit
fi

9.1.2 如果/server2/scripts下麵有if3.sh就輸出if3.sh到屏幕,如果沒有自動創建

[root@chensiqi1 scripts]# cat chensiqi.sh
#!/bin/bash

path=/server2/scripts
file=if3.sh
if [ ! -d $path ]
    then
        mkdir -p $path
        echo "directory is not exsist!"
fi
if [ ! -f $path/$file ]
    then
        touch $path/$file
        echo "file is not exsist!"
    else
        echo "file is exsist!"
fi

9.2 if 雙分支條件語句

if [ 條件 ]
    then
        指令
    else
        指令
fi
特殊寫法:if [ -f "$file1" ];then echo 1;else echo 0;fi
相當於[ -f "file1" ] && echo 1 ||echo 0

9.2.1 如果/server2/scripts下麵有if3.sh就輸出if3.sh到屏幕,如果沒有就自動創建

[root@chensiqi1 scripts]# cat chensiqi.sh 
#!/bin/bash

file=/server2/scripts/if3.sh
path=`dirname $file`

if [ -f $file ];then
    cat $file
    exit 0
else
    if [ ! -d $path ];then
        mkdir -p $path
        echo "$path is not exist,already created it."
        echo "1234" >> $file
    fi
    if [! -f $file ];then
        echo "1234" >> $file
        echo "$file is not exist,already created it."
    fi
fi

9.3 多分支if語句

if [ 條件1 ];then
    指令1
elif [ 條件2 ];then
    指令2
elif [ 條件3 ];then
    指令3
elif [ 條件4 ];then
    指令4
else
    指令n
fi

9.3.1 判斷兩個整數大小

[root@chensiqi1 scripts]# cat chensiqi.sh 
#!/bin/bash

if [ $# -ne 2 ];then
    echo "USAGE $0 num1 num2"
    exit 1
else
    num1=`echo $1 | sed 's#[0-9]##g'`
    num2=`echo $2 | sed 's#[0-9]##g'`
fi


if [ ${#num1} -eq 0 -a ${#num2} -eq 0 ];then
    if [ $1 -lt $2 ];then
        echo "$1 less than $2!"
        exit
    elif [ $1 -eq $2 ];then
        echo "$1 equal $2!"
        exit
    else    
        echo "$1 great than $2!"
        exit
    fi
else
    echo "num1 num2 must be digit!"
fi

10 case 結構條件句

10.1 case結構條件句語法

case "字元串變數" in
    值1)
        指令1
        ;;
    值2)
        指令2
        ;;
    *)
        指令
esac
註意:case語句相當於一個if的多分支結構語句
值1的選項
apple)
    echo -e "@RED_COLOR apple $RES"
    ;;
也可以這樣寫,輸入2種格式找同一個選項
apple|APPLE)
    echo -e "$RED_COLOR apple $RES"
    ;;

case 語句小結
1)case語句就相當於多分支的if語句。case語句的優勢是更規範,易讀。
2)case語句適合變數的值少,且為固定的數字或字元串集合。
3)系統服務啟動腳本傳參的判斷多用case語句

10.2 給指定文本加顏色

以傳參為例,在腳本命令行傳2個參數,給指定內容(第一個參數)加指定顏色(第二個參數)

11 迴圈語句(while/for)

11.1 迴圈語句語法

11.1.1 while條件語句

while 條件
    do
        指令
done

11.1.2 for迴圈結構語法

for 變數名 in 變數取值列表
    do
        指令...
done

11.2 while語句

休息命令:sleep 1 休息一秒,usleep 1000000休息1秒單位微妙

11.2.1 守護進程

[root@chensiqi1 scripts]# cat chensiqi.sh 
#!/bin/bash


while true
do
    uptime >> /var/log/uptime.log
    sleep 2
done
#while true 表示條件永遠為真,因此會一直運行,像死迴圈一樣。
[root@chensiqi1 scripts]# cat /var/log/uptime.log 
 23:01:57 up  8:33,  2 users,  load average: 0.04, 0.03, 0.05
 23:01:59 up  8:33,  2 users,  load average: 0.04, 0.03, 0.05
 23:02:01 up  8:33,  2 users,  load average: 0.04, 0.03, 0.05

11.2.2 從1加到100

[root@chensiqi1 scripts]# cat chensiqi.sh 
#!/bin/bash
i=1
sum=0
while [ $i -lt 100 ]
do
    ((sum=sum+i))
    ((i++))
done
echo $sum

11.2.3 倒計時

[root@chensiqi1 scripts]# cat chensiqi.sh 
#!/bin/bash

i=10
while [ $i -gt 0 ]
do
    echo $i
    sleep 1
    ((i--))
done

11.3 防止腳本執行中斷的方法

1)sh while01.sh & #放在後臺執行
2)screen 分離 ctrl+a+d 查看screen -ls進入screen -r num
3)nohup while01.sh &

11.4 for迴圈語句

11.4.1 列印列表元素

[root@chensiqi1 scripts]# cat chensiqi.sh 
#!/bin/bash

for i in 5 4 3 2 1   #用空格隔開
do
    echo $i
done
[root@chensiqi1 scripts]# sh chensiqi.sh 
5
4
3
2
1
[root@chensiqi1 scripts]# for i in {5..1};do echo $i;done
5
4
3
2
1
[root@chensiqi1 scripts]# echo 10.1.1.{1..10}
10.1.1.1 10.1.1.2 10.1.1.3 10.1.1.4 10.1.1.5 10.1.1.6 10.1.1.7 10.1.1.8 10.1.1.9 10.1.1.10
[root@chensiqi1 scripts]# for i in `seq 5 -1 1`;do echo $i;done
5
4
3
2
1
#迴圈執行命令n次
[root@chensiqi1 scripts]# for i in `seq 100`;do curl -I baidu.com;done

11.4.2 開機啟動項優化

[root@chensiqi1 scripts]# cat chensiqi.sh 
#!/bin/bash

LANG=en
for i in `chkconfig --list|grep "3:on"|awk '{print $1}'`
do
    chkconfig $i off
done

for name in sshd rsyslog crond network sysstat
do
    chkconfig $name on
done

11.4.3 在/chensiqi目錄批量創建文件

#!/bin/bash

Path=/chensiqi
[ -d "$Path" ] || mkdir -p $Path
for i in `seq 10`
do
    touch $Path/chensiqi_$i.html
done

11.4.4 批量改名

[root@chensiqi1 scripts]# cat chensiqi.sh 
#!/bin/bash
$Path=/chensiqi
[ -d "$Path" ] || mkdir -p $Path
for file in `ls $Path`
do
    mv $file `echo $file|sed -r 's#chensiqi(.*).html#linux\1.HTML#g'`
done

11.4.5 批量創建用戶並設置密碼

[root@chensiqi1 scripts]# cat chensiqi.sh 
#!/bin/bash

User=chensiqi
Path=/tmp

for user in ${User}{01..10}
do
    useradd $user >/dev/null 2>&1
    if [ ! $? -eq 0 ];then
        echo "$user created faile!"
        echo "scripts begin to rollback!"
        for i in ${User}{01..10}
        do
            userdel -r $i >/dev/null 2>&1
            [ $? -eq 0 ] || exit 1
        done
        echo >$Path/user_passwd
        exit 1
    else
        passWD=`echo $RANDOM|md5sum|cut -c1-8`
        [ -d $Path ] || mkdir $Path
        echo $passWD | passwd --stdin $user
        echo "$user:$passWD">>$Path/user_passwd
    fi
done

11.4.6 獲取當前目錄下的目錄名做為變數列表列印輸出

[root@chensiqi1 ~]# cat /server/scripts/chensiqi.sh
#!/bin/bash

Path=`pwd`
echo $Path
for filename in `ls`
do
    [ -d ${Path}/${filename} ] && echo $filename
done

11.4.7 九九乘法表

[root@chensiqi1 ~]# cat /server/scripts/chensiqi.sh 
#!/bin/bash

for ((i=1;i<10;i++))
do
    for ((j=1;j<=i;j++))
    do
        echo -n "$i * $j = $((i*j))"
        echo -n " "
    done
    echo " "
done
[root@chensiqi1 ~]# sh /server/scripts/chensiqi.sh
1 * 1 = 1  
2 * 1 = 2 2 * 2 = 4  
3 * 1 = 3 3 * 2 = 6 3 * 3 = 9  
4 * 1 = 4 4 * 2 = 8 4 * 3 = 12 4 * 4 = 16  
5 * 1 = 5 5 * 2 = 10 5 * 3 = 15 5 * 4 = 20 5 * 5 = 25  
6 * 1 = 6 6 * 2 = 12 6 * 3 = 18 6 * 4 = 24 6 * 5 = 30 6 * 6 = 36  
7 * 1 = 7 7 * 2 = 14 7 * 3 = 21 7 * 4 = 28 7 * 5 = 35 7 * 6 = 42 7 * 7 = 49  
8 * 1 = 8 8 * 2 = 16 8 * 3 = 24 8 * 4 = 32 8 * 5 = 40 8 * 6 = 48 8 * 7 = 56 8 * 8 = 64  
9 * 1 = 9 9 * 2 = 18 9 * 3 = 27 9 * 4 = 36 9 * 5 = 45 9 * 6 = 54 9 * 7 = 63 9 * 8 = 72 9 * 9 = 81 

11.5 各種語句小結

1)while迴圈的特長是執行守護進程以及我們希望迴圈不退出持續執行,用於頻率小於1分鐘迴圈處理(crond),其他的while迴圈幾乎都可以被for迴圈替代。
2)case語句可以被if語句替換,一般在系統啟動腳本傳入少量固定規則字元串用case語句,其他普通判斷多用if
3)一句話,if,for語句最常用,其次while(守護進程),case(服務啟動腳本)

11.6 獲取隨機數的幾種方法。

11.6.1 通過系統環境變數$RANDOM

[root@chensiqi1 ~]# echo $RANDOM
6178
[root@chensiqi1 ~]# echo $RANDOM
30890
[root@chensiqi1 ~]# echo $((RANDOM%9)) #輸出0~9之間隨機數
2
[root@chensiqi1 ~]# echo $((RANDOM%9)) 
[root@chensiqi1 ~]# echo $((RANDOM%9))$((RANDOM%9)) #輸出00~99 隨機數
64
[root@chensiqi1 ~]# echo $((RANDOM%9))$((RANDOM%9)) #輸出00~99歲?隨機數
10
[root@chensiqi1 ~]# echo $((RANDOM%9))$((RANDOM%9)) #輸出00~99歲?隨機數
51
[root@chensiqi1 ~]# echo $RANDOM|md5sum #隨機數長短不一,可以用md5sum命令統一格式化
599e328a94329684ce5c92b850d32f26  -

11.6.2 通過openssl產生

[root@chensiqi1 ~]# openssl rand -base64 8
aND8WMRM6vQ=
[root@chensiqi1 ~]# openssl rand -base64 8
RsRdRq/9vi4=
[root@chensiqi1 ~]# openssl rand -base64 8|md5sum
b1108cafbc2291392e41d2c914360138  -
[root@chensiqi1 ~]# openssl rand -base64 10      
1frkA2kIJODxqQ==

11.6.3 通過時間獲得隨機數

[root@chensiqi1 ~]# echo $(date +%N)
361599138
[root@chensiqi1 ~]# echo $(date +%N)
199271856
[root@chensiqi1 ~]# echo $(date +%t%N)
950526316
[root@chensiqi1 ~]# echo $(date +%t%N)
340140329

11.6.4 urandom

[root@chensiqi1 ~]# head /dev/urandom | cksum
621330951 2535
[root@chensiqi1 ~]# head /dev/urandom | cksum
404398617 2470

11.6.5 UUID

[root@chensiqi1 ~]# cat /proc/sys/kernel/random/uuid
8a6c5bbe-2d42-44ac-9ef1-3e7683a613e3
[root@chensiqi1 ~]# cat /proc/sys/kernel/random/uuid
c828c209-5b5f-4bc7-917c-678ed4215988
[root@chensiqi1 ~]# uuidgen
961dc354-81b2-4564-9b85-6095ed4bc7b5

11.7 break continue exit return

11.7.1 break continue exit 對比

break continue exit用於迴圈結構中控制虛幻(for,while,if)的走向

命令 說明
break n n表示跳出迴圈的層數,如果省略n表示跳出整個迴圈
continue n n表示退出到第n層繼續迴圈,如果省略n表示跳過本次迴圈,忽略本次迴圈剩餘代碼,進入迴圈的下一次迴圈
exit n 退出當前shell程式,n為返回值,n也可以省略,在下一個shell里通過$?接收這個n值
return n 用在函數里,做為函數的返回值,用於判斷函數執行是否正確。和exit一樣,如果函數里有迴圈,也會直接退出迴圈,退出函數

11.7.2 break

[root@chensiqi1 ~]# cat /server/scripts/chensiqi.sh
#!/bin/bash

for ((i=0;i<=5;i++))
do
    [ $i -eq 3 ] && break
    echo $i
done
echo "ok"
[root@chensiqi1 ~]# sh /server/scripts/chensiqi.sh
0
1
2
ok

11.7.3 continue

[root@chensiqi1 ~]# cat /server/scripts/chensiqi.sh
#!/bin/bash

for ((i=0;i<=5;i++))
do
    [ $i -eq 3 ] && continue
    echo $i
done
echo "ok"
[root@chensiqi1 ~]# sh /server/scripts/chensiqi.sh
0
1
2
4
5
ok

11.7.4 exit

[root@chensiqi1 ~]# cat /server/scripts/chensiqi.sh
#!/bin/bash

for ((i=0;i<=5;i++))
do
    [ $i -eq 3 ] && exit 2
    echo $i
done
echo "ok"
[root@chensiqi1 ~]# sh /server/scripts/chensiqi.sh
0
1
2
[root@chensiqi1 ~]# echo $?
2

11.7.5 return

[root@chensiqi1 ~]# cat /server/scripts/chensiqi.sh
#!/bin/bash

function xxxx {

    for ((i=0;i<=5;i++))
    do
        [ $i -eq 3 ] && return 7
        echo $i
    done
    echo "ok"

}


xxxx
echo $?

[root@chensiqi1 ~]# sh /server/scripts/chensiqi.sh
0
1
2
7

12,shell腳本的調試

  1. 使用dos2unix處理腳本

從windows編輯的腳本到Linux下需要使用這個命令
dos2unix windows.sh

  1. 使用echo命令調試

在變數讀取或修改的前後假如echo $變數,也可在後面使用exit退出腳本,這樣可以不用註釋後邊代碼

  1. 利用bash的參數調試

sh [-nvx]
-n:不會執行該腳本,僅查詢腳本語法是否有問題,並給出錯誤提示。可用於生產伺服器那些只能執行一次不可逆的腳本。
-v:在執行腳本時,先將腳本的內容輸出到屏幕上然後執行腳本,如果有錯誤,也會給出錯誤提示。(一般不用)
-x:將執行的腳本內容及輸出顯示到屏幕上,常用

shell腳本調試技巧小結:
1)要記得首先用dos2unix對腳本格式化
2)直接執行腳本根據報錯來調試,有時報錯不准確。
3)sh -x調試整個腳本,顯示執行過程。
4)set -x和set +x調試部分腳本(在腳本中設置)
5)echo輸出變數及相關內容,然後緊跟著exit退出,不執行後面程式的方式,一步步跟蹤腳本,對於邏輯錯誤比較好用。
6)最關鍵的時語法熟練,編碼習慣,編程思想,將錯誤扼殺在萌芽中,減輕調試負擔,提高效率。


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

-Advertisement-
Play Games
更多相關文章
  • 本文轉自:http://m.blog.csdn.net/article/details?id=51638925 寫在前面 本文來自iOS Tutorial Team 的 Marcelo Fabri,他是Movile的一名 iOS 程式員。這是他的個人網站:http://www.marcelofabr ...
  • 描述了在window系統下android Studio 中git如何使用Git ...
  • LruCache是一個泛型類,它內部採用LinkedHashMap,並以強引用的方式存儲外界的緩存對象,提供get和put方法來完成緩存的獲取和添加操作。當緩存滿時,LruCache會移除較早的緩存對象,然後再添加新的緩存對象。對Java中四種引用類型還不是特別清楚的讀者可以自行查閱相關資料,這裡不 ...
  • 前言 啦啦啦~各位小伙伴們好~經過這一學期的Android知識的學習,我們學到了很多和Android開發相關的知識,這一學期的學習也要告一段落了。(博客中有很多照片上有代碼,代碼文本較小,各位可按下Ctrl和前滾輪放大後再看~) 一起進入我們今天的相關內容~這次我們將一起學習使用 android 手 ...
  • 寫在前面:當你部署一臺伺服器,第一步不應該是部署應用,安全是才是首要任務 如果某一天當你登錄伺服器發現 /bin/bash –i,python -c 'import pty; pty.spawn("/bin/sh")' 等命令在伺服器上出現的時候,那麼恭喜你,伺服器被入侵了 但是入侵者都是很聰明的, ...
  • ownCloud(官網)是一款開源的私有雲框架,可以通過它實現個人網盤的功能,如果擁有一個性能不錯的VPS,那麼就可以擺脫奇慢無比的百度雲等網盤啦!我花了大約一天的時間總算搭好了ownCloud。 ...
  • 作者信息 作者: 彭東林 郵箱: [email protected] QQ: 405728433 軟體平臺 主機: Ubuntu14.04 64位版本 模擬器:Qemu-2.8.0 Linux內核版本: Linux-4.10 Busybox版本:busybox-1.24.2 工具鏈: ar ...
  • 1、經典入門:hello world 註:上面所使用的關鍵字:include 頭文件包含 int 整型,用來表示整數的類型 void 空類型 return 函數返回 2、基本概念: 源文件:源文件即源程式代碼文件,C語言源文件尾碼名是.c; 頭文件:頭文件的尾碼名為.h,C語言代碼由源文件和頭文件構 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...