1 Linux shell腳本編程: 2 守護進程,服務進程:啟動?開機時自動啟動: 3 互動式進程:shell應用程式 4 5 廣義:GUI,CLI 6 GUI: 7 CLI: 8 詞法分析:命令,選項,參數 9 內建命令: 10 外部命令:PATH 11 fork()創建為一個進程: 12 13
1 Linux shell腳本編程: 2 守護進程,服務進程:啟動?開機時自動啟動: 3 互動式進程:shell應用程式 4 5 廣義:GUI,CLI 6 GUI: 7 CLI: 8 詞法分析:命令,選項,參數 9 內建命令: 10 外部命令:PATH 11 fork()創建為一個進程: 12 13 把要運行的一系列命令,寫在文件中: 14 腳本或程式源文件:文本文件 15 兩種方式: 16 編譯執行:預處理---->編譯---->彙編---->鏈接:事先完成,結果:二進位程式文件 17 C,C++ 18 解釋執行:由解釋器全程參與運行過程,每次讀取一行,運行一行; 19 Python:程式庫 20 程式控制結構:調用編程庫完成編程編寫; 21 庫文件:功能模塊,在編程中可調用;通過其API:應用編程介面; 22 Bash:程式 23 程式控制結構,調用機器上命令程式文件進行編程編寫; 24 外部命令:各應用程式提供; 25 程式:指令+數據 26 演算法+數據結構 27 28 過程式編程:以指令為中心,設計演算法,數據服務於演算法; 29 對象式編程:以數據為中心,設計數據結構(類),程式服務於數據結構; 30 31 bash過程式編程: 32 順序執行:逐個執行 33 選擇執行:只執行其中一個分支 34 循壞執行:一段代碼要執行0,1或多遍 35 36 編程元素:變數、流程、函數 37 38 變數:可變化的量,命名記憶體空間 39 40 bash環境: 41 本地變數:當前shell進程; 42 環境變數:當前shell進程及其子進程; 43 局部變數:某個函數執行過程; 44 位置參數變數:在腳本中引用傳遞給腳本的參數;在函數中引用傳遞給函數的參數; 45 特殊變數:$?,$*,$@,$#,$$ 46 47 變數類型: 48 數值,字元: 49 50 數值: 51 整數 52 浮點數 53 字元: 54 ASCII 55 120: 56 字元:1, 2 , 0 57 數值:120 ---> 58 59 變數類型的作用: 60 存儲空間 61 運算格式 62 63 語言對變數類型的支持力度: 64 強類型: 65 弱類型:變數類型不嚴格區分; 66 預設存儲機制:bash為字元 67 68 bash的變數使用特點:弱類型、無需事先說明; 69 70 本地變數: 71 name=value 72 name:變數名 73 =:賦值符號 74 value:值 75 76 變數名:只能包含數字、字母和下劃線:且不能以數字開頭; 77 引用變數:${name},name 78 例: 79 [root@localhost ~]# animal="panao" 80 [root@localhost ~]# echo ${animal} 81 panao 82 引用: 83 弱引用:"",其內部的變數引用會替換為變數值; 84 強引用:'',其內部的變數引用會保持原有字元; 85 命令引用:`COMMAND`,$(COMMAND),引用命令的執行結果; 86 87 聲明為整型: 88 declare -i name[=value] 89 let name=value 90 91 生命周期: 92 創建 93 銷毀: 94 自動銷毀:shell進程終止; 95 手動銷毀:unset name 96 例: 97 [root@localhost ~]# unset animal 98 99 環境變數: 100 被"導出"的本地變數 101 export name[=value] 102 declare -x name[=value] 103 104 查看所有環境變數:env,printenv,export 105 106 銷毀: 107 unset name 108 109 腳本:文本文件 110 運行腳本:事實上是運行一個bash進程,此進程負責從腳本文件中讀取一個執行邏輯,而後有bash進程負責解析並運行此邏輯; 111 啟動腳本: 112 (1) #bash /PATH/TO/SCRIPT_FILE 113 (2)一個執行許可權, 114 # ./PATH/TO/SCRIPT_FILE 115 116 shebang: 117 #!/bin/bash 118 119 第一行:頂格給出shebang 120 註釋行:# 121 122 bash的常用選項: 123 -n:檢查腳本中的語法錯誤; 124 -x:調試執行腳本; 125 126 命令的狀態結果: 127 bash進程用於追蹤執行的命令成功與否的狀態; 128 0:成功 129 1-222:失敗 130 131 特殊變數: 132 $?:上一條命令的執行狀態結果; 133 例: 134 [root@localhost bin]# echo $? 135 0 // 0表示成功 136 137 138 布爾型: 139 "真":成功 140 "假":失敗 141 142 自定義腳本的狀態結果: 143 exit[n] 144 145 註意:腳本中任何位置執行了exit命令即會終止當前shell進程; 146 147 條件測試: 148 界定程式執行環境: 149 150 (1)根據運行的命令的狀態結果; 151 (2)測試表達式 152 test EXPRESSION 153 [ EXPRESSION ] //括弧兩邊必須有空格 154 [[ EXPRESSION ]] //括弧兩邊必須有空格 155 156 整數測試:隱含著做數值大小比較,所以不要給變數引用加引用; 157 $A -gt $B:是否大於:是則為"真",否則為"假"; 158 $A -ge $B:是否大於等於; 159 $A -lt $B:是否小於; 160 $A -le $B:是否小於等於; 161 $A -eq $B:是否等於; 162 $A -ne $B:是否不等於; 163 字元串測試:ASCII數值越大,字元比較時其值越大 164 "$A" > "$B":是否大於; 165 "$A" < "$B":是否小於; 166 "$A" == "$B":是否等於; 167 "$A" != "$B":是否不等於; 168 -z "$A":是否為空;空則為"真",否則為"假" 169 -n "$A":是否不空;不空則為"真",空則為"假" 170 171 註意:應該使用[[ EXPRESSION ]] 172 173 文件測試:測試文件的存在性以及屬性; 174 -e $file:是否存在,存在則為"真",否則為"假" 175 -a $file:同上 176 -f $file:文件是否存在且為普通文件; 177 -d $file:文件是否存在且為目錄; 178 -h $file:是否存在且為符號鏈接文件; 179 -L $file:同上; 180 -b $file:是否存在且為塊設備文件; 181 -c $file:是否存在且為字元設備文件; 182 -S $file:是否存在且為套接字文件; 183 -p $file:是否存在且為管道文件; 184 185 -r $file:當前用戶對文件是否擁有讀許可權; 186 -w $file:當前用戶對文件是否擁有寫許可權; 187 -x $file:當前用戶對文件是否擁有執行許可權; 188 189 -u $file:文件是否擁有SUID許可權; 190 -g $file:文件是否擁有SGID許可權; 191 -k $file:文件是否擁有sticky許可權; 192 193 -O $file:當前用戶是否為指定文件的屬主; 194 -G $file:當前用戶是否為指定文件的屬組; 195 196 雙目操作符: 197 $file1 -nt $file2:file1是否新於file2,file1的最近一次的修改時間是否晚於file2的; 198 $file1 -ot $file2:file1是否舊於file2,file1的最近一次的修改時間是否早於file2的; 199 $file1 -ef $file2:file1與file2是否指向了同一個inode:測試二者是否為同一個文件的硬鏈接; 200 201 202 203 特殊設備: 204 /dev/null:空,bit buckets,吞下所有數據,並直接丟棄; 205 /dev/zero:突出一堆0: 206 207 bash之條件判斷(選擇執行): 208 if/then,case 209 210 if CONDITTION;then 211 if-true-分支 212 fi 213 214 if CONDITTION;then 215 if-true-分支 216 else 217 if-false-分支 218 219 !CONDITTION:取反 220 221 練習:寫一個腳本 222 如果其路徑不存在,則將其創建為目錄,否則顯示其存在,並顯示內容類型; 223 224 #!/bin/bash 225 # 226 filename="/tmp/x/y/z/testdir" 227 if [ -e $filename ];then 228 echo "$filename exists." 229 file $filename 230 else 231 mkdir -p $filename 232 fi 233 ~ 234 ~ 235 腳本參數(位置參數變數): 236 ./script.sh /etc/fstab /etc/grub2.cfg 237 $0 $1 $2 238 239 位置參數變數:$1,$2,.... 240 ${10} 241 242 特殊變數: 243 $?:命令的狀態結果; 244 $#:傳遞給腳本或函數的參數個數; 245 $*和$@:引用傳遞給腳本或函數的參數列表; 246 247 shift:[n]:輪替 248 249 與用戶交互: 250 read命令: 251 read [option] VAR... 252 -p "PROMPT" 253 -t timeout 254 示例: 255 256 #!/bin/bash 257 # 258 259 read -p "Plz enter a username: " -t 5 username 260 261 if [ -z "$username" ]; then 262 username="myuser" 263 fi 264 265 if id $username &> /dev/null; then 266 echo "$username exists." 267 else 268 useradd $username 269 fi 270 271 272 273 命令引用: 274 `COMMAND`,$(COMMAND) 275 276 引用命令的執行結果: 277 (1)ls `which cat` 278 (2)lines=$(wc -l /etc/fstab | cut -d '' -f1) 279 280 #!/bin/bash 281 # 282 if [ -f $1 ]; then 283 lines=$(wc -l $1 | cut -d' ' -f1) 284 echo "$1 has $lines lines." 285 else 286 echo "$1 not exists or not a file." 287 fi 288 289 練習:寫一個腳本,完成如下功能: 290 判斷給定的兩個數值,孰大孰小; 291 給定數值的方法:腳本參數,命令交互; 292 代碼如下: 293 294 1 #!/bin/bash 295 2 # 296 3 read -p "Plz enter two integer: " -t 10 num1 num2 297 4 298 5 if [ -z "$num1" ];then 299 6 echo "Plz give two integers." 300 7 exit 1 301 8 fi 302 9 303 10 if [ -z "$num2" ];then 304 11 echo "Plz give two integers." 305 12 exit 1 306 13 fi 307 14 308 15 if [$num1 -ge $num2 ];then 309 16 echo "Max: $num1,Min;$num2." 310 17 else 311 18 echo "Max:$num2,Min:$num1." 312 19 fi 313 迴圈語句: 314 for,while,until 315 316 迴圈:將循壞體代碼執行0、1或多次; 317 進入條件:進入迴圈的條件; 318 退出條件:迴圈終止的條件; 319 320 for VARIABLE in LIST;do 321 迴圈體 322 done 323 324 LIST:是由一個或多個空格分隔開的字元串組成; 325 把列表的每個字元串逐個賦值給VARIABLE表示的變數; 326 327 for username in user1 user2 user3;do 328 迴圈體 329 done 330 331 進入條件:列表非空 332 退出條件:列表遍歷結束; 333 334 添加5個用戶: 335 #!/bin/bash 336 # 337 for username in user1 user2 user3 user4 user5; do 338 if id $username &> /dev/null; then 339 echo "$username exists." 340 else 341 useradd $username 342 echo "Add user $username finished." 343 fi 344 done 345 LIST的生成方法: 346 (1)整數列表 347 (a){start..end} 348 (b)$(seq start [[step]end]) 349 (2)直接給出 350 (3)glob 351 (4)根據命令生成 352 353 354 示例:數值列表 355 #!/bin/bash 356 # 357 for i in {1..10}; do 358 if id user$i &> /dev/null; then 359 echo "user$i exists." 360 else 361 useradd user$i 362 echo "Add user user$i finished." 363 fi 364 done 365 366 示例:glob 367 #!/bin/bash 368 # 369 for filename in /var/log/*; do 370 file $filename 371 done 372 373 示例:命令生成列表 374 #!/bin/bash 375 # 376 for username in $(cut -d: -f1 /etc/passwd); do 377 echo "$username primary group: $(id -n -g $username)." 378 done 379 ~ 380 381 算術運算: 382 +,-,*,%,** 383 384 sum=$a+$b 385 (1)$[$A+$B] 386 (2)$(($A+$B)) 387 (3)let VARIABLE=$A+$B 388 (4)VARIABLE$(expr $A + $B) 389 390 示例: 391 392 [root@localhost bin]# a=6 393 [root@localhost bin]# b=7 394 [root@localhost bin]# sum=$a+$b 395 [root@localhost bin]# echo $a+$b 396 6+7 397 [root@localhost bin]# echo $[$a+$b] 398 13 399 [root@localhost bin]# let $a+$b 400 [root@localhost bin]# let sum=$a+$b 401 [root@localhost bin]# echo $sum 402 13 403 [root@localhost bin]# expr $a + $b 404 13 405 406 示例:求100以內正整數之和; 407 #!/bin/bash 408 # 409 declare -i sum=0 410 411 for i in {1..100}; do 412 sum=$[$sum+$i] 413 done 414 415 echo $sum 416 417 練習:求100以內所有偶數之和; 418 使用至少三種方法實現;