shell 知识基础要点 非讲解

来源:互联网 发布:网络起名可靠吗 编辑:程序博客网 时间:2024/06/04 15:45


正则表达式
* 0个或多个之前的那个普通字符
. 匹配任意字符
^ 匹配行首,或者后面字符的非
$ 匹配行尾
[] 匹配字符集合
\<\> 精确匹配括号
\{n\} 匹配前面字符n次
\{n,\} 匹配前面字符至少n次
\{n,m\} 匹配前面字符至少m次


扩展
? 匹配0个或1个之前的那个普通字符
+ 匹配1个或多个之前的哪个普通字符
() 表示一个字符集合或者用在expr中
| 表示“或”,匹配一组可选的字符


=================================================


grep
-c 只输出匹配行的数量
-i 忽略大小写
-l 只列出符合匹配的文件名
-n 列出所匹配的行和行号
-s 不显示错误信息
-v 显示不包含匹配文本的所有行
-w 匹配整词
-x 匹配整行
-r 递归搜索




=================================================


sed
-n 不打印所有行到标准输出
-e 表示下一个字符串为sed编辑命令
-f 表示调用sed脚本文件
-i[SUFFIX] 在原文件修改, 有SUFFIX则备份


文本定义方法
x 定位x行
x,y 定位x,y行
/pattern/ 查询包含模式的行
/pattern/pattern/ 查询包含两个模式的行
/pattern/,x 查询从模式匹配行到x行
x,/pattern/ 查询从x行到模式匹配行
x,y! 查询不包含从x到y行的行


编辑命令
p 打印匹配行
= 打印行号
a\ 在定位行号之后追加文本
i\ 在定位行号之前加入文本
d 删除定位行
c\ 用新文本替换定位行
s 替换
    g 替换所有匹配
    p 打印替换行
    w 输出定向到一个文件
r 在匹配行之后插入文件
w 将匹配行输出到一个文件
y 替换字符
l 显示非打印字符
q 第一个匹配完成后退出
{} 执行命令组';'间隔
n 读取下一行,用下一个命令处理新行
h 将模式缓存区的内容复制到保持缓存区
H 将模式缓存区的内容追加到保持缓存区
x 互换模式缓存区和保持缓存区的内容
g 将保持缓存区的内容复制到模式缓存区
G 将保持缓存区的内容追加到模式缓存区


sed 命令是把输入的行存在模式缓存区,然后进行编译,再输出。


=================================================


awk 没有用过,这个听说在生成报告的时候比较常用。


awk编程模型
BEGIN程序段
处理程序段
END程序段


调用方法
1. awk [option] '程序段' 输入文件
2. awk -f 脚本 输入文件
3. ./脚本 输入文件


awk的程序段由 pattern action 组成
awk '/^$/ {print "blank line"}' inputfile


record:输入的每一行
field:在record中由分隔符分隔形成
$0 所有域
$n 第n个域


作用于模式匹配的关系和布尔运算符
< > <= >= == != ~(匹配) !~(不匹配)
|| && !


变量操作
赋值 =
算术运算符
+ - * / % ^或**(乘方) ++x x++


系统变量
$n 当前记录的第n个域,域间由FS分割
$0 记录的所有域
ARGC 命令行参数的数量
ARGIND 命令行中当前文件的位置(以0开始标号)
ARGV 命令行参数的数组
CONVFMT 数字转换格式
ENVIRON 环境变量关联数组
ERRNO 最后一个系统错误的描述
FIELDWIDTHS 字段宽度列表,以空格键分隔
FILENAME 当前文件名字
FNR 浏览文件的记录数
FS 字段分隔符,默认为空格
IGNORECASE 布尔变量,如果为真,则进行忽略大小写的匹配
NF 当前记录中的域数量
NR 当前记录数
OFMT 数字输出格式
OFS 输出域分隔符,默认空格
ORS 输出记录分隔符,默认换行
RLENGTH 由match函数所匹配的字符串长度
RS 记录分隔符,默认空格?默认不是换行吗?
RSTART 由match函数所匹配的字符串的第1个位置
SUBSEP 数组下表分隔符,默认值是\034


