shell脚本精华总结.docx
《shell脚本精华总结.docx》由会员分享,可在线阅读,更多相关《shell脚本精华总结.docx(18页珍藏版)》请在冰豆网上搜索。
![shell脚本精华总结.docx](https://file1.bdocx.com/fileroot1/2023-1/4/996bfbf1-55ec-4042-a65e-8dd1f74fcbf2/996bfbf1-55ec-4042-a65e-8dd1f74fcbf21.gif)
shell脚本精华总结
1.shell做解释程序,非交互地执行脚本,两种执行方式:
用sh命令执行脚本文件shhello.sh
给脚本文件添加执行权限,用./命令执行chmod755hello.sh./hello.sh
2.vim
(1)必须从命令模式转入插入模式才能进行输入编辑,可用命令有:
新增(append)
a:
从光标所在位置后面开始新增资料
A:
从光标所在行最后面的地方开始新增资料。
插入(insert)
i:
从光标所在位置前面开始插入资料
I:
从光标所在行的第一个非空白字元前面开始插入资料。
开始(open)
o:
在光标所在行下新增一列并进入输入模式O:
在光标所在行上方新增一列并进入输入模式
(2)冒号进入行命令模式,输入setnu可设置vi显示行号
:
/string搜索指定的字符串。
按键n:
继续进行搜索
如果写的是斜杠(/):
按n会从当前位置向后查找;如果写的是问号(?
),按n键则从当前位置向前查找
查找且替换
:
%s/SEARCH/REPLACE把文档中所有SEARCH替换成REPLACE;
:
#,#s/SEARCH/REPLACE/g#号表示数字,表示从多少行到多少行,把SEARCH替换成REPLACE;
:
s/SEARCH/REPLACE/g把当前光标所在行中的SEARCH单词,替换成REPLACE,并把所有SEARCH高亮显示
例题:
1.mkdir/tmp/vitest
2.cd/tmp/vitest
3.cp/etc/man.config.
4.viman.config
5.:
setnu
6.先按下58G再按下40→会看到/dir/bin/foo这个字样在双引号内;
7.先执行1G或gg后,直接输入/bzip2
8.直接执行:
50,100s/man/MAN/gc即可
9.
(1)简单的方法可以一直按u恢复到原始状态,
(2)使用不储存离开:
q!
之后,再重新读取一次该文件;
10.51G然后再10yy之后按下G到最后一行,再p粘贴10行
11.11G之后,再给他20dd即可删除20行了;
12.:
wman.test.config
13.29G之后,再给他15x即可删除15个字符;
14.:
wq!
#!
/bin/bash必须的,指出shell的类型
例题:
#!
/bin/bashshell类型
#asimpleshellscriptexample
#afunction
funcitonsayhello()函数
{
echo"EnterYourname:
"
readname读取来自键盘输入的变量
echo"Hello$name"
}
echo"programmestartshere..."主过程
sayhello
echo"programmeends."
3.符号
注释符#
除了#!
/bin/bash里的#特殊
变量符与反斜杠转义符相反,使其后的普通字符作为变量名,如$a表示变量a的值。
变量字符长度超过1个时,用{}括起来
单引号
被引起的字符全部做普通字符,即全部原样echo‘my$SHELL’
双引号引号内的内容,除$、转义符\、倒引号`这三个保留特殊功能,其他字符均做普通字符。
倒引号(数字1键旁边的那个键)
引号内的字符串当做shell命令行解释执行,得到的结果取代整个倒引号括起来的部分。
反斜线
反斜线是转义字符,它能把特殊字符变成普通字符。
在某个字符前面利用反斜杠(\)能够阻止shell把后面的字符解释为特殊字符。
4.本地变量在用户现在的shell生命期的脚本中使用
变量名=值
注意:
(1)等号两边不可以有空格
(2)取值包含空格,必须用双引号括起来
(3)Shell变量可以用大小写字母,区分大小写
除变量unset变量名
举例:
echo${name}unsetname(注意:
name前没有$)
设置变量时,不想再改变其值,可以将之设为只读变量
变量名=值
readonly变量名
5.环境变量
用于所有用户进程(通常称为子进程)。
登陆进程称为父进程,通过pstree可以查看
设置环境变量
variable-name=value
exportvariable-name(环境变量名大写)
显示环境变量:
(1)env可以看到所有的环境变量
(2)echo$环境变量名(显示一个变量)
清除环境变量unset环境变量名
HOME:
代表使用者的家目录。
cd~去到使用者的家目录或者利用cd就可以直接回到使用者家目录了。
PS1:
shell的主提示符
SHELL:
目前这个环境使用的SHELL是哪个程序?
如果是bash的话,预设是/bin/bash
PWD:
用户当前工作目录的路径。
它指出用户目前在Linux文件系统中处在什么位置。
它是由Linux自动设置的
HISTSIZE:
这个与“历史命令”有关,曾经下达过的指令可以被系统记录下来,而记录的“数目”则是由这个值来设定的。
ENV:
这个使用者所使用的个性化环境设置文件的读取文件。
MAIL:
当我们使用mail这个指令在收信时,系统会去读取的邮件信箱文件(mailbox)。
PATH:
就是执行文件搜寻的路径,目录与目录中间以冒号(:
)分隔,由于文件的搜寻是依序由PATH的变量内的目录来查询,所以,目录的顺序也是重要的喔。
LANG:
语系文件,很多数据都会用到他,当出现编码错误的时候往往需要设置它,中文编码是zh_CN.UTF8
6.Bash的初始化文件有:
/etc/profile、~/.bash_profile、~/.bash_login、~/.profile、~/.bashrc、/etc/bashrc
/etc/profile存放一些全局(共有)变量,不管哪个用户,登录时都会读取该文件。
通常设置一些Shell变量PATH,USER,HOSTNAME和HISTSIZE等
~/.bash_profile:
每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次!
默认情况下,他设置一些环境变量,执行用户的.bashrc文件.
~/.bashrc:
该文件包含专用于你的bashshell的bash信息,当登录时以及每次打开新的shell时,该该文件被读取.
/etc/bashrc:
为每一个运行bashshell的用户执行此文件.当bashshell被打开时,该文件被读取.
上述配置文件的作用
1)登录Linux先启动系统配置文件/etc/profile,并从/etc/profile.d目录的配置文件中搜集shell的设置,为系统的每个用户设置环境信息。
2)用户配置文件~/.bash_profile,每个用户专用于自己使用的shell信息,仅用户登录时执行一次!
默认情况下,此文件通过脚本执行同目录下用户的.bashrc文件。
3)~/.bashrc文件包含专用于用户bashshell的bash信息,登录及每次打开新的shell时都会执行。
里面又会调用/etc/bashrc
在/home/user/.bash_profile中定义下句,会怎样?
aliasla=‘ls–a|grep“\.*”’
答:
user下次再登陆,其shell会自动建立一个别名命令la,功能为查看当前目录下名字以.开头的文件。
写在~/.bash_profile中,需重新登录才能有效。
除非运行source.bash_profile使其立即有效。
写在~/.bashrc中,则打开新的终端中就有效
区别:
bash_profile只在会话开始的时候读取一次,而bashrc则每次打开终端时都会读取
按照传统,定义的变量如PATH放到.bash_profile中,而像别名函数等放在.bashrc中,但是.bash_profile先于.bashrc读取内容,也可全放入.bashrc中
7.部分内部变量是:
$#——传送给shell程序的位置参数的数量
$?
——最后命令的完成码或者在shell程序内部执行的shell程序(返回值)
$0——shell程序的名称
$*——调用shell程序时所传送的全部参数的单字符串,“参数1”“参数2”…形式保存的参数
$@“参数1”“参数2”…形式保存的参数
$n第n个参数
$$本程序的PID
$!
上一个命令的PID
8.条件判断命令test
testn1-参数n2(或–参数表达式)
真返回0,假返回1。
-lt小于-le小于等于-gt大于-ge大于等于-eq等于-ne不等于
例题:
#!
/bin/bash
iftest$1-gt0
then
echo“$1numberispostive”
elsethen
echo“$1numberisnagitive”
fi
如:
test-d“mydoc”判断mydoc是否是目录
-f存在且是普通文件
-d存在且是目录
-s存在且字节数大于0
-r存在且可读
-w存在且可写
-x存在且可执行
例题:
检测从命令行输入的文件是否存在:
#!
/bin/bash
if[$#-ne1]
then
echo“usage-$0file-name”
exit1
fi
if[-f$1]
then
echo“$1fileexist”
else
echo“sorry,$1filedoesnotexist”
fi
其他参数
-a逻辑与
-o逻辑或
9.seq命令:
产生1-9的数字序列
比如seq14
expr命令:
对表达式求值$expr2–1
$expr1\*3使用*要加转义符
$echo`expr1+3`
[]直接求值命令:
对被括起来的表达式求值
例题:
if分支
if[$#-eq0]
then
echo“输入了0个参数”
elif[$#-lt1]
thenecho“输入了多个参数”
elseecho“输入了1个参数”
fi
case
case“$#”in
0)echo“输入了0个参数”;;
1)echo“输入了1个参数”;;
*)echo“输入了多个参数”;;
esac
每个分支条件后必须以两个分号结尾
for例子——输出100内10的倍数
foriin`seq19`
do
echo`expr$i\*10`
done
或写echo$(expr$i\*10)
10.read变量1[变量2…]
可以从键盘上读取多个变量的值,用户输入数据时,以空格或者Tab键作为分隔。
如果输入的数据个数不够,则从左到右对应赋值,没有输入的变量为空;
如果输入的数据个数超了,则从左到右对应赋值,最后一个变量被赋予剩余的所有数据。
例题:
readab
foriin`seq$a$b`
do
echo`expr$i\*10`
done
while例子——求1到100的和
i=1
sum=0
while[$i–le100]
do
sum=$[$sum+$i]
i=$[$i+1]
done
echo$sum
11重定向
1stdout标准输出
2stderr标准错误
输出重定向到文件file,终端上只能看到标准错误:
#命令>file
错误重定向到文件file,终端上只能看到标准输出:
#命令2>file
标准输出和标准错误都重定向到file,终端上看不到任何信息:
#命令>file2>&1
(等于#命令1>file2>&1)
cp/etc/my.conf>/dev/null2>&1
/dev/null空设备
此句命令的结果是:
cp命令没有目标文件,应该输出错误。
2>&1表示错误重定向指向标准输出。
>/dev/null又使标准输出重定向到空,就是不要输出信息
即:
一个错误的命令执行,什么功能都不实现,且没有任何信息或错误提示输出。
$catfile文件內容会被洗掉
$catfile此处会没有内容
stdout、stderr的管道先准备好才会从stdin读内容
>file会先清空file,然後才读进因此再重定位读进file的为空
最后cat显示的file就成空了
例题:
编写一个名为iffile程序,它执行时判断/bin目录下date文件是否存在?
#!
/bin/sh-
fname=/bin/date
if(test–f“$fname”)then
echo“exist”
fi
编写一个名为greet的问候程序,它执行时能根据系统当前的时间向用户输出问候信息。
设从半夜到中午为早晨,中午到下午六点为下午,下午六点到半夜为晚上。
#!
/bin/sh-
hour=`date|cut–c12-13`将命令执行的结果赋给hour变量,所以用反向单引号
iftest“$hour”–ge0–a“$hour”–le11;then
echo“Goodmorning!
”
eliftest“$hour”–ge12–a“$hour”–le17;then
echo“Goodafternoon!
”
else
echo“Goodevening!
”
fi
编写一个名为ifuser的程序,它执行时带用户名作为命令行参数,判断该用户是否已经在系统中登录,并给出相关信息。
#!
/bin/sh-
iftest$#-ne1then
echo"Incorrectnumberofarguments"
echo"Usage:
ifuserusername"
else
user=$1
ifwho|grep–q$user;then#who|grep$user不是表达式而是命令组合,所以不需要test语句测试;如果命令组合执行成功,即找到指定的用户名则返回码为0;否则为非0。
grep命令–q选项来禁止显示搜索到的信息
echo$1"userisloggedon."
exit0exit0表示程序终止后返回0值
else
echo$1"userisnotloggedon."
exit1exit1表示程序终止后返回非0的值
fi
fi
编写一个名为menu的程序,实现简单的弹出式菜单功能,用户能根据显示的菜单项从键盘选择执行对应的命令。
#!
/bin/sh-
clear
echo"-----------------MENU------------------"
echo
echo"1.Findfilesmodifiedinlast24hours"
echo"2.Thefreediskspace"
echo"3.Spaceconsumedbythisuser"
echo"4.Exit"
echo
echo-n"Select:
"echo–n实现输入的选择数字不换行
readchoice
case$choicein
1)find$HOME-mtime-1-print;;显示/home目录下,最近24小时内所有修改过的文件,-1参数是数字“1”,表示一天
2)df;;检查磁盘空间
3)du-s$HOME;;显示/home目录下文件的大小,命令中的-s选项是为了仅显示总计
4)exit;;
*)echo"Invalidoption"
esac
编写一个名为chname的程序,将当前目录下所有的.txt文件更名为.doc文件。
#!
/bin/sh-
forfilein*.txt
doleftname=`basename$file.txt`basename命令,该命令从随后的文件名剥去指定的后缀
mv$file$leftname.doc
done
在Linux系统中不支持mv*.txt*.doc这样的更名命令形式,如果需要将文件成批地更名最好编写一个shell脚本文件
编写一个名为chuser的程序,执行中每隔5分钟检查指定的用户是否登录系统,用户名从命令行输入;如果指定的用户已经登录,则显示相关信息。
#!
/bin/sh–
iftest$#-ne1如果没有从命令行输入用户名,则测试$#-ne1为“真”,显示用法提示信息
then
echo“Usage:
chuserusername”
elseuser=”$1”
untilwho|grep“$user”>/dev/null采用重定向到/dev/null空文件的目的是不显示查找到的用户其他信息
dosleep300
done
echo“$userhasloggedon!
”
fi
程序中until语句的expression(循环条件)是who|grep“$user”命令执行的返回码,如果没有找到指定的用户名,返回码为非0(为“假”),则用sleep命令暂停执行程序5分钟;找到后返回码为0(为“真”),则终止循环并显示该用户已经登录的信息
printnumber判断参数是否是数
#!
/bin/bash
a=$(echo$1|bc2>/dev/dull)
if[[$a!
=$1]];then
echo“$1参数不是数”
else
echo“$1参数是数”
12.bc计算器,进制转换命令
13.${变量名匹配模式}
截掉匹配子串后剩余字符串是结果
str1=${a%%.*}str2=${a##*.}#从左向右,%从右向左
搜索最长匹配符号写两次,最短匹配写1次
$MYVAR=foodforthought.jpg
$echo${MYVAR##*fo}rthought.jpg
$echo${MYVAR#*fo}odforthought.jpg
$MYFOO="chickensoup.tar.gz"
$echo${MYFOO%%.*}chickensoup
$echo${MYFOO%.*}chickensoup.tar
指定字符偏移和长度截出子串
$EXCLAIM=cowabunga
$echo${EXCLAIM:
0:
3}cow
#从第一个字符开始,截3个字符
$echo${EXCLAIM:
3:
7}abunga
#从第四个字符开始,截7个字符
x=abcd${#x}#获取字串长度4
exprindex$x“b“#获取子串所在偏移2
exprindex$x"a“#获取子串所在偏移1
echo${x:
1}#获取子串
替换
echo${name//jx/tc}
tc-sys-
例题:
数组
遍历数组:
total=${#A[*]}
for((i=0;ido
echo${A[$i]}
done
14.元字符
.匹配任何单个字符。
$匹配行结束符。
^匹配一行的开始。
*匹配0或多个正好在它之前的那个字符。
+匹配1或多个正好在它之前的那个字符。
?
匹配0或1个正好在它之前的那个字符。
\{i\}\{i,j\}匹配指定数目的字符。
\这是引用符,转义;
[][c1-c2]匹配括号中的任何一个字符。
[^c1-c2]
\<\>匹配词(word)的开始(\<)和结束(\>)。
\(\)将\(和\)之间的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个),它们可以用\1到\9的符号来引用。
|将两个匹配条件进行逻辑“或”(Or)运算。
例如正则表达式(him|her)
将当前任务挂起,返回job_id
fgjob_id把后台作业放到前台执行
bgjob_id把作业放到后台执行
例题:
自定义函数
functionfoo()#foo为函数名
{
locala=$1;#局部变量
echo$a;
return0;#返回值
}
foo“cool!
”#函数调用
echo$?
自定义函数–16进制转点分十进制
a()
{
localstr=$1
echo-n$((16#${str:
0:
2}))
str=${str:
2}
if["x$str"="x"]
then
echo;return
else
echo-n".";a$str
fi
}
#Usage
a"DDB14CCF"
15.整数计算
id++id--++id–id-+!
~***/%计算
<<>>&^|位操作
<=>=<>==!
=比较
&&||逻辑操作
expr?
expr:
expr三元操作符
=*=/=%=+=-=<<=>>=&=^=|=赋值操作符
y=2000闰年计算
echo$((y%4==0&&y%100!
=0||y%400==0))
((y++))自增1
tmp=$((16#a))进制转换
16.浮点运算
echo“scale=5;3/7"|bc–l.42857
echo"100.43KB20.12KB"|awk'{print$1-$2}'80.31
echo"ibase=16;F"|bc-l15
例题:
随机字符串生成
typeset-rDEFAULT_STR_LEN=5
typeset-radict=(abcdefghijklmnopqrstuvwxyz)
functionget_random_letter()
{
echo-n${dict[$((RANDOM%${#dict[*]}))]}
return0
}
functionget_random_string()
{
localslenstr
[$#-eq1]&&slen=$1||slen=$DEFAULT_STR_LEN