Linux shell的一些特性

来源:互联网 发布:如何使用淘宝冰点营销 编辑:程序博客网 时间:2024/04/29 06:24
    1.变量替换及应用


${var:-word}              如果var存在且非空,则返回var,否则返回word但是不替换var
${var:+word}             如果var存在且非空,则返回word(不替换var),否则返回var
${var:=word}             如果var存在或为空,则返回var,否则返回word且替换var
${var:?message}       如果var存在且非空,返回var,否则返回"var:message"这个字符串
${var:offset}               在var中提从offset到其末尾的子字符串
${var:offset:length}    在var中从offset开始提取length长的子字符串
${var#pattern}           返回删除掉var中开头pattern最短匹配后剩余的字符串
${var##pattern}         返回删除掉var中开头pattern最长匹配后剩余的字符串
${var%pattern}          返回删除掉var中结尾pattern最短匹配后剩余的字符串
${var%%pattern}       返回删除掉var中结尾pattern最长匹配后剩余的字符串
${var/pattern/string} 用string替换var中开头pattern的最短匹配
${var//pattern/string} 用string替换var中开头pattern的最长匹配


例子:
${*:-.}                如果没有提供位置参数则使用当前目录
${path##*/}       从全路径中获取基本文件名,等价于basename(外部程序没shell内置机制效率高)
${path%/*}        获取目录名,等价于dirname(外部程序没shell内置机制效率高)


    2.命令替换及应用


$(command)
`command`


ROOT=`pwd` <=> ROOT=$(pwd)


    3.数学运算


let i=i+1 bash             内置变量(不能加空格)
((i += 2))                     运算符可用空格隔开
i=`expr 3 \* 5`              注意需要转义符
i=$(expr 3 \* 5)
i=`echo "scale=2; $TSIZE/$SSIZE*100" | bc -l`       bc命令不一定每个linux用户都安装了
declare -i a=1 b=2;declare c=a+b           声明称整数来计算


    4.数组及应用


数组初始化:
var[index]=value           整数做下标
var[string]=value            字符串做下标
var=(value1 value2 ...)   空格隔开


清空数组:
var=
unset var
unset var[value]


引用数组数据:
${var}                     引用不带下标的数组,得到数组第一个元素
${var[variable]}      下标使用变量时不需要美元符号引用
${var[@]}                得到数组所有元素
${var[*]}                 得到数组所有元素
${#var[@]}             得到数组元素个数
${#var[*]}               得到数组元素个数


    5.特殊变量


$$ 当前shell的PID
$! 在后台运行的最后一个作业的PID
$? 关于上个执行指令的回传码
$0 当前shell的名字
$n (n:1-) 位置参数
$# 参数个数
$* 所有位置参数组成的单一字符串
$@ 每个位置参数的字符串组合成的


$*和$@的区别
$*将所有位置参数作为单一字符串
$@是所有位置参数的字符串组合


function "$*"           函数参数只有一个
function "$@"        函数参数有多个


    6.命令行选项


通常使用getopts,第一个冒号表示用户键入错误选项时不提示
$OPTARG表示选项对应的参数值,$OPTIND表示命令行选项的索引


模板:
while getopts ":X1:X2:..." opt;do
case $opt in
   x1) value_x1=$OPTARG;;
   X2) ..;;
esac
done
shift $(($OPTIND-1))


    7.命令行解析


一个shell命令行的完整处理过程:


1).将输入分隔成记号(记号包括单词,关键字,I/O定向符,分号等)
2).检测每个命令的第一个记号,若为开发关键字(像if等)则继续匹配一个完整的符合命令,重复处理完成,返回步骤1。
3).别名检测(检测第一个记号是别名就进行替换,返回步骤1)
4).大括号扩展(a{b,c}扩展为ab ac)
5).~符号扩展(如果存在替换为$HOME)
6).变量(参数)替换(以$开头的表达式)
7).命令替换(对$(string)形式进行)
8).算术替换(对$((string))进行计算)
9).单词分隔(使用$IFS中的字符分隔参数,命令,算术替换中的部分成单词)
10).路径名扩展(通配符扩展,例如*,/等)
11).命令查询(函数>内置命令>脚本和可执行程序)
12).运行命令(设置完I/O重定向后执行命令)


单引号‘’(绕过前10个步骤)
单引号中的命令只能执行路径扩展,命令查找


双引号""(绕过步骤1~5,9,10)
双引号中可以使用参数替换,命令替换,算术替换


命令查找顺序可以用command,builtin,enable来修改
command删除别名和函数查找
builtin只查找内置命令
enable -a显示所有命令及其是否可用


eval通知shell接受eval参数,并再次通过命令行处理的所有步骤来运行
所以被绕过的步骤可以重新解析


shell解析命令顺序
别名>关键字>函数>内置命令>脚本和可执行程序


    8.进程控制


作业编号指当前运行在用户shell下的后台进程(不同shell窗口下的作业毫无关系)
进程ID指当前运行在整个系统上的所有用户的进程


作业控制:


jobs -l列出作业的完整信息


引用后台作业的方式:
fg %N            作业编号N
fg %string     作业命令名以string开始的作业
fg %?string   作业命令包含的string的作业
fg %+           最近被调用的后台作业(引用被放到后台的最新作业)
fg %%          同上
fg %-            第二个最近被调用的后台作业
fg (不带%)    作业进程ID


使用的作业控制的好处:
有可能前台的作业运行时间很长,而你还想用控制终端做其他操作,这是就可以将其放到后台
CTRL-Z即将当前作业放到后台


kill用法:
kill参数可以使进程ID,作业编号,进程命令名
kill默认发送TERM信号到目标,但可以改变所发信号类型
kill -l 列出支持的所有信号名称和编号列表
CTRL-C   INIT
CTRL-\     QUIT
CTRL-Z   TSTP
kill   TERM


stty signame char可以绑定信号到什么控制键上 例如:stty intr ^X


kill         %作业编号
kill           进程ID
kill          进程名
kill          信号类型 参数


协同程序:
shell命令行下协同,执行命令之间使用&即可
脚本里面,最后必须加上wait命令保证所有后台作业都完成


模式:
命令1 &
...
命令2
wait


进程使用系统资源的特性:CPU密集型,I/O密集型,交互式


对于I/O密集型使用一个大型计算的作用会较好
对于CPU密集型,多通过shell并发执行回提高效率


当在一个多CPU计算机上启动一个后台作业时,计算机会将其赋予到下一个可用处理器
这意味着两个作业时间上运行在同一时刻,所有能提升效率


子shell:
子shell继承的东西:
1)当前目录
2)环境变量
3)标准输入,标准输出,标准错误,以及其他任何打开的文件描述符
4)被忽略的信号(trap)
未继承的东东:
1)shell变量(除了环境变量和定义在环境文件中.bashrc的变量)
2)没被忽略的信号处理


exec精髓,替换本shell来执行exec参数中的命令对本shell一直发生影响
exec 2>errlog 把脚本中所有错误写到errlog文件中(放在脚本开头)
exec switch_root /newroot "/sbin/init" 启动脚本中常常见到
原创粉丝点击