格式化输出
printf (格式控制符,参数)


格式修饰符
- 左对齐,默认是右对齐
width 域的步长
.prec 小数点右边的位数


格式符
%c ASCII字符
%d 整型数
%e 浮点数,科学记数法
%f 浮点数
%o 八进制数
%s 字符串
%x 十六进制数


内置字符串函数
gsub(r,s) 在输入文件中用s替换r
gsub(r,s,t) 在t中用s替换r
index(s,t) 返回s中字符串第一个r的位置
length(s) 返回s的长度
match(s,t) 测试s是否包含匹配t的字符串
split(r,s,t) 以字符串t为分隔符,将r字符串拆分为字符串数组,存于s中
sub(r,s,t) 将t中第一次出现的r替换为s
substr(r,s) 返回字符串r中从第s个字符开始的后缀部分
substr(r,s,t) 返回字符串r中从第s个字符开始长度为t的后缀部分


awk脚本中的变量可以在命令行赋值,实现向脚本传递参数,变量赋值放在脚本之后,输入文件之前。
BEGIN字段不能访问命令行参数


if (condition)
    action
[else
    action]


while (condition)
    action


do
    action
while(condition)


for(;;)
    action


数组
awk的所有数组是关联数组。索引和元素一一对应。索引可以是字符串
array[index]=value
赋值后直接使用
for (variable in array)
    do something with array[variable]




=================================================


sort
默认按第一域字符序排序
-c 测试文件是否已经排序
-k 指定排序的域
-m 合并两个已排序的文件
-n 根据数字大小排序
-o file 输出到指定文件
-r 逆序显示结果
-t 改变域分隔符
-u 去除结果中重复的行


=================================================


uniq
默认去除连续重复的行
-c 打印每行重复出现的次数
-d 只显示有重复的记录
-u 只显示没有重复的记录


=================================================


join
默认以第一个域用于连接,只显示连接的记录结果
-a1或-a2 除了显示连接结果,-a1表示还显示第一个文件中未连接的记录,-a2表示还显示第二个文件中未连接的记录
-i 比较域内容时,忽略大小写
-o 设置输出记录格式,-o1.1 2.2 1.2表示结果记录有3个域依次是第一个文件第一个域,第二个文件第二个域,第一个文件第二个域
-t 改变域分隔符
-v1或-v2 与-a1 -a2类似,只是不显示连接的记录结果
-1或-2 -1 3 表示第一个文件以第三个域作为连接域,-2 1表示第二个文件以第一个域作为连接域


=================================================


cut
-c 指定提取的字符数和字符范围
-f 指定提取的域数或域范围
-d 改变域分隔符


=================================================


paste
默认将两个文件竖着放,即新文件的每一行为两个文件相同行的组合
-d 设置每一行组合时使用的分隔符
-s 将两个文件改为横着放
- 从标准输入读取数据, 一个-表示一个域。


=================================================


split
-或-l 指定切割成的小文件的行数
-b 指定切割成小文件的字节数
-C 与-b选项类似,但是,切割时尽量维持每行的完整性


=================================================


tr
只能从标准输入读取数据,默认功能将数据中出现在字符串1中的字符替换为字符串2中的字符
-c 选定字符串1中字符集的补集
-d 删除字符串1中出现的字符
-s 删除所有连续重复出现的字符序列,只保留一个
tr 支持的控制字符
\a \007 Ctrl+G 铃声
\b \010 Ctrl+H 退格符
\f \014 Ctrl+L 走行换页
\n \012 Ctrl+J 换行符
\r \015 Ctrl+M 回车符
\t \011 Ctrl+I Tab建




=================================================


