Linux shell脚本编程(一)
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 使用至少三种方法实现;
########## 今天的苦逼是为了不这样一直苦逼下去!##########