shell脚本基础知识
1.常见的shell内置变量有哪些?
变 量 | 含义 |
---|---|
$0 |
脚本名字 |
$1 |
位置参数 #1 |
$2 - $9 |
位置参数 #2 - #9 |
${10} |
位置参数 #10 |
$# |
位置参数的个数 |
"$*" |
所有的位置参数(作为单个字符串) (必须被引用起来, 否则默认为"$@ ") |
"$@" |
所有的位置参数(每个都作为独立的字符串) |
${#*} |
传递到脚本中的命令行参数的个数 |
${#@} |
传递到脚本中的命令行参数的个数 |
$? |
上一条命令返回值(0表示成功,可以echo输出查看) |
$$ |
脚本运行的当前进程ID(PID) |
$- |
传递到脚本中的标志(使用set) |
$_ |
之前命令的最后一个参数 |
$! |
运行在后台的最后一个作业的进程ID(PID) |
2.如何向脚本传递并使用参数 ?
./script argument1 argument2 argument3
在脚本中,$1引用第一个参数,$2引用第二个参数,依次类推;
$#可以计算向脚本传递的参数个数;
$*和$@都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数;
"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;"$@"和$@输出结果一致
脚本test.sh内容如下
#!/bin/bash echo '$*输出如下:' for var in $* do echo "$var" done echo '"$*"输出如下:' for var in "$*" do echo "$var" done echo '$@输出如下:' for var in $@ do echo "$var" done echo '"$@"输出如下:' for var in "$@" do echo "$var" done
传递参数执行: ./test.sh va1 va2 va3 ,输出结果如下:
$*输出如下: va1 va2 va3 va4 "$*"输出如下: va1 va2 va3 va4 $@输出如下: va1 va2 va3 va4 "$@"输出如下: va1 va2 va3 va4
3.文件类型的测试操作有哪些?
操作 | 测试条件 | 操作 | 测试条件 |
---|---|---|---|
-e |
文件是否存在 | -s |
文件大小不为0 |
-f |
是一个标准文件 | ||
-d |
是一个目录 | -r |
文件具有读权限 |
-h |
文件是一个符号链接 | -w |
文件具有写权限 |
-L |
文件是一个符号链接 | -x |
文件具有执行权限 |
-b |
文件是一个块设备 | ||
-c |
文件是一个字符设备 | -g |
设置了sgid标记 |
-p |
文件是一个管道 | -u |
设置了suid标记 |
-S |
文件是一个socket |
-k |
设置了"粘贴位" |
-t |
文件与一个终端相关联 | ||
-N |
从这个文件最后一次被读取之后, 它被修改过 | F1 -nt F2 |
文件F1比文件F2新 * |
-O |
这个文件的宿主是你 | F1 -ot F2 |
文件F1比文件F2旧 * |
-G |
文件的组id与你所属的组相同 | F1 -ef F2 |
文件F1和文件F2都是同一个文件的硬链接 * |
! |
"非" (反转上边的测试结果) |
4.如何获取一个文件指定行列(第x行第y列)的内容?
awk 'NR=x{print $y}' filename
更多awk相关可以参考awk命令入门 - 博客园 (cnblogs.com)
5.如何在后台运行脚本或命令?
nohup command&
6.shell中单引号、双引号、反引号有什么区别?
'(单引号):会原样输出单引号内所有内容;即使单引号里使用了变量等也不会进行解析;
"(双引号):会把双引号内的内容输出出来;如果内容中有命令、变量等,会先把变量、命令解析出结果,再输出最终内容来;
`(反引号):一般用于命令,执行的时候会获取命令结果,相当于$()。
7.shell脚本中变量自增(i=i+1)的写法?
一般写在循环内配合条件来自增:
① i=$(( $i + 1 ))
② i=$[$i+1]
③ ((i++))
④ let i+=1
⑤ i=`expr $i + 1` (注意空格)
8.shell脚本中有哪些循环?
①for循环:
1 for i in list 2 do 3 command... 4 done
list可以理解为一个数组,可以是命令返回的结果等;也可以是自定义的如 1 2 3 4 5等等;
②while循环:
1 while [ condition ] 2 do 3 command... 4 done
③until循环:
until是条件不满足就一直执行循环体代码块内的指令,条件满足就会退出开始执行后面的命令
1 until 循环条件 2 do 3 command... 4 done
eg1:监控用户是否登录,如果用户登录则杀死对应进程并结束
1 until pgrep -u user1 &> /dev/null;do 2 3 sleep 1 4 5 done 6 7 pkill -9 -u user1
eg2:使变量递增直到其值大于10
1 val=0; 2 until ((val>10)) 3 do 4 let val+=1; 5 done 6 echo $val
④select循环:
select variable in list do 循环体命令 done
1.select 循环主要用于创建菜单,按数字顺序排列的菜单项将显示在标准错误上,并显示PS3 提示符,等待用户输入;
2.用户输入菜单列表中的某个数字,执行相应的命令
3.用户输入被保存在内置变量 REPLY 中
4.select 是个无限循环,因此要记住用 break 命令退出循环,或用 exit 按 命令终止脚本。也可以按 ctrl+c退出循环
5.select 和 经常和 case 联合使用
6.与for循环类似,可以省略 in list, 此时使用位置参量
eg:
PS3="请输入你需要选择的菜单序号:" select menu in 米饭 包子 饺子 面条 quit;do case $REPLY in 1|2) echo "你选择的是米饭或包子,价格为3元每份。" ;; 3|4) echo "你选择的是饺子或面条,价格为10元每份。" ;; 5) break ;; *) echo "没有这个选项,请重新选择!!!" esac done
9.shell中如何获取变量长度以及如何截取变量?
假定var为变量:
${#var}可以获取变量长度
截取变量的方法:
① ${var:x:y} 表示从左边第x个字符开始,截取y个字符(ps:这里左边起始位置是从0开始);
如执行var=123456789 && echo ${var:2:3} 输出结果为345
② ${var:x} 表示从左边第x个字符开始,一直到结束;
如执行var=123456789 && echo ${var:2} 输出结果为3456789
③ ${var#*//} 其中 # 是运算符,*// 表示从左边开始删除第一个 // 号及左边的所有字符;
如执行var=http://www.name.com/test.html && echo ${var#*//} 输出结果为 www.name.com/test.html
④ ${var##*/} 表示从左边开始删除最后(最右边)一个 / 及左边的所有字符;
如执行var=http://www.name.com/test.html && echo ${var##*/} 输出结果为 test.html
⑤ ${var%/*} 表示从右边开始,删除第一个 / 号及右边的字符;
如执行var=http://www.name.com/test.html && echo ${var%/*} 输出结果为 http://www.name.com
⑥ ${var%%/*} 使用%%截取(删除右边字符,保留左边字符);表示从右边开始,删除最后(最左边)一个 / 号及右边的字符;
如执行var=http://www.name.com/test.html && echo ${var%%/*} 输出结果为 http:
⑦${var:0-9:4} 其中的 0-9 表示从右边第9个字符开始,4表示要截取字符的位数(ps:从右边开始的第一个字符用 0-1 表示)
如执行 var=http://www.name.com/test.html && echo ${var:0-9:4} 输出结果为 test
⑧${var:0-9} 其中的 0-7 表示从右边第9个字符开始,截取右边所有
var=http://www.name.com/test.html && echo ${var:0-9} 输出结果为 test.html
10.shell脚本中的四则运算
shell中进行数学运算有以下形式:
①使用expr,表达式和运算符之间要有空格,完整的表达式要被 ` `(即反引号) 包含
若是使用expr来进行乘法运费,需要在*前添加\ 以便shell识别
eg:
#!/bin/bash a=100; b=200; c=`expr $a - $b` echo $c
②$((a+b))
a=100; b=200; d=$((a*b)); echo $d
③$[$a*$b]
#!/bin/bash a=100; b=200; e=$[$a*$b] echo $e