变量
shell脚本的变量是字符型,当进行算术运算时,如果变量只包含数字,则作为数值型进行运算,否则作为字符型,字符型的数值为0
$为变量替换符号,variable代表变量,$variable就代表变量的值。
赋值 variable=value
引用 echo $variable
清除 unset variable
声明环境变量
ENVIRON_VARIABLE=value
export ENVIRON_VARIABLE


位置参数
$0 脚本名
$n 第n个参数,大于9要写${n}
$# 传递到脚本的参数数量
$*和$@ 传递到脚本的所有参数
$$ 脚本运行的进程号
$? 前一个命令的退出状态,0为没有错误。


引用
"" 引用除美元符号($)、反引号(`)和反斜杠(\)之外的所有字符
'' 引用全部字符
\ 转义字符




变量计算
let "expression" let命令用来进行变量的数值计算


算术运算符
+加 -减 *乘 /除 %取余 **幂运算
+= -= *= /= %=
位运算符
<<左移 >>右移 &与 |或 ~非 ^异或
<<= >>= &= |= ^=
++自增 --自减


数字常量
默认十进制, 0前缀八进制 0x前缀十六进制
n#前缀n进制


declare [选项] variable
-r 将变量设置为只读
-i 将变量定义为整型数
-a 将变量定义为数组
-f 显示此脚本目前定义的所有函数名及内容
-F 仅显示从脚本目前定义的所有函数名
-x 将变量声明为环境变量
定义为整型数之后可以直接进行算术运算, 否则可以使用双括号执行算术运算。


间接变量引用
variable1=variable2
variable2=value


eval tempvar=\$$variable1
tempvar=${!variable1}
2种间接引用的方法,tempvar为value




内部变量
HOSTNAME 主机名
HOSTTYPE MACHTYPE 硬件架构
OSTYPE 操作系统类型
REPLY 存储一些用户输入
SECONDS 记录脚本从开始到结束所用时间
SHELLOPTS 记录‘开’的shell options
SHLVL shell脚本嵌套层次
TMOUT shell在TMOUT秒之后自动注销


=================================================


命令替换
''或者$() 将命令替换为命令执行的输出内容。




=================================================


测试
[ expression ]
expression为真,返回0, 为假返回非0整数。
经常作为流程控制语句的判断条件。


注意!在shell脚本中0为真


整数比较运算符
n -eq m  如果n等于m,为真
n -ge m  如果n大于等于m, 为真
n -gt m  如果n大于m, 为真
n -le m  如果n小于等于m, 为真
n -lt m  如果n小于m, 为真
n -ne m  如果n不等于m, 为真


字符串运算符
str  如果str不为空, 为真
-n str 如果str不为空, 为真
-z str 如果str为空, 为真
str1 = str2 如果str1等于str2, 为真
str1 != str2 如果str1不等于str2, 为真


文件运算符
-d file 如果file为目录,为真
-e file 如果file存在, 为真
-f file 如果file为普通文件, 为真
-r file 如果file为进程可读文件, 为真
-s file 如果file大小不为0,为真
-w file 如果file为进程可写文件, 为真
-x file 如果file为进程可执行文件, 为真
-L file 如果file为链接文件, 为真


逻辑运算符
! -a -o 非 与 或


=================================================


exit status 退出并指定退出状态


=================================================


if 结构
1.
if expression
then
    command
    command
fi
2.
if expression ; then
    command
    command
fi
3.
if expression
then
    command
    command
else
    command
fi
4.
if expression1
then
    command
    command
elif expression2
then
    command
elif expression3
then
    command
else
    command
fi
5. if语句可以嵌套使用


=================================================


case 结构
case variable in
value1)
    command
    command;;
value2)
    command
    command;;
valuen)
    command
    command;;
*)
    command
    command;;
esac


=================================================


循环
列表for循环
for variable in {list}
do
    command
    command
    ...
done


{1..100..2}或$(seq 1 2 100)表示1到100的所有奇数


不带列表for循环
for variable
do
    command
    command
    ...
done
这种循环用于遍历参数


类C风格for循环
for((expr1; expr2; expr3))
do
    command
    command
    ...
done
注意! 当使用数值计算时,判断条件要使用双圆括号或者双方括号
下面的各类循环同理


while循环
while expression
do
    command
    command
done


shift命令使位置变量下移一位(即$2代替$1, $3代替$2)


until循环
until expression
do
    command
    command
    ...
done
与while的区别是条件为真时才停止循环


各类循环可以嵌套使用


循环控制符有break continue


=================================================


select结构 用于交互式菜单显示,这个不是循环
select variable in {list}
do
    command
    command
    ...
    break
done
也可以去掉"in {list}"而使用命令行参数


=================================================


pushd 将目录压入栈中,并将当前目录切换到入栈的目录
popd 将目录从栈中弹出, 并将当前目录切换到弹出的目录
read variable 从标准输入读取一行,存储到variable变量中


=================================================


字符串处理
${#string}
expr length "$string"
计算string的长度


expr index $string $substring
返回substring中的字符(不是字符串)第一次在string中出现的位置,没有匹配上就返回0


expr match $string $substring
在string开头匹配substring字符串,返回匹配到的长度。substring可以是正则表达式,匹配不到返回0


${string:position}
${string:position:length}
从string的position个位置开始抽取字串或者抽取长度为length的字串,postion从0开始计数


${string: -postion}       #注意:号-号之间有空格
${string:(-position)}
从右边开始计数抽取子串


expr substr $string $position $length
从左边抽取子串,与${string:position:length}不同之处在于position从1开始计数


expr match $string '\($substring\)'
expr $string : '\($substring\)'      #注意:号前后有空格
使用正则表达式抽取字符串开头的子串


expr match $string '.*\($substring\)'
expr $string : '.*\($substring\)'    #注意:号前后有空格
使用正则表达式抽取字符串结尾的子串


${string#substring}
${string##substring}
删除string开头处与substring匹配的最短子串
删除string开头处与substring匹配的最长子串


${string%substring}
${string%%substring}
删除string结尾处与substring匹配的最短子串
删除string结尾处与substring匹配的最长子串


${string/substring/replacement}
${string//substring/replacement}
替换第一次匹配的子串
替换所有匹配的子串


=================================================


bc运算器
sample
#!/bin/bash
var1=20
var2=3.14159
var3=`echo "scale=5;$var1 ^ 2 " | bc`
var4=`echo "scale=5;$var3 *$var2" | bc`
echo "Then area of this circle is:$var4"


管道
command1 | command2 | command3 | ... | commandn
作用:前一个命令的输出作为下一个命令的输入


=================================================


文件描述符
0 标准输入
1 标准输出
2 标准错误输出
< filename 将filename的内容作为标准输入
> filename 将标准输出的内容写入filename
>> filename 将标准输出的内容追加到filename已有内容之后
n> filename 将FD为n的输出写入文件filename
n< filename 将filename内容写入FD n中
<<delimiter 定义输入结束字符串
-<<delimiter 可以删除每行开头的Tab


n>&m 将FD为n的输出重定向到与FD为m的输出一样的输出流
n<&m 将FD为m的输入重定向到与FD为n的输入一样的输入流
n>&- 关闭FD为n的输出
n<&- 关闭FD为n的输入
&>file 将标准输出和标准错误输出重定向到文件


exec 执行重定向
exec 8<&0 #将标准输入重定向到FD为8
exec 0<&8 8<&- #将FD为8的输入重定向到FD为0,即将标准输入重新定义到0, 然后关闭FD为8的输入.


代码块重定向
while unitl for if/then 函数等结构都可以重定向
sample
#!/bin/bash
ls /etc > loggg  #将ls /etc的结果写入loggg


while [ "$filename" != "rc.d" ]
do
    read filename         #实际读取的是loggg中的内容
    let "count +=1"
done < loggg       #将loggg的内容作为while循环中的标准输入
echo "$count times read"


read test          #循环体外还是从标准输入读取数据
echo $test


=================================================


eval 命令的作用就是让shell命令经过一次shell解析之后,作为新命令再次让shell解析执行
在变量间接引用中 eval tempvar=\$$variable1
如果没有eval, tempvar的值为$variable2,
有eval时,shell一次解析之后变成了 eval tempvar=$variable2
然后shell重新执行tempvar=$variable2
之后,tempvar就为variable2的值,而非字符串$variable2


=================================================


圆括号强制将命令运行于子shell中
(
    command1
    command2
    ...
    commandn
)




=================================================


信号
Ctrl+C INT信号, 停止当前运行的作业
Ctrl+Z TSTP信号, 暂停当前作业进入阻塞态
Ctrl+\ QUIT信号, Ctrl+C的强化版


trap command sig1 sig2 sig3
当收到信号时,执行command


=================================================


函数定义
function_name()
{
    command1
    command2
    ...
    commandn
}


函数调用
function_name arg1 arg2 ...


函数返回值
return 0


函数局部变量
local variable="I am local variable"


=================================================


alias alias-name='original-command'
给命令起别名


unalias [-a] [alias-name]
删除别名(-a 所有别名)


=================================================


与列表
command1 && command2 && command3 && command4 
从左往右依次执行,任何一个命令返回false时,执行终止


或列表
command1 || command2 || command3 || command4
从左往右依次执行, 任何一个命令返回true时,执行终止


command1; command2; command3
无论结果如果, 依次执行


command1 & command2
command1进入后台执行, 然后立刻开始执行command2


=================================================


数组
引用下标为x的元素
${array[x]}


for i in ${array[@]}
...


赋值
array[0]=xxx
array[1]=yyy
array[10]=zzz


array=(xxx yyy zzz)


array=([1]=yyy [10]=zzz [0]=xxx)


数组元素个数
${#array[@]}


=================================================


shift命令
对参数偏移


=================================================


getopts命令
getopts options_str variable
1.getopts检查所有的命令行参数,找到以‘-’开头的字符
2.将‘-’字符之后的字符与在"options_str"中的字符进行比较
3.若找到匹配, 则指定variable为匹配字符,否则指定variable为'?'
4.重复1~3直到考虑完所有选项
5.分析结束,返回非零值退出


=================================================


调试
1.使用echo语句


2.使用trap命令
三个伪信号
EXIT 从函数中退出,或者整个脚本执行完毕
ERR  当一条命令返回非零状态码,即命令执行不成功
DEBUG 脚本的每一条命令执行之前


3.使用tee命令
tee 将输入写入文件同时也写入标准输出


4.调试钩子


5.shell 选项
noexec n 读取脚本中的命令,进行语法检查,但是不执行这些命令
xtrace x 在执行每一个命令之前,将每一个命令打印到标准输出
       c 从命令行读取命令
       e 当脚本发生第一个错误时退出脚本




调试用的内部变量
LINENO  表示shell脚本的行号
FUNCNAME    数组变量,表示整个调用链上所有的函数名
PS4     设置-x选项的提示符,默认是“+”号

export PS4='+{$LINENO:${FUNCNAME[0]}:${FUNCNAME[1]}}'


=================================================

写这个的时候, 有人说你这不是没用吗,我也想过,这个确实没有太多用, 因为工作中真记不得了还可以再翻下书。

但是有时候又觉得,如果你告诉招聘人员,这个问题我看下书就会了,真心不知道他会不会要自己。

工作中,其实也是偶尔写一些很简单的shell语句(感觉还不能说上脚本吧),简化下操作, 好多shell的东西其实不清楚,最终的结果是没有积累,不能形成能力。

所以,我还是觉得有了这600多行, 以后有事看一下, 心中就有数了。

0 0
原创粉丝点击