shell 是一种脚本语言。 脚本:本质是一个文件,文件里面存放的是 特定格式的指令,系统可以使用脚本解析器 翻译或解析 指令 并执行(它不需要编译) shell 既是应用程序 又是一种脚本语言(应用程序 解析 脚本语言)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 #!/bin/bash # 第一行主要用于指定解释器(包括:bin/sh、bin/bash、usr/bin/sh、usr/bin/bash) # 我是单行注释 # 执行脚本的方式有三种:sh test.sh、. test.sh、source test.sh # 决定路径执行:./test.sh,这种执行方式需要可执行权限,给脚本添加可执行权限:chmod 777 test.sh # ./test.sh 方式执行需要指定解释器 # 三种变量:局部变量、环境变量、shell变量 # 变量: name="hello" # 等号两边不能有空格 echo ${name} # 输出普通变量 function test() { local name="test hello" # 局部变量用local关键字修饰,local必须在函数中使用 echo ${name} } name="only_read" readonly name # readonly修饰符,修饰只读变量 echo $name # 或者 ${name} name1="name1" unset name1 # 删除变量,不能删除只读变量,删除后的变量无法被访问 # 单引号和双引号字符串的区别 name2='name2' # 单引号字符串,字符串内不能转义,不能包含变量 name3="name3\"${name2}" # 双引号字符串,字符串内可以有转义,也可以包含变量 echo ${name3} # 字符串拼接 str1="1""2""3"'4''5' # 字符串字面量拼接 str2='6' str3=${str1}${str2} # 字符串变量拼接 echo $str3 str4=`date`'==='$str3 # 命令拼接 echo $str4 # 获取字符串长度的5种方式 echo "hello" | wc -L # 1、wc -L 获取当前行的长度 expr length ${str3} # 2、使用expr length可以获取string的长度 echo "abc" |awk -F "" '{print NF}' # 3、awk获取域的个数 echo "Alex" |awk '{print length($0)}' # 4、通过awk+length的方式获取字符串长度 str5=Alex echo ${#str5} # 通5、过 ${#str5} 的方式获取字符串长度 # 提取字符串 str6=123456789.jpg echo ${str6##*56} # 从左向右截取最后一个string后的字符串 ,输出:789.jpg echo ${str6#*56} # 左向右截取第一个string后的字符串,输出:789.jpg echo ${str6%%56*} # 从右向左截取最后一个string后的字符串,输出:1234 echo ${str6%56*} # 从右向左截取第一个string后的字符串,输出:1234 echo ${str6:1:3} # 截取字符串,输出:234 # 数组 echo "====数组==== 数组越界不会报错" array=(1 2 3 4 5 6) echo ${array} # 输出数组,默认输出角标为0的数据 echo ${array[5]} # 输出数组角标为5的数据 array[0]=7 # 数组赋值 echo ${array} # 输出数组 array=([0]=0 [1]=1 [2]=2 [3]=3 [4]=4 [5]=5 [6]=6) # 数组初始化或赋值 echo ${array[6]} # 输出数组角标为6的数据 for((i=0;i<7;i++)) # for循环遍历数组 do echo "array[$i]=${array[$i]}" done echo ${array[*]} # 输出整个数组 echo "a len: ${#array[*]}" # 输出数组的长度 a=(1 2 3 4 5 6) b=("hello" "zhaixue.cc") c=(${a[*]} ${b[*]}) # 数组拼接 echo ${c[*]} # 输出整个数组 echo "c length: ${#c[*]}" # 输出:c length: 8 unset c[6] # 删除数组中的元素 echo "c length: ${#c[*]}" # 输出:c length: 7 # 参数传递 # $0 代表执行的文件名 # $1 代表传入的第1个参数 # $n 代表传入的第n个参数 # $# 参数个数 # $* 以一个单字符串显示所有向脚本传递的参数。 # $@ 与$*相同,但是使用时加引号,并在引号中返回每个参数 # $$ 脚本运行的当前进程号 # $! 后台运行的最后一个进程的ID # $? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 # 运算符 需注意:条件表法式需要放在方括号之间,并且要有空格。使用expr进行计算时需要使用反引号。 # 加法 expr $a + $b # 减法 expr $a - $b # 乘法 expr $a \* $b # 除法 expr $b / $a # 取余 expr $b % $a # 赋值 a=$b # 相等 [ $a == $b ] # 不相等 [ $a != $b ] a=10 b=20 c=`expr $a + $b` # 加法运算 echo "a + b : $c" # 关系运算符 # 关系运算符只支持数字,不支持字符串,除非字符串的值是数字。 # 关系用 [] 来表示, echo "====关系运算符====" a=1 b=2 # 检测两个数是否相等 [ $a -eq $b ] -eq if [ $a == $b ] then echo "a和b相等" else echo "a和b不相等" fi # 或者 if [ $a -eq $b ] then echo "a和b相等" else echo "a和b不相等" fi # 检测两个数是否不相等 [ $a -ne $b ] -ne if [ $a != $b ] then echo "a和b不相等" else echo "a和b相等" fi # 或者 if [ $a -ne $b ] then echo "a和b不相等" else echo "a和b相等" fi # 检测左边的数是否大于右边的 [ $a -gt $b ] -gt if [ $a -gt $b ] then echo "a大于b" else echo "a等于b或a小于b" fi # 检测左边的数是否小于右边的 [ $a -lt $b ] -lt if [ $a -lt $b ] then echo "a小于b" else echo "a等于b或a大于b" fi # 检测左边的数是否大于等于右边的 [ $a -ge $b ] -ge if [ $a -ge $b ] then echo "a大于等于b" else echo "a小于b" fi # 检测左边的数是否小于等于右边的 [ $a -le $b ] -le if [ $a -le $b ] then echo "a小于等于b" else echo "a大于b" fi # 布尔运算符 # 非运算 [ ! false ] ! # 或运算 [ $a -lt 20 -o $b -gt 100 ] -o # 与运算 [ $a -lt 20 -a $b -gt 100 ] -a # 逻辑运算符 # 逻辑的 AND [[ $a -lt 100 && $b -gt 100 ]] && # 逻辑的 OR [[ $a -lt 100 || $b -gt 100 ]] || # 布尔运算符和逻辑运算符的区别: # 语法上,逻辑运算需要双括弧,布尔运算只需要单大括弧功能上,逻辑运算具有特殊的短路功能, # 即是在AND运算中第一个表达式为false时则不执行第二个表达式, # 在OR运算中第一个表达式为true时不执行第二个表达式。 # 字符串运算符 # 检测两个字符串是否相等 [ $a = $b ] = # 检测两个字符串是否不相等 [ $a != $b ] != # 检测字符串长度是否为0 [ -z $a ] -z # 检测字符串长度是否不为 0 [ -n “$a” ] -n # 检测字符串是否为空 [ $a ] $ # 文件测试运算符 # 检测文件是否是块设备文件 [ -b $file ] -b file # 检测文件是否是字符设备文件 [ -c $file ] -c file # 检测文件是否是目录 [ -d $file ] -d file # 检测文件是否是普通文件(既不是目录,也不是设备文件) [ -f $file ] 返回 true -f file # 检测文件是否设置了 SGID 位 [ -g $file ] -g file # 检测文件是否设置了粘着位(Sticky Bit) [ -k $file ] -k file # 检测文件是否是有名管道 [ -p $file ] -p file # 检测文件是否设置了 SUID 位 [ -u $file ] -u file # 检测文件是否可读 [ -r $file ] -r file # 检测文件是否可写 [ -w $file ] -w file # 检测文件是否可执行 [ -x $file ] -x file # 检测文件是否为空(文件大小是否大于0) [ -s $file ] -s file # 检测文件(包括目录)是否存在 [ -e $file ] -e file file="/home/westos/Desktop/textcpp/test.sh" if [ -e $file ] then echo "文件存在" else echo "文件不存在" fi # 运算指令 # (( )) 可以直接使用双圆括弧计算其中的内容,如((var=a+b)) # let 在计算表达式的时候我们可以直接使用let,如let var=a+b。 # expr var=`expr a+b` echo $var # bc计算器 :bc计算器支持shell中的小数进行运算,并且可以交互式或者非交互式的使用 var=$(echo "(1.1+2.1)"|bc) echo $var # $[]: 计算中括弧中的内容,如echo $[1+2] # 控制语句 a=1 b=1 # if-fi if [ $a -eq $b ] then echo "a等于b" fi # if-else-fi if [ $a -eq $b ] then echo "a等于b" else echo "a不等于b" fi # if else-if else if [ $a -gt $b ] then echo "a大于b" elif [ $a -lt $b ] then echo "a小于b" else echo "a等于b" fi # for循环 for a in 1 5 3 4 do echo ${a} # 一次输出 1 5 3 4 done array=(1 2 3 4 5 6 7 8) for((i=0;i<8;i++)) # for循环遍历数组 do echo "array[$i]=${array[$i]}" done for loop in 1 2 3 4 5 do echo "The value is: $loop" done # while循环 a=1 b=4 while [ $a -lt $b ] do echo "${a}" let a++ done # 无限循环 # for (( ; ; )) # do # echo 111 # done # while true # do # echo 222 # done # until循环 # until 循环执行一系列命令直至条件为 true 时停止 a=1 until [ $a -gt 3 ] do echo "until循环:$a" let a++ done # 跳出循环 var=1 while(( $var < 5 )) do if(( $var>3 )) then echo "break跳出循环" break fi echo "$var" var=`expr $var + 1` done var=1 while(( $var < 5 )) do echo "$var" var=`expr $var + 1` if [ $var -gt 2 ] && [ $var -lt 4 ] then echo "continue跳出循环:$var" continue elif [ $var -eq 4 ] then echo "break跳出循环" break fi done # case-esac多选择语句 echo "====case-esac多选择语句====" var=100 case $var in # 分支语句开始 10) echo "输出10" ;; # 相当于break 100) echo "输出100" ;; # 相当于break esac # 分支语句结束 # select-in语句 # select in是shell中独有的一种循环,非常适合终端的交互场景,它可以显示出带编号的菜单, # 用户输入不同编号就可以选择不同的菜单,并执行不同的功能 echo "What is your favourite OS?" select var in "Linux" "Gnu Hurd" "Free BSD" "Other"; do echo "You have selected $var" break; done # 函数 function funName() { # function可以省略 echo "执行了funName函数" } funName # 执行函数 funWithParam(){ echo "第一个参数为 $1 !" echo "第十个参数为 ${10} !" } funWithParam 1 2 3 4 5 6 7 8 9 34 73 # 执行函数并传递参数 # 重定向 #一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件: # 1、标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。 # 2、标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。 # 3、标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。 # > 标准输出覆盖重定向:将命令的输出重定向输出到其他文件中 # >> 标准输出追加重定向:将命令的输出重定向输出到其他文件中 # >& 标识输出重定向:将一个标识的输出重定向到另一个标识的输入 # < 标准输入重定向:命令将从指定文件中读取输入而不是从键盘输入 # | 管道符,从一个命令中读取输出并作为另一个命令的输入 # 输入重定向 # 可以让命令从文件中获取,这样本来的命令需要从标准输入stdin中获取, # 转换为从我们的指定文件中获取。这样本来需要从键盘输入的命令就会转移到文件读取内容 # command1 < file # 0<1.txt cat # 重定向输入流 # 输出重定向 # 输出重定向也是将本来需要输出标准输出文件stdout中转化为我们的指定文件中 # cat 1.txt > 2.txt # 将1.txt的内容覆盖到2.txt # cat 1.txt 1> 2.txt # 将1.txt的内容覆盖到2.txt # cat 1.txt >> 2.txt # 将1.txt的内容追加到2.txt # cat 1.txt 1>> 2.txt # 将1.txt的内容追加到2.txt # 标准错误文件重定向 # 借助标准错误文件的文件描述符来重定向stderr # command 2>file # 将stdout标准输出文件和stderr标准错误文件合并重定向到一个指定文件中 # command > file 2>&1 # /dev/null 文件 # 如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null中, # /dev/null 是一个特殊的文件,写入到它的内容都会被丢弃; # 如果尝试从该文件读取内容,那么什么也读不到。 # 但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。 # command > /dev/null
原文链接:https://www.jianshu.com/p/4599ef826895