腳本編程(一)

来源:https://www.cnblogs.com/fengciaimei/archive/2020/04/05/12635551.html
-Advertisement-
Play Games

腳本編程(一) 啰里啰唆:每周的最後一天都特別難受。墨跡扣不出文章。 一、概況 註釋是以#開都的,#開頭不一定都是註釋 SHELL是解釋型語言 SHELL腳本第一句以#!/bin/bash開頭 SHELL腳本需要具有執行許可權 一般以.sh結尾 別名在腳本中無效。在腳本中不能使用別名。 bash使用技 ...


 

腳本編程(一)

啰里啰唆:每周的最後一天都特別難受。墨跡扣不出文章。

一、概況

註釋是以#開都的,#開頭不一定都是註釋

SHELL是解釋型語言

SHELL腳本第一句以#!/bin/bash開頭

SHELL腳本需要具有執行許可權

一般以.sh結尾

別名在腳本中無效。在腳本中不能使用別名。

 

bash使用技巧:

-n 檢查語法,無法無法檢測處命令錯誤,同時只是檢查語法不會真正執行腳本。

-x 逐行執行,逐行顯示執行結果

 

腳本中的錯誤:

1、語法錯誤,會導致後續的命令無法繼續執行。可以通過bash -n選項來檢查

提示的錯誤行不一定是準確的。

2、命令錯誤,後續的命令還可以繼續執行。無法通過bash -n 選項來檢查錯誤,可以使用set -e或者set -o errexit來設定遇到錯誤命令後退出

3、邏輯錯誤,只能使用bash -x選項來檢查錯誤。

 

變數:

變數表示命名的記憶體空間,講數據放在記憶體空間中,通過 "$變數名" 引用,從而獲取數據

 

內置環境變數:

PS1 SHELL HASTNAME $$ $?

自定義變數:

[set] NAME=VALUE set可以省略

 

變數類型:

字元型:預設都是字元型

數值:整型、 bash不支持浮點型

 

靜態編譯語言,使用變數前,先聲明變數類型,之後類型不能改變,在編譯時執行檢查,JAVA C

動態編譯語言:不用事先聲明,可以隨時改變變數類型,SHELL PYTHON

 

強類型語言:不同類型的操作數,必須經過強制轉換成同一類型的變數後才能運算

弱類型語言:不同類型的操作數,會隱式轉換數據類型,如SHELL

 

shell中變數命令規則

變數名不用實現聲明

變數名不能和系統已經定義好的變數同名

變數名不能和系統的內外部命令同名

變數名不能和系統定義好的關鍵字同名,如:if else case for

變數名不能以數字開頭

變數名不支持短橫線-

變數名需要見名知意,最好用英語名,最好不要命拼音,不要用拼英縮寫

統一命名規則:駝峰命名法,大駝峰studentName     小駝峰studentName

變數名大寫

局部變數小寫

函數名小寫

 

普通變數,生效範圍是當前shell進程;對當前shell之外的其它進程(包括當前shell的子進程)均無效。

環境變數,生效範圍是當前shell進程及其子進程

本地變數,生效範圍進士當前shell進程中某個代碼片段,通常指函數。

 

變數賦值的時候等號左右不要有空格: NAME="value"    如果賦值中有空格需要使用引號引起來。

可以把文件路徑賦值給變數。

特殊用法參考以下示例:

