Shell脚本语言常用命令总结~
寫目錄
- 一、Shell概述
- 二、Shell腳本
- 三、Shell中的變量
- 3.1 系統變量
- 3.2 自定義變量
- 3.3 特殊變量:$n
- 3.4 特殊變量:$#
- 3.5 特殊變量:$* 、 $@
- 3.6 特殊變量:$?
- 四、運算法
- 五、條件判斷
- 六、流程控制
- 6.1 if判斷
- 6.2 case 語句
- 6.3 for 循環
- 6.4 while 循環
- 七、read讀取控制臺輸入 ??
- 八、函數
- 8.1 系統函數
- 8.2 自定義函數
- 九、Shell工具 ??
- 9.1 cut
- 9.2 sed
- 9.3 awk
- 9.4 sort ??
- 十、真題
一、Shell概述
Shell是一個命令行解釋器,它接收應用程序/用戶命令,然后調用操作系統內核。
優點:Shell還是一個功能相當強大的編程語言,易編寫、易調試、靈活性強。
二、Shell腳本
腳本以 #!/bin/bash 開頭(指定解析器)
需求:創建一個Shell腳本,輸出helloworld
1). 使用以下命令創建一個datas文件夾,存放腳本:
[xiaobai@hadoop100 ~]$ mkdir datas2). 使用以下命令創建helloworld.sh腳本
[xiaobai@hadoop100 datas]$ touch helloworld.sh3). 使用以下命令編輯helloworld.sh腳本:
[xiaobai@hadoop100 datas]$ vim helloworld.sh4). 輸入以下內容:
#!/bin/bashecho "hello world"5). 腳本執行方式:
方式1??. 采用bash或sh+腳本的相對路徑/絕對路徑(不用賦予腳本+x權限)
sh+腳本的相對路徑:
[xiaobai@hadoop100 datas]$ sh helloworld.sh hello worldsh+腳本的絕對路徑:
[xiaobai@hadoop100 datas]$ sh /home/xiaobai/datas/helloworld.sh hello worldbash+腳本的相對路徑:
[xiaobai@hadoop100 datas]$ bash helloworld.sh hello worldbash+腳本的絕對路徑:
[xiaobai@hadoop100 datas]$ bash /home/xiaobai/datas/helloworld.sh hello world方式2??. 采用輸入腳本的絕對路徑/相對路徑執行腳本(必須具有可執行權限+x)
a. 首先賦予helloworld.sh 腳本的+x權限:
[xiaobai@hadoop100 datas]$ chmod 777 helloworld.shb. 執行腳本:
相對路徑執行腳本:
[xiaobai@hadoop100 datas]$ ./helloworld.sh hello world絕對路徑執行腳本:
[xiaobai@hadoop100 datas]$ /home/xiaobai/datas/helloworld.sh hello worldtips:
方式1?? ,本質是解析器幫助執行腳本,所以腳本本身不需喲啊執行權限;方式2?? ,本質是腳本需要自己執行,所以需要?x權限。
需求:
在/home/xiaobai/目錄下創建一個welcome.txt, 新增內容“Welcome to China!”
1). 使用以下命令創建一個batch.sh腳本:
[xiaobai@hadoop100 datas]$ touch batch.sh [xiaobai@hadoop100 datas]$ vi batch.sh2). 如圖,在batch.sh腳本添加以下內容:
#!/bin/bashcd /home/xiaobai/ touch welcome.txt echo "Welcome to China" >> welcome.txt3). 運行batch.sh腳本:
[xiaobai@hadoop100 datas]$ bash batch.sh4). 查看腳本運行結果:
三、Shell中的變量
3.1 系統變量
查看系統變量的值:
[xiaobai@hadoop100 ~]$ echo $HOME /home/xiaobai [xiaobai@hadoop100 ~]$ [xiaobai@hadoop100 ~]$ echo $PWD /home/xiaobai [xiaobai@hadoop100 ~]$ echo $SHELL /bin/bash [xiaobai@hadoop100 ~]$ echo $USER xiaobai3.2 自定義變量
1). 定義變量:變量=值
[xiaobai@hadoop100 ~]$ a=1 [xiaobai@hadoop100 ~]$ echo $a 12). 撤銷變量:unset 變量
[xiaobai@hadoop100 ~]$ unset a [xiaobai@hadoop100 ~]$ echo $a[xiaobai@hadoop100 ~]$3). 聲明靜態變量:readonly 變量,
tips:只讀 不可以使用unset
1). 變量名稱可以由字母、數字和下劃線組成,但是不能以數字開頭,環境變量名最好大寫!
2). 等號兩側?有空格;
3). 在bash中,變量默認類型都是字符串類型,無法直接進行數值運算;
[xiaobai@hadoop100 ~]$ c=1+2 [xiaobai@hadoop100 ~]$ echo $c 1+24). 變量的值如果有空格,需要使用雙引號 " " / ’ ’ 括起來。
[xiaobai@hadoop100 ~]$ d="i love China" [xiaobai@hadoop100 ~]$ echo $d i love Chinatips:
使用“ export 變量名 ” 可以將變量提升為全局環境變量,供其他Shell程序使用。
eg:
如圖,在helloworld.sh 中增加 echo $d:
如果不將 d 提升為全局變量,helloworld.sh 并不會打印出 d 的值:
使用 “ export d ” 將d提升為全局變量,重新打印helloworld.sh :
[xiaobai@hadoop100 datas]$ export d [xiaobai@hadoop100 datas]$ ./helloworld.sh hello world i love China3.3 特殊變量:$n
$n (功能描述:n為數字,$0代表該腳本名稱,$1-$9代表第一到第九個參數,🔟以上的參數需要用大括號 { }包含,如${10})
1). 輸出該腳本文件名稱、輸入參數1和輸入參數2的值:
[xiaobai@hadoop100 datas]$ touch parameter.sh [xiaobai@hadoop100 datas]$ vi parameter.sh #!/bin/bashecho "$0 $1 $2 $3"2). 第 $0 個參數是 parameter.sh 腳本本身,$1是輸入的第一個參數,$2是輸入的第二個參數,$3是輸入的第三個參數,由于只定義了三個參數,所以$3后輸入的參數不能被打印出來。
[xiaobai@hadoop100 datas]$ bash parameter.sh parameter.sh [xiaobai@hadoop100 datas]$ bash parameter.sh i parameter.sh i [xiaobai@hadoop100 datas]$ bash parameter.sh i love parameter.sh i love [xiaobai@hadoop100 datas]$ bash parameter.sh i love China parameter.sh i love China [xiaobai@hadoop100 datas]$ bash parameter.sh i love China so much parameter.sh i love China3.4 特殊變量:$#
$# (功能描述:獲取所有輸入參數個數,常用于循環)。
獲取輸入參數的個數:
[xiaobai@hadoop100 datas]$ vi parameter.sh #!/bin/bashecho "$0 $1 $2 $3"echo $# [xiaobai@hadoop100 datas]$ chmod 777 parameter.sh [xiaobai@hadoop100 datas]$ ./parameter.sh China is the best country ./parameter.sh China is the 5 [xiaobai@hadoop100 datas]$ ./parameter.sh coming ./parameter.sh coming 13.5 特殊變量:$* 、 $@
$* (功能描述:此變量代表命令行中所有的參數,$* 把所有的參數看成一個整體);
$@ (功能描述:此變量也代表命令行中所有參數,不過$@把每個參數區分對待)。
3.6 特殊變量:$?
$?(功能描述:最后一次執行的命令的返回狀態。如果此變量值為0,證明上一個命令正確執行;如果此變量值為非0,則證明上一個命令執行錯誤)。
判斷 helloworld.sh 腳本是否正確執行:
[xiaobai@hadoop100 datas]$ ./helloworld.sh hello world i love China [xiaobai@hadoop100 datas]$ echo $? 0四、運算法
1). " $((運算式))" / "$[運算式]"
2). expr + - \* / % 加減乘除取余
tips:
expr運算符間需?空格。
1). 計算 10+5 的值:
[xiaobai@hadoop100 datas]$ expr 10 + 5 152). 計算 10-5 的值:
[xiaobai@hadoop100 datas]$ expr 10 - 5 53). 計算 (10+5) x 4 的值:
a. expr 一步完成計算
tips: 嵌套expr使用 ` 而非 ‘ 。
b. 采用 $[運算式] 方式:
[xiaobai@hadoop100 datas]$ s=$[(10+5)*4] [xiaobai@hadoop100 datas]$ echo $s 60五、條件判斷
[ condition ] (tips:condition前后有空格)
注:條件非空即為true,[ balabala ] 返回true, []返回false。
1). 兩個整數之間比較
= 字符串比較
-lt 小于 (less than)
-le 小于等于(less equal)
-eq 等于(equal)
-gt 大于(greater than)
-ge 大于等于(greater equal)
-ne 不等于(not equal)
2). 按照文件權限進行判斷
-r有讀的權限(read)
-w 有寫的權限(write)
-x 有執行的權限(execute)
3).按照文件類型進行判斷
-f 文件存在且是一個常規的文件(file)
-e 文件存在(existence)
-d 文件存在且是一個目錄(directory)
1). 30是否大于等于25:
[xiaobai@hadoop100 datas]$ [ 30 -ge 25 ] [xiaobai@hadoop100 datas]$ echo $? 030是否小于等于25:
[xiaobai@hadoop100 datas]$ [ 30 -le 25 ] [xiaobai@hadoop100 datas]$ echo $? 12). batch.sh是否具有寫權限
[xiaobai@hadoop100 datas]$ [ -w batch.sh ] [xiaobai@hadoop100 datas]$ echo $? 03). /home/xiaobai/welcome.txt 目錄中的文件是否存在:
[xiaobai@hadoop100 datas]$ [ -e /home/xiaobai/welcome.txt ] [xiaobai@hadoop100 datas]$ echo $? 04). 多條件判斷(&& 表示上一條命令執行成功時,才執行后一條命令, || 表示上一條命令執行失敗后,才執行下一條命令)
[xiaobai@hadoop100 datas]$ [ condition ] && echo OK || echo notOK OK [xiaobai@hadoop100 datas]$ [ condition ] && [ ] || echo notOK notOK六、流程控制
6.1 if判斷
注:
if后空格! [ 條件判斷式 ]中括號和判斷式之間需有空格;
輸入一個數字,若輸入1,則輸出the number is one;若輸入2,則輸出the number is two;若輸入其他,則不輸出任何;
[xiaobai@hadoop100 datas]$ touch if.sh [xiaobai@hadoop100 datas]$ vi if.sh #!/bin/bashif [ $1 -eq 1 ] thenecho "the number is one" elif [ $1 -eq 2 ] thenecho "the number is two" fi需運行帶參數的if.sh腳本:
[xiaobai@hadoop100 datas]$ bash if.sh if.sh: line 3: [: -eq: unary operator expected if.sh: line 6: [: -eq: unary operator expected [xiaobai@hadoop100 datas]$ bash if.sh 1 the number is one [xiaobai@hadoop100 datas]$ bash if.sh 2 the number is two [xiaobai@hadoop100 datas]$ bash if.sh 3 [xiaobai@hadoop100 datas]$6.2 case 語句
注:
1). case行尾須為單詞“in”,每一個模式匹配必須以右括號“ ) ” 結束;
2). 雙分號“ ;; ” 表示命令序列結束,相當于java中的break;
3). 最后的 “ *) ” 表示默認模式,相當于java中的default。
1). 輸入一個數字,若輸入1,則輸出the number is one;若輸入2,則輸出the number is two;若輸入其他,則不輸出任何;
[xiaobai@hadoop100 datas]$ touch case.sh [xiaobai@hadoop100 datas]$ vi case.sh #!/bin/bash#!/bin/bashcase $1 in 1)echo " the number is one" ;;2)echo " the number is two" ;;*)echo "the other number except the two choice" ;; esac [xiaobai@hadoop100 datas]$ bash case.sh 1the number is one [xiaobai@hadoop100 datas]$ bash case.sh 2the number is two [xiaobai@hadoop100 datas]$ bash case.sh 3 the other number except the two choice [xiaobai@hadoop100 datas]$ bash case.sh a the other number except the two choice6.3 for 循環
從1?到100:
[xiaobai@hadoop100 datas]$ touch for.sh [xiaobai@hadoop100 datas]$ vi for.sh #!/bin/bashs=0 for(( i=1;i<=100;i++ )) dos=$[$s+$i] done echo $s [xiaobai@hadoop100 datas]$ bash for.sh 5050打印所有輸入參數:
[xiaobai@hadoop100 datas]$ vim for2.sh不用引號的 $* 和 $@ 似乎無任何區別,都是將輸入元素按照順序單個輸出:
#!/bin/bashfor i in $* doecho "the parameter you entered is $i" donefor j in $@ doecho "the parameter you entered is $j" done??tips:
用引號"" 引起來的 "$*“是將輸入的所有字符一次性全部輸出,
而”$@"則是將輸入的所有字符按照輸入順序一個一個輸出。
6.4 while 循環
從1?到100:
[xiaobai@hadoop100 datas]$ vim while.sh #!/bin/bashs=0 i=1 while [ $i -le 100 ] dos=$[$s + $i]i=$[$i + 1] done echo $s [xiaobai@hadoop100 datas]$ bash while.sh 5050tips:
[條件判斷]不支持<= 運算符!須使用-le / -ge等;
變量的值<=100, 表示為$i <= 100; 而不是變量i<=100.
[ $i -le 100 ]表條件判斷[ 判斷式 ]前后須?空格,s=$[$i + $s]為運算符表運算不加空格!
七、read讀取控制臺輸入 ??
read(選項)(參數)
選項:
-p:指定讀取值時的提示符;
-t:指定讀取值時等待的時間(秒)。
參數:
變量:指定讀取值的變量名。
提示7秒內,讀取控制臺輸入的名稱:
[xiaobai@hadoop100 datas]$ vim read.sh #!/bin/bashread -t 7 -p "please input your name" NAMEecho $NAME [xiaobai@hadoop100 datas]$ bash read.sh please input your namexiaobai xiaobai八、函數
8.1 系統函數
basename [string / pathname] [suffix]
功能描述:若加了后綴suffix,則basename命令會刪掉所有的后綴包括最后一個( ’ / ') 字符,然后顯示出字符串。
選項:
suffix為后綴,為可選項,如果suffix被指定了,basename會將pathname或string中的suffix去掉。
??tips:
basename 截取文件名稱,dirname截取文件路徑,組合使用可獲取文件全路徑!
截取/home/xiaobai/welcome.txt路徑的文件名稱:
[xiaobai@hadoop100 datas]$ basename /home/xiaobai/welcome.txt welcome.txt [xiaobai@hadoop100 datas]$ basename /home/xiaobai/welcome.txt .txt welcomedirname 文件絕對路徑;
功能描述:從給定的包含絕對路徑的文件名中去除文件名(非目錄),然后返回目錄。
獲取welcome.txt文件的路徑:
[xiaobai@hadoop100 datas]$ dirname /home/xiaobai/datas/while.sh /home/xiaobai/datas8.2 自定義函數
1). 必須在調用函數之前先聲明函數,shell腳本時逐行運行,不會先編譯再運行;
2). 函數返回值只能通過$?系統變量獲得,可以顯式? return 返回,若不加return,則以最后一條命令運行結果作為返回值,return后跟數值n(0-255)。
計算兩個輸入參數的和:
[xiaobai@hadoop100 datas]$ vim sum.sh #!/bin/bashfunction sum() {s=0;s=$[$1+$2]echo $s } read -p "please input your parameter1:" p1 read -p "please input your parameter2:" p2sum $p1 $p2 [xiaobai@hadoop100 datas]$ bash sum.sh please input your parameter1:23 please input your parameter2:56 79九、Shell工具 ??
9.1 cut
cut,顧名思義,負責剪切數據;cut命令從文件的每一行剪切字節、字符和字段并輸出。
cut [選項參數] filename
注:默認分隔符是制表符。
| -f | 列號,按列號提取 |
| -d | 分隔符,按照指定分隔符分割列 |
1). 準備數據文件cut.txt:
[xiaobai@hadoop100 datas]$ vim cut.txt welcome to China hh hha i am coming big data go go go!2). 切割cut.txt第二、三列:
[xiaobai@hadoop100 datas]$ cut -d " " -f 2,3 cut.txt to China hha am coming datago3). 在cut.txt文件中切割出China:
[xiaobai@hadoop100 datas]$ cat cut.txt welcome to China hh hha i am coming big data go go go! [xiaobai@hadoop100 datas]$ cat cut.txt | grep China welcome to China [xiaobai@hadoop100 datas]$ cat cut.txt | grep China | cut -d " " -f 3 China4). 選取系統PATH變量值,第二個“ : ” 開始后的所有路徑:
[xiaobai@hadoop100 datas]$ echo $PATH /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/xiaobai/.local/bin:/home/xiaobai/bin [xiaobai@hadoop100 datas]$ echo $PATH | cut -d : -f 3- /usr/local/sbin:/usr/sbin:/home/xiaobai/.local/bin:/home/xiaobai/bintips:
-f 3- 表示第3列以后!
5). 切割ifconfig后打印的IP地址:
centos7如下:
[xiaobai@hadoop100 datas]$ ifconfig ens33 ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.31.100 netmask 255.255.255.0 broadcast 192.168.31.255inet6 fe80::2a3e:3aa4:e6cf:83e1 prefixlen 64 scopeid 0x20<link>ether 00:0c:29:cf:e9:22 txqueuelen 1000 (Ethernet)RX packets 107043 bytes 7695379 (7.3 MiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 29534 bytes 6130394 (5.8 MiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0[xiaobai@hadoop100 datas]$ ifconfig ens33 | grep -w "inet"inet 192.168.31.100 netmask 255.255.255.0 broadcast 192.168.31.255 [xiaobai@hadoop100 datas]$ ifconfig ens33 | grep -w "inet" | cut -d " " -f 10192.168.31.100如圖:centos7選擇ens33:
如圖:inet前有8個空格!ip處在第10列!
9.2 sed
sed是一種流編輯器,一次處理一行內容。處理時把當前處理的行存儲在臨時緩沖區中,稱為“模式空間”,接著用sed命令處理緩沖區中的內容并將其輸出屏幕。
不斷重復直至文件末尾。
tips: 文件內容并無改變,除非使用重定向。
sed [選項參數] ‘command’ filename
| -e | 直接在指令列模式上進行sed的動作編輯 |
| a | 新增,a后面可接字符串,在下一行出現 |
| d | 刪除 |
| s | 查找并替換 |
tips:
a在前,d在后,如:sed "2a Shanghai" sed.txt,sed "/hh/d" sed.txt 。
1). 準備數據文件sed.txt
[xiaobai@hadoop100 datas]$ vim sed.txt welcome to China hh hha i am coming big data go go go!2). 將“Shanghai”插入到sed.txt第二行下面并打印出來:
[xiaobai@hadoop100 datas]$ sed "2a Shanghai" sed.txt welcome to China hh hha Shanghai i am coming big data go go go!注:原文件并未改變!只是改變控制臺輸出內容!
[xiaobai@hadoop100 datas]$ cat sed.txt welcome to China hh hha i am coming big data go go go!3). 刪除sed.txt 文件中包含hh的行:
[xiaobai@hadoop100 datas]$ sed "/hh/d" sed.txt welcome to China i am coming big data go go go!4). 將sed.txt 文件中hh替換為wa:
[xiaobai@hadoop100 datas]$ sed "s/hh/wa/g" sed.txt welcome to China wa waa i am coming big data go go go!tips: ’ g ’ 表示global全局替換,若不加g則替換第一個出現的字符。
5). 將sed.txt 文件中的第二行刪除并將go替換成come:
[xiaobai@hadoop100 datas]$ sed -e "2d" -e "s/go/come/g" sed.txt welcome to China i am coming big data come come come!9.3 awk
awk是一個強大的文本分析工具,將文件逐行讀入,以空格為默認分隔符將行切片,對切開的部分再進行分析處理。
awk [] 'pattern1{action1} pattern2{action2} … ’ filename
pattern: 表示awk在數據中查找的內容,就是匹配模式;
action: 在找到匹配內容時所執行的一系列命令
| -F | 指定輸入文件分隔符 |
| -v | 賦值一個用戶定義變量 |
1). 準備數據文件passwd:
[xiaobai@hadoop100 datas]$ sudo cp /etc/passwd ./passwd所屬權限為root,可更改為當前用戶xiaobai:
-rw-r--r--. 1 root root 2388 Sep 24 20:57 passwd [xiaobai@hadoop100 datas]$ sudo chown xiaobai:xiaobai passwd -rw-r--r--. 1 xiaobai xiaobai 2388 Sep 24 20:57 passwd2). 搜索passwd文件以root關鍵字開頭的所有行,并輸出第7列:
[xiaobai@hadoop100 datas]$ awk -F : '/^root/ {print $7}' passwd /bin/bash3). 搜索passwd文件以root關鍵字開頭的所有行,并輸出第1列和第7列,中間以“ , ” 分割:
[xiaobai@hadoop100 datas]$ awk -F : '/^root/ {print $1","$7}' passwd root,/bin/bashtips:
只有匹配了pattern的行才會執行action。
4). 只顯示/etc/passwd的第1列和第7列,以“ , ” 分割,且在首行前面添加列名“user,shell”; 在末尾一行添加"shell, /bin/hadoop" :
[xiaobai@hadoop100 datas]$ awk -F : 'BEGIN{print "user,shell"} {print $1","$7} END{print"shell,/bin/hadoop"}' passwd
**🌟注:**BEGIN表示在讀取所有數據行之前執行;END表示在所有數據行執行之后執行。
5). 將passwd文件中的用戶id增加數值1并輸出:
[xiaobai@hadoop100 datas]$ awk -F : -v i=1 '{print $3+i}' passwd 1 2 3 4 5 6 . . . 989 73 71 1001 1002 1003| FILENAME | 文件名 |
| NR | 已讀的記錄數 |
| NF | 瀏覽記錄的域的個數(切割后列的個數) |
1). 統計passwd文件名,每行的行號,每行的列數:
[xiaobai@hadoop100 datas]$ awk -F : '{print FILENAME "," NR "," NF}' passwd passwd,1,7 passwd,2,7 passwd,3,7 passwd,4,7 passwd,5,7 passwd,6,7 . . . passwd,40,7 passwd,41,7 passwd,42,7 passwd,43,7 passwd,44,7 passwd,45,7 passwd,46,72). 切割ip:
[xiaobai@hadoop100 datas]$ ifconfig ens33 | grep -w "inet" | awk -F " " '{print $2}' 192.168.31.100tips: 使用awk切割ip時,前面的8個空格又不算了😭,試出來的。
3). 查詢awk.txt中空行所在的行號:
[xiaobai@hadoop100 datas]$ vim awk.txt welcome to China hh hhai am coming big data go go go! [xiaobai@hadoop100 datas]$ awk '/^$/ {print NR}' awk.txt 39.4 sort ??
sort命令在Linux中非常有用,它將文件進行排序,并將排序結果標準輸出。
sort(選項)(參數)
| -n | 按照數值的大小排序 |
| -r | 以相反的順序來排序 |
| -t | 設置排序時所用的分割字符 |
| -k | 指定需要排序的列 |
參數:指定待排序的文件列表。
1). 準備數據文件sort.sh:
[xiaobai@hadoop100 datas]$ vim sort.sh a:10:4.1 b:23:3.2 c:54:2.6 d:10:6.7 e:36:8.9 f:65:2.0 g:76:5.82). 按照" : " 分割后的第三列倒序排序:
[xiaobai@hadoop100 datas]$ sort -t : -nrk 2 sort.sh g:76:5.8 f:65:2.0 c:54:2.6 e:36:8.9 b:23:3.2 d:10:6.7 a:10:4.1十、真題
有文件chengji.txt如下:
張三 40
李四 50
王五 60
使用Linux命令計算第二列的和并輸出:
測試已存在文件awk.txt:
測試未存在文件file.txt:
[xiaobai@hadoop100 datas]$ vim ifexist.sh #!/bin/bashif [ -f file.txt ]; thenecho "the file exist!" elseecho "the file is not exist!" fi [xiaobai@hadoop100 datas]$ bash ifexist.sh the file is not exist!對上述test.txt 無序文本進行排序并求和:
[xiaobai@hadoop100 datas]$ sort -n test.txt | awk '{a+=$0;print$0} END{print "sum="a}' 1 2 3 4 5 6 7 8 9 10 sum=55tips: $0表示第一列!
總結
以上是生活随笔為你收集整理的Shell脚本语言常用命令总结~的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vxworks 学习和windows a
- 下一篇: 继承、派生、组合