1,shell脚本的变量认识
变量 | 含义 |
$0 | 当前脚本的文件名 |
$n | 传递给脚本或函数的参数,n是一个数字,表示第几个参数。例如第一个参数是$1,第二个参数是$2 |
$# | 表示传递给脚本或者参数的个数 |
$* | 传递给脚本或函数的所有参数 |
$@ | 传递给函数互脚本的所有的参数,被双引号(“ ”),与$*稍有不同 |
$? | 上个命令的退出状态,或函数的返回值 |
$$ | 当前shell进程id。对于shell脚本,就是这些脚本所在的进程id |
- 注释:$*和$@的区别:
- $*和$@都表示传递给函数或脚本的的所有的参数,不被双引号(“ ”)包含时,都以$1,$2,$3。。。$n的形式输出所有参数,但他们被双引号(“ ”)时,$*会将所有参数作为一个整体,以“$1, $2,$3...$n”的形式输出,$@会将各个参数分开,将以“$1”,“$2”,“$3”。。。“$n”的形式输出
2,一个简单的shell脚本文件
a="雪雪" echo "$a is my favourite"
- 注意:在定义变量和给变量赋值的时候,变量名和=之间不能有空格,=和变量之间也不要有空格
3,逻辑控制语句
a="雪雪" echo "$a is my favourite" if [ -n "$a" ];then echo "$a long time no see" else echo "$a i miss you" fi# 语法结构# if [ 条件 ];then# 代码块# else# 代码块# fi 结束if语句# 基本的条件判断# [ -f "somefile" ]:判断是否是一个文件# [ -x "/bin/ls" ]:判断/bin/ls是否存在,并有可执行权限# [ -n "$var" ]:判断var变量是否有值# [ "$a" = "$b" ]:判断$a和$b是否相等# [ ]
- 注意:在写if,else逻辑控制语句的时候if和条件用空格隔开,条件用[]包裹起来[]后边要跟;(不是冒号:一定要分清);后边要跟then,然后是业务逻辑部分else,后边是否则的业务逻辑的部分,最后要加上fi结束if语句
mailfolder=~/hello/readme.txt if [ -r "$mailfolder" ];then echo "$mailfolder has mail from : " echo | grep "^echo" $mailfolder >> readme2.txt chmod +r readme2.txt cat readme2.txt >> $mailfolder rm -f readme2.txt else echo "can not read $masifolder" touch $mailfolder chmod +rw $mailfolder echo "echo 世情薄,人情恶,雨送黄花花易落,晓风干, 泪痕残。欲笺心事,独倚斜栏, 难,难,难! 人成各,今非昨, 病魂常似秋千索,角声寒,夜阑珊,怕人询问,咽泪装欢,瞒,瞒,瞒。" fi
4,while循环的shell代码
f1=/etc/passwd count=`cat $f1 | wc =l` # 下面是一个管道,下面循环读取文件中的每一行 cat $f1 | while read line do user= "echo $line|awk -F ':' '{print $1}'" # 代表以:分段$1就是取第一段 uid="echo $line|awk -F ':' '{print $3}'" echo "hello, $user your uid is $uid" done echo "====User_count:$count===="
- 注释:awk是行处理器,awk -F,处理行指定分隔符,wc(word count)是Linux中统计指定文件的字节数、字数、行数等计数用的
5,for循环的代码编写
需求:
- 切换至工作目录/tmp
- 一次向每个子目录下的文件或者子目录问好
- 统计/tmp目录下有多少个文件并统计出来
cd /tmp for i in /tmp/* do echo "hello,$i" done count="ls -l|grep '^-'|wc -l" echo "====file_count:$count===="
***我写的第一版:遇到一个问题,就是在count计数的时候,用饿的是英文的双引号("")结果,就是计数不成功
我写的第二版
# cd /tmp # 把进入到/tmp目录下这个注释掉 for i in /tmp/* do echo "hello,$i" done count=`ls -l|grep '^-'|wc -l` echo "====file_count:$count===="
###我把进入到/tmp目录下这行代码注释掉,并把count计数用反引号包裹起来,计数就生效了,而且计数是9个文件
第三版:将cd /tmp注释打开
cd /tmp # 把进入到/tmp目录下这个注释掉 for i in /tmp/* do echo "hello,$i" done count=`ls -l|grep '^-'|wc -l` echo "====file_count:$count===="
- 此时对于文件的计数就是1个。
6,给shell脚本传递参数,
# 给shell脚本传递整数,让脚本计算穿进去整数的和,积,差,商 a=$1 b=$2 # 表示如果$a字符串为空,就输出please $1 number1 [ -z $a ] && echo "please \$1 number1" && exit 1 # 表示如果$b字符串为空,就输出please $2 number2 [ -z $b ] && echo "please \$2 number2" && exit 2 # 表示这个脚本需要传递2个参数 [ ! $# -eq 2 ] && echo "--please num1 num2" && exit 3 # $#是表示传递给脚本的参数的个数 # -eq相当于=,-ne相当于不等于, -ge >=,-gt >,le <=, -lt < echo "$a + $b = $(($a+$b))" echo "$a - $b = $(($a-$b))" echo "$a * $b = $(($a*$b))" echo "$a / $b = $(($a/$b))"
- 注意:传递参数的时候,中间不要加逗号(,)这样系统会认为前两个数是一样的,只会把逗号(,)前后2个接近的数进行运算
判断语句的知识点:
- 文件表达式
- if [ -f file ]:表示如果文件存在
- if [ -d ... ]:表示如果目录存在
- if [ -s file ]:表示如果文件存在且非空
- if [ -w file ]:表示如果文件存在且可写
- if [ -r file ]:表示如果文件存在且可执行
- 整数变量表达式
- if [ int1 -eq int2 ]:表示如果int等于int2
- if [ int1 -ne int2 ]:表示如果int1不等于int2
- if [ int1 -ge int2 ]: 表示如果int1大于等于int2
- if [ int1 -gt int2 ]:表示如果int1大于int2
- if [ int1 -le int2 ]:表示如果int1小于等于int2
- if [ int1 -lt int2 ]:表示如果int1小于int2
- 字符串变量表达式
- if [ $a=$b ]:如果string1等于,字符串允许使用赋值号作为等号(=)
- if [ $string1 != $string2 ]:如果string1不等于string2(!=)
- if [ -n $string ]:如果string非空(非0),返回o(true)
- if [ -z $string ]:如果string为空
- if [ $string ]:如果字符串非空,返回0(和-n类似)
- 在shell编程中:&&与||的区别
- cmd1 && cmd2:(类似if 条件)
- 若cmd1执行完毕且执行正确,才开始执行cmd2
- 若cmd1执行完毕且执行错误,则cmd2不执行
- cmd1 || cmd2:(类似if not 条件)
- 若cmd1执行完毕且执行正确,cmd2也不会执行
- 若cmd1执行完毕且执行错误,cmd2则开始执行
- cmd1 && cmd2:(类似if 条件)
7,编写脚本计算从1到100的和
sum=0 i=1 while [ $i -le 100 ] # 再次强调条件和[ 条件 ]之间一定要用空格隔开 do sum=$(($sum+$i)) # 坑:运算的时候要用$(($a+$b)) i=$(($i+1)) done echo "$sum"
for 循环的饿从1加到100
sum=0 for ((i=1;i<=100;i++)) # 用for循环的时候要用(())包裹起来,之间的元素有分号(;)隔开 do ((sum=sum+i)) # 结果还是得用(())包裹起来 done echo "$sum"
8,shell函数的编写
- 函数编程的语法:
# 第一种 function 函数名(){ 指令。。。 return -n } # 第二种 function 函数名{ 指令。。。 return -n } # 第三种 函数名 (){ 指令 return -n }
- 注释:function表示声明一个函数,return -n是指退出函数
# shell函数的编写 function xuexue () { # 函数的声明是一个function,函数名叫xuexue(){} echo "世情薄,人情恶, 雨送黄昏花易落,晓风干,泪痕残,欲笺心事,独语斜栏。难,难,难!" # 函数的代码块 echo "唐婉" } # 函数的闭合区间 function xiaoxue(){ # 函数的声明是function,函数名叫做xiaoxue)_{} echo "人成各,今非昨,病魂常似秋千索,角声寒,夜阑珊,怕人询问,咽泪装欢。瞒,瞒,瞒!" # 函数功能的代码块 return # 退出函数 echo "月亮很亮" } # 函数的闭合区间 xuexue # 调用xuexue这个定义的函数 xiaoxue # 调用xiaoxue这个定义的函数
9, 分离函数体执行函数的脚本文件
- 第一步向将函数写入指定的文件中
cat >>~/hello/functions<<EOF function xuexue(){ echo "世情薄,人情恶,雨送黄昏花易落,晓风干,泪痕残,欲笺心事,独语斜阑。难,难,难!" } EOF
-
- 表示把函数xuexue,导入到~/hello/functions中
- 第二步执行命令把把函数写到指定的卢金过得文件中
我们可以清除的看到,函数已经被写入到指定的文件中了,下面我们可以在另外一个文件调用函数了
if [ -f ~/hello/functions ] then . ~/hello/functions fi xuexue
切记:切记,.在这里表示加载functions(文件)中的命令或者变量参数等,.和后边的路径一定要有空格,然后我们运行这个脚本就可以了
小结:当我们定义大量函数的时候,我们就可以把函数写在某一个函数中,当我们写脚本的时候,需要其中的某一个函数的时候,我们就可以直接调用文件中的函数名
10,编写待参数的函数实例
function xueren(){ echo "我的名字叫:$1,我喜欢:$2" } xueren $1 $2
11,闭包函数
a=1 function outter(){ a=2 function inner(){ echo "这是什么啊"$a } inner echo $a } echo $a outter
运行代码输出:
12,利用shell函数开发企业级url检测脚本
#!/bin/bash #no.1 if [ "$#" -ne 1 ] #如果用户输入的传参参数不是1 then # 那么 echo "/root/sh/ $0" 请您输入一个网址 #输出脚本路径和脚本名称 最后输出请您输入一个网址! exit 1 #退出脚本 fi #结束 #no.2 wget --spider -q -o /dev/null --tries=1 -T 3 $1 #如果用户输入传参数是对的,那么执行wget命令最后$1是用户输入的内容 if [ "$?" -eq 0 ] #如果以上wget测试成功了! then #那么 echo "$1 检测是成功的!" #输出用户输入网址并输出是成功的 else #否则 echo "$1 检测是失败的!" #输出用户输入网址并输出是失败的 exit 1 #退出脚本 fi #fi结束
很尴尬,我检测都是失败的。
来源:https://www.cnblogs.com/ljc-0923/p/10988414.html