[root@CentOS8 /]# FILE=/*
[root@CentOS8 /]# echo $FILE
/bin /boot /data /dev /etc /home /lib /lib64 /media /mnt /opt /proc /root /run /sbin /srv /sys /@System.solv /tmp /usr /var
/*
[root@CentOS8 /]# ls -d $FILE
/bin   /data  /etc   /lib    /media  /opt   /root  /sbin  /sys           /tmp  /var
/boot  /dev   /home  /lib64  /mnt    /proc  /run   /srv   /@System.solv  /usr
[root@CentOS8 /]# ls -d "$FILE"

 

 

變數引用  $NAME   ${NAME}

 

變數引用的時候,加上雙引號會保留原始的回車符等隱式字元,

不加上雙引號預設會去掉回車符並以空格代替。

看以下示例 {

[root@CentOS8 ~]# NUM=`seq 10`
[root@CentOS8 ~]# echo "$NUM"
1
2
3
4
5
6
7
8
9
10
[root@CentOS8 ~]# echo $NUM
1 2 3 4 5 6 7 8 9 10
[root@CentOS8 ~]#

註意:變數賦值時臨時生效,當退出終端後,變數會自動刪除;腳本中的變數會隨著腳本結束自動刪除。

 

env可以顯示所有已經定義好的環境變數

export不跟任何選項,也可以顯示所有已經定義的環境變數

declare -x 也可以顯示所有已經定義的環境變數

set可以顯示所有已經定義好的所有變數

 

unset NAME可以取消變數定義

unset NAME1 NAME2 NAME3...取消多個變數

 

無法在子shell中使用父shell中定義的本地變數,可以使用exportdeclare -x把變數聲明成環境變數,就可以在子shell(包括孫子進程)中調用父shell中定義的環境變數。但是無法讓父進程繼承子進程的

變數,孫子進程可以繼承子進程的環境變數。

 

$BASHPID 顯示當前進程的PID

$PPID 顯示父進程的PID

LANG 語言系環境變數

MAIL 郵箱

SHLVL shell的嵌套深度

 

變數除了可以存字元,還可以存命令。$CMD的結果SHELL會當成命令執行。

 

只讀變數,定義後的只讀變數不能修改和刪除,只能退出重新登

readonly NAME 定義只讀變數

declare -r NAME 定義只讀變數

 

位置變數:

$0 表示命令本身,會包括路徑

$1 表示對應第一個參數,使用shift n替換

$2 表示對應第二個參數,使用shift n替換

...

${10} 表示對應的第十個參數,不能直接寫成$10

${11} 表示對應的第十一個參數,不能直接寫成$11

$* 表示所有參數,會把各個變數看成統一整體,只有雙引號$*"$@"才有區別

$@ 表示所有參數,會把各個變數看成獨立個體,只有雙引號$*"$@"才有區別

$# 表示參數個數

$? 判斷上一條執行狀態的執行結果

$_ 前一個命令的最後一個參數

 

set -- 清楚所有位置變數

[root@CentOS7 2]# cat arg.sh
#!/bin/bash
#
echo "1st is $1"
echo "2st is $2"
echo "3st is $3"
echo "10st is ${10}"
echo "10st is $10"
echo "11st is ${11}"
echo "11st is $11"
echo "The number of `basename $0` is $#"
echo "All args are $*"
echo "All args are $@"
.
/arg2.sh $* ;echo '$*' ./arg2.sh $@ ;echo '$@' ./arg2.sh "$*" ;echo '"$*"' ./arg2.sh "$@" ;echo '"$@"'
[root@CentOS7 2]# cat arg2.sh #!/bin/bash # echo -n "$1 " [root@CentOS7 2]# ./arg.sh {a..z} 1st is a 2st is b 3st is c 10st is j 10st is a0 11st is k 11st is a1 The number of arg.sh is 26 All args are a b c d e f g h i j k l m n o p q r s t u v w x y z All args are a b c d e f g h i j k l m n o p q r s t u v w x y z a $* a $@ a b c d e f g h i j k l m n o p q r s t u v w x y z "$*" a "$@" [root@CentOS7 2]#

 

命令行展開

命令行展開優先順序

1、把命令行分成單個命令詞

2、展開別名

3、展開大括弧的聲明{}

4、展開波浪線聲明~

5、命令替換$()或··

6、再次把命令行分成命令詞

7、展開文件通配符

8、準備I/O重定向

9、運行命令

 

防止擴展

使用反斜線\會是隨後的字元按願意執行

 

腳本安全和set

she命令,地址shell環境

$- 以關鍵字形式顯示系統啟用功能

+表示禁用,-表示啟用

h 表示hash,可以set +h選項關閉hash

i 互動式,說明當前shell是個交互是shell

m 表示啟用job control來控制進程的停止

B 表示啟用大括弧擴展

H HISTORY,表示可以展開命令歷史列表

  $_ 前一個命令的最後一個參數

set命令 修改環境變數

-o 打開關閉某些選項,如果後面不跟任何選項表示顯示以shell啟用的某些功能

set -o 表示啟用

set +o  表示禁用

-e 等同於 -o errexit遇到命令出錯就退出

-u 是否使用沒有定義的變數,相當於-o nounset

-x 單步執行

 

  exit命令

    用戶可以在腳本中使用以下命令自定義退出狀態碼

        exit [n]

    腳本中一旦遇到exit命令,腳本會立即終止,然後返回狀態碼

    如果exit未指定退出碼,整個腳本的最終狀態碼取決於最後一條命令的狀態碼。

    例:{示例說明演示未指定退出碼的情況

[root@CentOS7 2]# cat exit.sh
#!/bin/bash
#
echo haha
ech haha
exit
[root@CentOS7 2]# ./exit.sh
haha
./exit.sh: line 4: ech: command not found
[root@CentOS7 2]# echo $?
127

 

printf命令

printf "指定的格式" 文本1  文本2.。。 按照指定格式顯示指定文本

%s 字元串格式,%-#.##s中,#表示顯示字元寬度,數字不足的用空格補足,##表示顯示小數個數,-表示左對齊

%f 浮點型格式

%b 相對應的參數中包含轉義字元時,可以使用此替換符進行替換,對應的轉義字元會被轉義

%d  | %i 十進位整數

%c ASCII字元,即顯示對應參數的第一個字元

%o 八進位顯示

%u 不帶正負號的十進位顯示

%x 小寫的十六進位顯示,即a-f

%X 大寫的十六進位顯示,即A-F

%% 表示%本身

 

轉義字元:

\a 警告字元,會發一聲響

\b 後退一格

\f 換頁

\n 換行

\r 回車

\t 橫向製表符

\v 縱向製表符

\\ 表示\本身

 

二、算數運算

算數運算符

+

-

*

/

% 取模,求餘數

** 乘方

 

進行算數表達式

let $M+$N 不用帶$,帶上也沒問題

let M++ M自增,與++M的區別是前者是先引用後自增,後者是先自增後引用

let N-- N自減,與--N的區別是前者是先引用後自減,後者是先自減後引用

$[$M+$N] 不用帶$,帶上也沒問題

$(($M+$N)) 不用帶$,帶上也沒問題

expr $M + $N 在運算符兩邊要有空格,在運算乘法的時候需要轉移即\*

declare -i VAR 可以使用declare -i把變數聲明成整數,然後就可以直接運算了

 

三、邏輯運算

 1&&1=1   1&&0=0   0&&1=0    0&&0=0 任何數與0相與都為假

 1||1=1   1||0=1   0||1=1    0||0=0 任何數與1相或都為真

 !1=0     !0=1

異或  1^0=1   1^1=0    0^0=0     0^1=0 異或是用二進位進行運算。異或的兩個值,相同為假,不同為真

兩個運算數異或得出的值,此值在與兩個運算數其中任何一個再異或,必定得出另一個運算數

示例演示用異或互換兩個變數的值

#!/bin/bash
# i
=10 j=20 echo "i=$i;j=$j" #i中的值現在已經是i與j的異或值 i=$[i^j] #下句的意思是用上一句得出的異或值i,與運算數j 再次進行異或,會得出另一個運算數 j=$[i^j] #下句的意思是用上一句得出的異或值j再次與第一句中得出的異或值i進行異或,會得出另一個 運算數 i=$[i^j] echo "i=$i;j=$j"

 

短路運算

短路與:CMD1&&CMD2

第一個CMD1結果為0,總的結果必定為0,因此不需要執行CMD2

第一個CMD1結果為1,第二個CMD2必須要參與運算,才能得到最終結果

短路或:CMD1||CMD2

第一個CMD1結果為1,總的結果必定為1,因此不需要執行CMD2

第一個CMD1結果為0,第二個CMD2必須要參與運算,才能得到最終結果

 

四、條件測試

條件測試命令

test EXPRESSION

[ EXPRESSION ] 判斷式必須有空格。等同於test

[[ EXPRESSION ]]

 

變數測試

[ -v VAR ] 判斷變數VAR是否已經定義,True if the shell variable VAR is set.

[ -R VAR ] 判斷變數VAR是否已經定義並且已經引用,True if the shell variable VAR is set and is a name reference.

 

數值測試     進行數值判斷的時候不能有非數字

-eq 相等

-ne 不相等

-lt 小於

-le 小於等於

-gt 大於

-ge 大於等於

 

字元串測試

-z 測試變數是否為空或者沒賦值,變數未定義 變數裡面是空值 都為真,但是在以用變數的時候需要加上雙引號。True if string is empty.例:n="";[ -z "$n" ];echo $?

-n 判斷變數是否為非空,在引用變數的時候必須加上雙引號 True if string is not empty.: [ -n "$mm" ]

[STRING] 判斷式中什麼也不見,預設是指判斷變數是否為非空。True if string is not empty.

= 判斷字元串是否相等,等號兩邊都有空格,True if the strings are equal.

!= 判斷字元串是否不相等,不等號兩邊都有空格,True if the strings are not equal.

> 前一個字元串的長度大於後一個字元串,True if STRING1 sorts after STRING2 lexicographically.

< 前一個字元串的長度小於後一個字元串,True if STRING1 sorts before STRING2 lexicographically.

[ $mm ] 如果什麼也不跟,是為了判斷變數mm長度是否非零,True if string is not empty.

示例演示[ $mm ]

[root@CentOS8 7]# mm=""
[root@CentOS8 7]# [ $mm ] && echo haha
[root@CentOS8 7]# mm="123"
[root@CentOS8 7]# [ $mm ] && echo haha
haha}

 

  [[ ]] 雙中括弧的時候裡面可以用正則表達式,雙中括弧也支持通配符,一般情況下使用單中括弧

   [[ "$FILE" == *.log ]] 在雙中括弧中== 後面接通配符,判斷FILE文件是不是log結尾

   [[ "$IP" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]  在雙中括弧中=~ 後面接正則表達式

   結論:[[ == ]]這種寫法中,==右側的* 如果想做通配符,不要加"",只想做*本身含義,需要轉移或者加上雙引號

    示例演示通配符 {[root@CentOS8 7]# mm=hh.tt

[root@CentOS8 7]# [ "$mm" == "*.tt" ] && echo haha
[root@CentOS8 7]# [ $mm == "*.tt" ] && echo haha
[root@CentOS8 7]# [[ $mm == "*.tt" ]] && echo haha
[root@CentOS8 7]# [[ "$mm" == "*.tt" ]] && echo haha
[root@CentOS8 7]# [[ "$mm" == "*\.tt" ]] && echo haha
[root@CentOS8 7]# [[ "$mm" == *.tt ]] && echo haha
haha

 

  =~==詳細使用介紹{

#通配符

[root@centos8 ~]#FILE=test.log
[root@centos8 ~]#[[ "$FILE" == *.log ]]
[root@centos8 ~]#echo $?
0
[root@centos8 ~]#FILE=test.txt
[root@centos8 ~]#[[ "$FILE" == *.log ]]
[root@centos8 ~]#echo $?
1
[root@centos8 ~]#[[ "$FILE" != *.log ]]
[root@centos8 ~]#echo $?
0

#正則表達式
[root@centos8 ~]#[[ "$FILE" =~ \.log$ ]]
[root@centos8 ~]#echo $?
1
[root@centos8 ~]#FILE=test.log
[root@centos8 ~]#[[ "$FILE" =~ \.log$ ]]
[root@centos8 ~]#echo $?
0
[root@centos8 ~]#N=100
[root@centos8 ~]#[[ "$N" =~ ^[0-9]+$ ]]
[root@centos8 ~]#echo $?
0
[root@centos8 ~]#N=Magedu10
[root@centos8 ~]#[[ "$N" =~ ^[0-9]+$ ]]
[root@centos8 ~]#echo $?
1
[root@centos8 ~]#IP=1.2.3.4
[root@centos8 ~]#[[ "$IP" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]
[root@centos8 ~]#echo $?
0
[root@centos8 ~]#IP=1.2.3.4567
[root@centos8 ~]#[[ "$IP" =~ ^([0-9]{1,3}.){3}[0-9]{1,3}$ ]]
[root@centos8 ~]#echo $?
1
[root@centos8 ~]#[[ $IP =~ ^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}
([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]]
[root@centos8 ~]#echo $?
1

#通配符
[root@centos8 ~]#NAME="linux1"
[root@centos8 ~]#[[ "$NAME" == linux* ]]
[root@centos8 ~]#echo $?
0
[root@centos8 ~]#[[ "$NAME" == "linux*" ]]
[root@centos8 ~]#echo $?
1
[root@centos8 ~]#NAME="linux*"
[root@centos8 ~]#[[ "$NAME" == "linux*" ]]
[root@centos8 ~]#echo $?
0

#結論:[[ == ]] == 右側的 * 做為通配符,不要加“”,只想做為*, 需要加“” 或轉義

 

文件測試

-a 文件是否存在,True if file exists.

-e 文件是否存在 等同於-a, -e選項常用,True if file exists.

-b 文件是否是塊文件,True if file is block special.

-c 文件是否是字元文件,True if file is character special.

-d 判斷是不是目錄,True if file is a directory.

-f 判斷是不是普通文件,在判斷軟連接的時候,會追蹤軟連接指向的文件,True if file exists and is a regular file.

-h -L 判斷是不是軟連接,True if file is a symbolic link.

-p 判斷是不是管道文件,True if file is a named pipe.

-S 大寫,判斷是不是套接字文件

文件新舊比較

-ot old thanTrue if file1 is older than file2.

-nt new thanTrue if file1 is newer than file2

-ef 判斷是不是硬鏈接,True if file1 is a hard link to file2.

文件許可權測試

-w 判斷文件是否有寫許可權,判斷最終的許可權,而不是看錶面ll的顯示結果,True if the file is writable by you.

-x 判斷文件是否有執行許可權,判斷最終的許可權,而不是看錶面ll的顯示結果,True if the file is executable by you.

-r 判斷文件是否有讀許可權,判斷最終的許可權,而不是看錶面ll的顯示結果,True if file is readable by you.

-u FILE 是否存在且擁有suid許可權

-g FILE 是否存在且擁有sgid許可權

-k FILE 是否存在且擁有sticky許可權

 

文件屬性測試

-s 小寫,是否存在且非空,True if file exists and is not empty.

-t 判斷文件的文件描述符是否已經打開,True if FD is opened on a terminal.

-N FILE 文件自從上一次被讀取之後是否被修改過

-O FILE 當前有效用戶是否為文件屬主

-G FILE 當前有效用戶是否為文件屬組

 

 

() 小括弧中變數會在子進程中運行,同時會繼承父進程中的變數值,但是起產生的結果不會影響父進程中的值

{} 花括弧中的變數不會在子進程中運行,會在當前進程中執行,其結果會影響話括弧外面的變數,花括弧內的最後公式需要以分號;結尾,花括弧內兩邊有空格

(){}都能將多個命令組合在一起,批量執行.

 

組合測試條件

[ EXPRESSION1 -a EXPRESSION2 ] 並且,表達式1和表達式2,結果才為真,True if both expr1 AND expr2 are true.

[ EXPRESSION1 -o EXPRESSION2 ]  或者,表達式1和表達式2只要一個為真,結果就為真,會進行短路運算,True if either expr1 OR expr2 is true.

[ ! EXPRESSION ]   取反,True if expr is false.

 

  -a-o選項只能在單中括弧內使用,不能再[[ ]]內使用。

 

 

  COMMAND1 && COMMAND2 並且,短路與,代表條件性的AND THEN。如果COMMAND1 成功,將執行COMMAND2,否則,將不執行COMMAND2

  COMMAND1 || COMMAND2 或者,短路或,代表條件性的OR ELSE。如果COMMAND1 成功,將不執行COMMAND2,否則,將執行COMMAND2

  ! COMMAND ,取反

  如果&&||同時使用,一般情況下&&放在前面給,||放在後面。

 

六、條件判斷

順序執行:

  ;分號

if語句

  單分支:

if COMMANDS; then

COMMANDS

fi

 

  雙分支:

if EXPRIESSION;then

COMMANDS

else

COMMANDS

fi

 

  多分支:

if EXPRIESSION;then

COMMANDS

elif EXPRIESSION; then

COMMANDS

elif EXPRIESSION; then

COMMANDS

fi

 

 

case語句

case WORD in

[PATTERN])

COMMAND

;;

[PATTERN])

COMMAND

;;

*)

COMMAND

;;

esac

 

PATTER

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

-Advertisement-
Play Games
更多相關文章
  • 在Flutter中實現整個App變為灰色是非常簡單的,只需要在最外層的控制項上包裹ColorFiltered,用法如下: 前後效果對比如下: | | | | | | | | | 交流 如果你對Flutter還有疑問或者技術方面的疑惑,歡迎加入Flutter交流群(微信:laomengit)。 同時也歡 ...
  • 前言 網路請求是開發中最基礎也是最核心的需求,封裝一個穩定且可用性高的請求也顯得尤為重要。通常封裝的內容除了入參之外,更多的是請求中的異常處理。本文分享下我在處理 異常方面的做法,通過維護請求隊列,實現重發請求,減少 重覆請求。 公共請求方法 下麵以封裝微信小程式請求作為例子,這是一個基礎的公共請求 ...
  • JSON 是一種輕量的數據交互格式,與 AJAX 配合完成前端與服務端的信息傳遞,本文介紹 JSON 的使用、原生 AJAX 寫法、JSONP 跨域解決方法以及 AJAX 和 JSONP 工具函數的封裝 ...
  • 這次的疫情帶來的影響真的超乎想象……怎麼疫情和這篇筆記有關呢!到現在還有好多學校都沒有開學,學生們都在家網上學習(這其中包括我的小舅子)。正題來了,他們老師給了一個視頻鏈接(學習視頻)—— 格式是m3u8的。用手機太費眼了,又喜歡打游戲……他想在電腦上看,便問了我一下怎麼播放。我開始給他找了一些線上 ...
  • 面向對象第一次作業周期(前四周)總結 ——對面向對象程式設計的基本認識 0.前言: 接觸面向對象程式設計這門課程已經有四周有餘了,經過四周的網課,直播課,PTA作業題等的練習,我對面向對象程式設計有了自己的理解和興趣。前三次的PTA作業讓我逐漸從面向過程思維逐步轉變為面向對象思維,作業由自己獨立思考 ...
  • 圖解Java設計模式之策略模式 編寫鴨子項目,具體要求如下 : 傳統方案解決鴨子問題的分析和代碼實現 傳統方式解決鴨子問題分析和解決方案 策略模式基本介紹 策略模式的原理類圖 策略模式解決鴨子問題 策略模式在JDK - Arrays 應用的源碼分析 策略模式的註意實現和細節 編寫鴨子項目,具體要求如 ...
  • 圖解Java設計模式之狀態模式 APP抽象活動問題 狀態模式基本介紹 狀態模式的原理類圖 狀態模式解決APP抽獎問題 狀態模式的註意事項和細節 APP抽象活動問題 請編寫程式完成APP抽象活動,具體要求如下 :1)加入每參加一個這個活動要扣除用戶50積分,中獎概率是10%。2)獎品數量固定,抽完就不 ...
  • 將文本正確轉換為 DateTime 需要執行三個子任務:1、正確格式的日期和時間字元串。2、區域性,不同地區的日期和時間表示格式有區別,字元串格式有區別。3、指定轉換格式,例如轉換後的DateTime,可能沒有時間部分。 使用Parse轉換和TryParse轉換: string dateInput ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...