Shell总结

觉得有帮助的,请多多支持博主,点赞关注哦~

Shell 编程

1)介绍
Shell脚本是包含一系列命令的文本文件
Shell读取此文件并执行命令
2)使用场景
重复性操作
批量事务处理
自动化运维
定时任务执行

一、走进 Shell 编程的大门

1.1、为什么要学Shell?

学一个东西,我们大部分情况都是往实用性方向着想。从工作角度来讲,学习 Shell 是为了提高我们自己工作效率,提高产出,让我们在更少的时间完成更多的事情。

很多人会说 Shell 编程属于运维方面的知识了,应该是运维人员来做,我们做后端开发的没必要学。我觉得这种说法大错特错,相比于专门做Linux运维的人员来说,我们对 Shell 编程掌握程度的要求要比他们低,但是shell编程也是我们必须要掌握的!

目前Linux系统下最流行的运维自动化语言就是Shell和Python了。

两者之间,Shell几乎是IT企业必须使用的运维自动化编程语言,特别是在运维工作中的服务监控、业务快速部署、服务启动停止、数据备份及处理、日志分析等环节里,shell是不可缺的。Python 更适合处理复杂的业务逻辑,以及开发复杂的运维软件工具,实现通过web访问等。Shell是一个命令解释器,解释执行用户所输入的命令和程序。一输入命令,就立即回应的交互的对话方式。

另外,了解 shell 编程也是大部分互联网公司招聘后端开发人员的要求。

1.2、什么是 Shell?

简单来说“Shell编程就是对一堆Linux命令的逻辑化处理”。

W3Cschool 上的一篇文章是这样介绍 Shell的,如下图所示。
在这里插入图片描述

1.3、Shell 编程的 Hello World

学习任何一门编程语言第一件事就是输出HelloWord了!下面我会从新建文件到shell代码编写来说下Shell 编程如何输出Hello World。

(1)新建一个文件 helloworld.sh :touch helloworld.sh,扩展名为 sh(sh代表Shell)(扩展名并不影响脚本执行,见名知意就好,如果你用 php 写 shell 脚本,扩展名就用 php 好了)

(2) 使脚本具有执行权限:chmod +x helloworld.sh

(3) 使用 vim 命令修改helloworld.sh文件:vim helloworld.sh(vim 文件------>进入文件----->命令模式------>按i进入编辑模式----->编辑文件 ------->按Esc进入底行模式----->输入:wq/q! (输入wq代表写入内容并退出,即保存;输入q!代表强制退出不保存。))

helloworld.sh 内容如下:

#!/bin/bash
#第一个shell小程序,echo 是linux中的输出命令。
echo  "helloworld!"

shell中 # 符号表示注释。shell 的第一行比较特殊,一般都会以#!开始来指定使用的 shell 类型。在linux中,除了bash shell以外,还有很多版本的shell, 例如zsh、dash等等…不过bash shell还是我们使用最多的。

(4) 运行脚本:./helloworld.sh 。(注意,一定要写成 ./helloworld.sh ,而不是 helloworld.sh ,运行其它二进制的程序也一样,直接写 helloworld.sh ,linux 系统会去 PATH 里寻找有没有叫 helloworld.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,你的当前目录通常不在 PATH 里,所以写成 helloworld.sh 是会找不到命令的,要用./helloworld.sh 告诉系统说,就在当前目录找。)

在这里插入图片描述

1.4、标注 shell的解释器【推荐】

查看shell解释器:
在这里插入图片描述
Linux中预设的解释器是:bash,即/bin/bash

1)步骤:
 1.1)编写shell脚本的时候,加上shell解释器
     /bin/bash
     /bin/sh
 1.2)必须修改shell脚本的权限,具备x(执行)的权限
     chmod u+x test.sh
 1.3)执行shell脚本
     ./test.sh
     注意:不能直接访问test.sh(原因:必须要配置到环境列表中)
     
2)案例:
  #!/bin/bash
   echo "HELLO World!"

1.5、shell脚本的执行

执行的shell脚本,需要有执行的权限

1)步骤
 1.1)编写shell脚本,不需要显示加shell解释器
      直接编写命令
 1.2) 执行shell脚本(必须在shell文件前,添加shell解释器)
      bash  test.sh
      sh   test.sh
      /bin/bash test.sh
      /bin/sh  test

二、Shell 变量

2.1、Shell 编程中的变量介绍

Shell编程中一般分为三种变量:

  1. 我们自己定义的变量(自定义变量): 仅在当前 Shell 实例中有效,其他 Shell 启动的程序不能访问局部变量。
  2. Linux已定义的环境变量(环境变量, 例如:$PATH, $HOME 等…, 这类变量我们可以直接使用),使用 **env 命令可以查看所有的环境变量,而set**命令既可以查看环境变量也可以查看自定义变量。
  3. Shell变量 :Shell变量是由 Shell 程序设置的特殊变量。Shell 变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了 Shell 的正常运行

常用的环境变量:

PATH 决定了shell将到哪些目录中寻找命令或程序
HOME 当前用户主目录
HISTSIZE 历史记录数
LOGNAME 当前用户的登录名
HOSTNAME 指主机的名称
SHELL 当前用户Shell类型
LANGUGE  语言相关的环境变量,多语言可以修改此环境变量
MAIL 当前用户的邮件存放目录
PS1 基本提示符,对于root用户是#,对于普通用户是$

使用 Linux 已定义的环境变量:

比如我们要看当前用户目录可以使用:echo $HOME命令;如果我们要看当前用户Shell类型 可以使用echo $SHELL命令。可以看出,使用方法非常简单。

使用自己定义的变量:

#!/bin/bash
#自定义变量hello
hello="hello world"
echo $hello
echo  "helloworld!"

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QKTzLgMe-1580924021841)(E:\JAVA\Nodepad++\Typora\imgs\image-20200206000555468.png)]

Shell 编程中的变量名的命名的注意事项:

  • 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头,但是可以使用下划线(_)开头。
  • 中间不能有空格,可以使用下划线(_)。
  • 不能使用标点符号。
  • 不能使用bash里的关键字(可用help命令查看保留关键字)。
2.1.1、系统变量
#!/bin/bash
echo "当前用户是:$USER"
echo "当前用户的主目录是:$HOME"
echo "当前所在的文件路径:$PWD"

访问所有的系统变量和自定义变量: set
访问所有系统环境变量:printenv、env、export
2.1.2、自定义变量
1)声明变量语法
  变量名=变量值
  注意:
    =左右两边不能出现空格
    变量名:数字、字母、_,要以字母开头,参照java变量的命名方式
           不能是用关键字
2)使用变量的语法
   方式1:$变量名
   方式2:${变量名}

3)案例
#!/bin/bash
# 声明变量
  num1=1234  num2=20
  num3=${num1/23/AB}
  mypath=$PATH
#声明只读变量
  readonly count=10
#移除非只读变量
  unset mypath
  num4=num1
# 输出变量值
  echo "num1的值是:$num1,num2的值是:$num2"
  echo "mypath的值是:$mypath"
  echo "转换后的num3的值是:$num3"
  echo "num4的值是:${!num4}"


4)场景
  4.1)一个变量num2引用了另一个变量num1,如何访问该变量?
      num1=1234
      num2=num1
      echo ${num2}  #输出num1,错误,因为变量值应为1234
      echo ${!num2} #输出1234,正确
  
  4.2)设置只读变量
      readonly  num1=10
      num1=11 # 出错,不能被修改
  
  4.3)移除变量
       unset  num2
       echo $num2 #返回结果是:空

【变量赋予 命令执行的结果】两种方式

【变量赋予   命令执行的结果】两种方式
 方式1:
   变量=`命令`
   比如:
    list1=`ls -l`
    echo "当前时间是`date +%Y/%m/%d`"
 
 方式2:
   变量=$(ls -l)
    比如:
    list2=$(ls -l)
    echo "当前时间是$(date +%Y/%m/%d)"

【如何实现数值的计算】

【如何实现数值的计算】
方式一:$(( 运算的表达式 ))  # $((num1+num2))
方式二:$[运算的表达式]   # $[num1+num2]
方式三:((变量=运算的表达式))      # ((sum=$num1+$num2))
sum=$[${n1}+${n2}] 

【变量的作用域】

【变量的作用域】
1)默认的作用域:当前的shell文件
2)全局的作用域:环境变量的级别
   使用的关键字:export
   
实现:
 1)demo1.sh #声明一个变量 nowdate当前时间,设置成全局
    #!/bin/bash
    export nowdate=$(date +%y年%m)
    echo "当前日期是:$nowdate"

    source demo1.sh  #让nowdate变为全局,起作用
    
 2)demo2.sh #直接使用demo1.sh 中的nowdate变量

练习:
编写shell脚本showdate.sh,要求使用showdate.sh中的日期变量,并进行输出

[root@biubiubiu shelltest]# vi showtime.sh
[root@biubiubiu shelltest]# sh showtime.sh 
当前时间是:20200210:50:17
[root@biubiubiu shelltest]# cat showtime.sh 
#!/bin/bash
nowdate=$(date +%Y年%m月)
nowtime=$(date +%H:%M:%S)

echo "当前时间是:$nowdate $nowtime"
[root@biubiubiu shelltest]# vi showdate.sh
[root@biubiubiu shelltest]# source showdate.sh 
当前日期是:2020-02-05
[root@biubiubiu shelltest]# sh showdate.sh 
当前日期是:2020-02-05
[root@biubiubiu shelltest]# cat showdate.sh 
#!/bin/bash
export nowdate=$(date +%Y-%m-%d)
echo "当前日期是:$nowdate"

在这里插入图片描述

2.1.3、预定义变量

定义:


  $# :参数个数
  $* 和$@:输出所有参数
     两者只有在用""引起来的时候,才有区别,区别是:
     "$*":把所有参数作为一个整体
     "$@":把每个参数作为一个独立的个体
  $$:得到当前shell进程的pid,进程的id号
  $0:代表shell程序本身
  位置参数:$1...:第1个参数,注意:${10}
  $?:上一条程序是否执行成功

案例:

#!/bin/bash
#输出得到的参数个数$#
echo "输出的参数总个数是:$# 个"
#输出得到所有参数$*
echo "*所有参数是:"$*
#输出得到所有参数$@
echo "@所有参数是:"$@
#使用位置参数:$0~....
echo "当前程序是:$0,第一个参数是$1,第二个参数是$2"
#输出当前shell进程的编号:$$
echo "当前的进程编号是:$$"
#输出上条的命令执行是否成功:$?
echo "上条命令执行成功吗?0则成功,非0则失败:$?"

案例:$@$*的区别:

[root@os1 ch01]# ./test_op2.sh 10 20
#!/bin/bash
for i in  "$*"  # 直接$*测试,观察效果
do
  #循环体
  echo "*参数是:$i"
done

echo "--------------------------------"

for i in "$@"
do
  #循环体
  echo "@参数是:$i"
done


*参数是:10 20
--------------------------------
@参数是:10
@参数是:20

2.2、Shell 字符串入门

字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了),字符串可以用单引号,也可以用双引号。这点和Java中有所不同。

单引号字符串:

#!/bin/bash
name='biubiubiu'
hello='Hello, I  am '$name'!'
echo $hello

输出内容:

Hello, I am biubiubiu!

双引号字符串:

#!/bin/bash
name='biubiubiu'
hello="Hello, I  am "$name"!"
echo $hello

输出内容:

Hello, I am biubiubiu!

2.3、Shell 字符串常见操作

拼接字符串:

#!/bin/bash
name="biubiubiu"
# 使用双引号拼接
greeting="hello, "$name" !"
greeting_1="hello, ${name} !"   #双引号内字符串可以不加引号加括号
echo $greeting  $greeting_1
# 使用单引号拼接
greeting_2='hello, '$name' !'
greeting_3='hello, ${name} !'   #单引号内字符串不可以不加单引号
echo $greeting_2  $greeting_3

输出结果:

hello, biubiubiu ! hello, biubiubiu !
hello, biubiubiu ! hello, ${name} !

获取字符串长度:

#!/bin/bash
#获取字符串长度
name="biubiubiu"
# 第一种方式
echo ${#name}  #输出 9
# 第二种方式
expr length "$name";  #输出 9

输出结果:

9
9

使用 expr 命令时,表达式中的运算符左右必须包含空格,如果不包含空格,将会输出表达式本身:

expr 5+6    // 直接输出 5+6
expr 5 + 6       // 输出 11

对于某些运算符,还需要我们使用符号\进行转义,否则就会提示语法错误。

expr 5 * 6       // 输出错误
expr 5 \* 6      // 输出30
expr 5 '*' 6      // 输出30

截取子字符串:

简单的字符串截取:

#从字符串第 1 个字符开始往后截取 9 个字符
str="bubiubiu is a great man"
echo ${str:0:9} #输出:bubiubiu

根据表达式截取:

#!bin/bash
#author:amau

var="http://www.runoob.com/linux/linux-shell-variable.html"

# *是通配符的一种,表示任意长度的字符串
# %号截取的是左边的字符,所有*在右边,匹配右边的字符
# 直到最后一个指定字符(子字符串)再匹配结束,那么可以使用%%
s1=${var%%t*}#h
# 使用%号可以截取指定字符(或者子字符串)左边的所有字符,遇到第一个匹配的字符(子字符串)就结束了
s2=${var%t*}#http://www.runoob.com/linux/linux-shell-variable.h
s3=${var%%.*}#http://www
# #号截取的是右边的字符,所以*在左边,匹配左边的字符
# 使用#号可以截取指定字符(或者子字符串)右边的所有字符,遇到第一个匹配的字符(子字符串)就结束了
s4=${var#*/}#/www.runoob.com/linux/linux-shell-variable.html
# 直到最后一个指定字符(子字符串)再匹配结束,那么可以使用##
s5=${var##*/}#linux-shell-variable.html
# ${var#str} 从左向右匹配,非贪婪匹配,截取并保留右边的内容
txt='123456abc123456'
echo ${txt#*34}
# 56abc123456

# ${var##str} 从左向右匹配,贪婪匹配,截取并保留右边的内容
txt='123456abc123456'
echo ${txt##*34}
# 56

# ${var%str} 从右向左匹配,非贪婪匹配,截取并保留左边的内容
txt='123456abc123456'
echo ${txt%34*}
# 123456abc12

# ${var%%str} 从右向左匹配,贪婪匹配,截取并保留左边的内容
txt='123456abc123456'
echo ${txt%%34*}
# 12

2.4、Shell 数组

bash支持一维数组(不支持多维数组),并且没有限定数组的大小。我下面给了大家一个关于数组操作的 Shell 代码示例,通过该示例大家可以知道如何创建数组、获取数组长度、获取/删除特定位置的数组元素、删除整个数组以及遍历数组。

#!/bin/bash
array=(1 2 3 4 5);
# 获取数组长度
# 利用”@”或“*”字符,将数组扩展成列表,然后使用”#”来获取数组元素的个数
length=${#array[@]}
# 或者
length2=${#array[*]}
#输出数组长度
echo $length #输出:5
echo $length2 #输出:5
# 输出数组第三个元素
echo ${array[2]} #输出:3
unset array[1] # unset 数组名[索引] : (删除索引下的元素)删除下标为1的元素也就是删除第二个元素
# 遍历数组有三种方式:
# ${数组名[@]}、${数组名[*]}均可以获得所有元素(不管是元素列表,还是一整个字符串),使用for循环遍历即可;
# 带数组下标的遍历,当需要使用到数组的下标时,可以使用${!数组名[@]};
# while循环:根据元素的个数遍历,但对于稀疏数组,可能会丢失数据。
for i in ${array[@]};do echo $i ;done # 遍历数组,输出: 1 3 4 5 
unset array # unset 数组名 : 删除数组中的所有元素(删除整个数组)
for i in ${array[@]};do echo $i ;done # 遍历数组,数组元素为空,没有任何输出内容

三、Shell 基本运算符

Shell 编程支持下面几种运算符

  • 算数运算符
  • 关系运算符
  • 布尔运算符
  • 字符串运算符
  • 文件测试运算符

3.1、算数运算符

选项说明
$((运算表达式))比如: $((num1+num2))
$[运算表达式]比如:$[10+20]$[num1+num2]
expr a + b比如:echo expr 10 + 10

在这里插入图片描述

我以加法运算符做一个简单的示例(注意:不是单引号,是反引号):

#!/bin/bash
a=3;b=3;
val=`expr $a + $b`
echo "Total value : $val"
#输出:Total value : 6

3.2、关系运算符

在这里插入图片描述
案例:

#!/bin/bash
#关系运算符
num1=10 num2=10
[ $num1 -eq $num2  ]
echo "$num1,$num2相等吗?$?"
[ 10 -gt 20 ]    等效于  [[ 10 > 20 ]]
echo "10>20? $?"

[ 10  -ge 20 ]
echo "10大于等于20? $?"

[ 10 -lt 20 ]
echo "10小于20? $?"

[ 10 -le 20 ]
echo "10小于等于20? $?"

[ 10 -ne 20 ]
echo "10不等于20? $?"

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

在这里插入图片描述

通过一个简单的示例演示关系运算符的使用,下面shell程序的作用是当score=100的时候输出A否则输出B。

#!/bin/bash
score=90;
maxscore=100;
if [ $score -eq $maxscore ]
then
   echo "A"
else
   echo "B"
fi

输出结果:

B

3.3、逻辑运算符

在这里插入图片描述
【说明】

 -a ,&& :逻辑与
 -o,|| :逻辑或
 ! :取反符号

【案例】

#!/bin/bash
num1=10  num2=20
#&&  -a
[ $num1 -lt $num2 -a  1 -ne 2  ]
echo "[]使用逻辑与:$?"
[[ $num1 -lt $num2  &&  1 -ne 2  ]]
echo "[[]]使用逻辑与:$?"

#||  -o
[ $num1 -gt $num2 -o  1 -ne 2  ]
echo "[]使用逻辑或:$?"
[[ $num1 -gt $num2  ||  1 -ne 2  ]]
echo "[[]]使用逻辑或:$?"

#!
[ ! $num1 -gt $num2 ]
echo "使用取反符号的结果:$?"

[ ! $num1 -gt $num2 ] &&  echo "取反符号的结果是:正确"

在这里插入图片描述

示例:

#!/bin/bash
a=$(( 1 && 0))
echo $a;
# 输出:0;逻辑与运算只有相与的两边都是1,与的结果才是1;否则与的结果是0

3.4、布尔运算符

也就是表达式运算符

shell中:0表示为ture,0表示为false

一共是三种:
1[ boolean表达式 ] :比如[ $name ]  #判断变量是否存在
2)test boolean表达式:  test  $name
3[[ boolean表达式 ]][[ $name ]]

注意:两边的空格
[[ $num1 <  $num2  ]] && echo "小于"

在这里插入图片描述

这里就不做演示了,挺简单的。

3.5、字符串运算符

在这里插入图片描述

练习:
接收控制台的一个参数(输入文件名),编写一个shell脚本:
1)判断参数是否为空
2)如果不为空,则直接输出接收的参数是:hello.txt

在这里插入图片描述
在这里插入图片描述

简单示例:

#!/bin/bash
a="abc";
b="efg";
if [ $a = $b ]
then
   echo "a 等于 b"
else
   echo "a 不等于 b"
fi

输出:

a 不等于 b

3.6、文件相关运算符

常用:

选项说明
-d判断是否为目录
-e判断目录或文件是否****存在 exist
-f判断是否为文件
-r判断文件或目录针对当前用户是否可读
-w判断文件或目录针对当前用户是否可写
-x判断文件或目录针对当前用户是否可执行

全部:
在这里插入图片描述

使用方式很简单,比如我们定义好了一个文件路径file="/usr/learnshell/test.sh" 如果我们想判断这个文件是否可读,可以这样if [ -r $file ] 如果想判断这个文件是否可写,可以这样-w $file,是不是很简单。

四、shell流程控制

4.1、if 条件语句

【语法】:

#【语法一】
 if [ 表达式 ];then
    #代码
 elif [[ 表达式  ]];then
    #代码
 elif test 表达式  ;then   
    #代码
 else 
    #代码
 fi
 
#【语法二】
 if [ 表达式 ]
  then
    #代码
 elif [[ 表达式  ]];then
    #代码
 elif test 表达式  ;then   
    #代码
 else 
    #代码
 fi

【案例】:

#!/bin/bash
count=2
if [ $count -eq 1  ];then
   echo "相等"
elif [ $count -gt 1  ];then
   echo "$count大于1"
else
   echo "$count小于1"
fi
echo "-------------------------"
if [ $count -eq 1  ]
  then
   echo "相等"
else
   echo "不相等"
fi

简单的 if else-if else 的条件语句示例

#!/bin/bash
a=3;
b=9;
if [ $a -eq $b ]
then
   echo "a 等于 b"
elif [ $a -gt $b ]
then
   echo "a 大于 b"
else
   echo "a 小于 b"
fi

输出结果:

a 小于 b

在这里插入图片描述

#!/bin/bash
if [ $# -ne 2 ];then
  echo "至少要传递两个参数!"
  exit
fi

if [ -d $1 ];then
   $( ls -l $1 | wc -l > $2 )
else
   echo "输入的参数必须是目录类型。"
   exit
fi
echo "程序处理成功,写入完毕!"

在这里插入图片描述
相信大家通过上面的示例就已经掌握了 shell 编程中的 if 条件语句。不过,还要提到的一点是,不同于我们常见的 Java 以及 PHP 中的 if 条件语句,shell if 条件语句中不能包含空语句也就是什么都不做的语句。

4.2、case 条件语句

【语法】

 case  变量  in 
   "值")
      #代码
    ;;
   "值2")
      #代码
    ;;
   *)
      #代码
    ;;
 esac

【案例】

#!/bin/bash
echo "给与评价,A:优秀,B:良好,其他。。加油!"
#1)使用read提醒用户输入level
read -p "请输入成绩级别:"  level

#2)使用条件分支结构case,判断
case $level in
 "A")
    echo "优秀!!!"
 ;;  #相当于break
 "B")
    echo "良好!!"
 ;;
 *)
    echo "继续加油!"
 ;;
esac

4.3、for 循环语句

通过下面三个简单的示例认识 for 循环语句最基本的使用,实际上 for 循环语句的功能比下面你看到的示例展现的要大得多。

语法:

#语法一
for 变量 in 值1 值2 值3...
do
	# 循环操作
done

#语法二
for (( 初始值;循环控制条件;变量变化 ))
do
	# 循环操作
done

#语法三
for (( 初始值;循环控制条件;变量变化 ));do
	# 循环操作
done

#语法四
for [ 表达式 ];do
  #循环操作
done

#语法五
for [ 表达式 ]
do
  #循环操作
done

输出当前列表中的数据:

for loop in 1 2 3 4 5
do
    echo "The value is: $loop"
done

产生 10 个随机数:

#!/bin/bash
for i in {0..9}
do 
   echo $RANDOM;
done

输出1到5:

通常情况下 shell 变量调用需要加 $,但是 for 的 (()) 中不需要$,下面来看一个例子:

#!/bin/bash
for((i=1;i<=5;i++))
do
    echo $i;
done;

4.3、while 语句

语法:

while [ 条件判断式 ]
do
	#循环操作
donewhile [ 条件判断式 ];do
	#循环操作
done

基本的 while 循环语句:

#!/bin/bash
int=1
while(( $int<=5 ))
do
    echo $int
    let "int++"
done
#!/bin/bash
# 1~100的和
sum=0
i=1
while [ $i -le 100 ]
do
        sum=$[$sum+$i]
        i=$[$i+1]
done
echo "$sum"  #5050

使用read结合while循环读取文本文件

#!/bin/bash
file=$1         #将位置参数1的文件名复制给file
if [ $# -lt 1 ];then   #判断用户是否输入了位置参数
 echo "Usage:$0 filepath"
 exit
fi
# 从file文件中读取文件内容赋值给line(使用参数r会屏蔽文本中的特殊符号,只做输出不做转译)
while read -r line  
do
 echo $line    #输出文件内容
done  < $file
#!/bin/bash
file=$1
if [[ $# -lt 1 ]]
then
 echo "Usage: $0 please enter you filepath"
 exit
fi
while read -r f1 f2 f3  #将文件内容分为三列
do
 echo "file 1:$f1 ===> file 2:$f2 ===> file 3:$f3"  #按列输出文件内容
done < "$file"

while循环可用于读取键盘信息:**

echo '按下 <CTRL-D> 退出'
echo -n '输入你最喜欢的电影: '
while read FILM
do
    echo "是的!$FILM 是一个好电影"
done

输出内容:

按下 <CTRL-D> 退出
输入你最喜欢的电影: 变形金刚
是的!变形金刚 是一个好电影

无限循环:

while true
do
    command
done

4.4、read控制台输入

语法:

read (选项) (参数)
选项:
    -p 指定读取值时的提示符
    -t 指定读取值时等待的时间()
参数:
    变量:指定读取值的变量名
#!/bin/bash
read -t 5 -p "请输入参数" param
echo $param

4.5、TMOUT

TMOUT 数值 #单位秒
经常配合read使用
案例:

#!/bin/bash
TMOUT=3
echo "你的名字是?"
echo "你只有3秒回答!"
read name
if [ $? -eq 0 ]
then
  echo "你的姓名是:$name"
else
  echo "时间到!"
  exit 1 #因为等待时间到了,所以不是正常退出
fi

五、shell 函数

5.1、系统函数

5.1.1、basename

功能:

basename命令会删掉所有的前缀包括最后一个(‘/’)字符,然后将字符串显示出来
	即:得到路径对应的【文件名】,从路径的最后一个/开始向后截取

语法:

basename  路径 【后缀】
basename [pathname] [suffix]
basename [string] [suffix]
选项:
    suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉

案例:

   basename /opt/test_shell/tmout.sh  [.sh]
   mydir=/opt/test_shell/tmout.sh
   filename=$(basename $mydir .sh)  #提取文件名,并赋值
[root@biubiubiu opt]# ll
总用量 8
-rw-r--r--. 1 root root   29 26 10:48 hello.txt
drwxr-xr-x. 3 root root   20 115 09:02 model
drwxr-xr-x. 2 root root    6 1031 2018 rh
drwxr-xr-x. 3 root root 4096 26 17:07 shelltest
drwxr-xr-x. 2 root root   40 115 08:48 software
drwxr-xr-x. 2 root root   95 24 11:19 testdemo
[root@biubiubiu opt]# basename /opt/hello.txt
hello.txt
[root@biubiubiu opt]# basename /opt/hello.txt .tx
hello.txt
[root@biubiubiu opt]# basename /opt/hello.txt .txt
hello
5.1.2、dirname

功能:

dirname从给定的包含绝对路径的文件名中去除文件名(非目录部分),然后返回剩下的路径(目录的部分)
  即:从路径中得到【根路径】

语法:

dirname 文件绝对路径

案例:

   dirname /opt/test_shell/tmout.sh
   myfile=/opt/test_shell/tmout.sh
   rootDir=`dirname $myfile`  #提取根路径,并赋值
[root@biubiubiu opt]# ll
总用量 8
-rw-r--r--. 1 root root   29 26 10:48 hello.txt
drwxr-xr-x. 3 root root   20 115 09:02 model
drwxr-xr-x. 2 root root    6 1031 2018 rh
drwxr-xr-x. 3 root root 4096 26 17:07 shelltest
drwxr-xr-x. 2 root root   40 115 08:48 software
drwxr-xr-x. 2 root root   95 24 11:19 testdemo
[root@biubiubiu opt]# dirname /opt/hello.txt
/opt

5.1、不带参数没有返回值的函数

#!/bin/bash
hello(){
    echo "这是我的第一个 shell 函数!"
}
echo "-----函数开始执行-----"
hello
echo "-----函数执行完毕-----"

输出结果:

-----函数开始执行-----
这是我的第一个 shell 函数!
-----函数执行完毕-----

5.2、有返回值的函数

输入两个数字之后相加并返回结果:

#!/bin/bash
funWithReturn(){
    echo "输入第一个数字: "
    read aNum
    echo "输入第二个数字: "
    read anotherNum
    echo "两个数字分别为 $aNum$anotherNum !"
    return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $?"

输出结果:

输入第一个数字: 
1
输入第二个数字: 
2
两个数字分别为 1 和 2 !
输入的两个数字之和为 3

5.3、带参数的函数

#!/bin/bash
funWithParam(){
    echo "第一个参数为 $1 !"
    echo "第二个参数为 $2 !"
    echo "第十个参数为 $10 !"
    echo "第十个参数为 ${10} !"
    echo "第十一个参数为 ${11} !"
    echo "参数总数有 $# 个!"
    echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73

输出结果:

第一个参数为 1 !
第二个参数为 2 !
第十个参数为 10 !
第十个参数为 34 !
第十一个参数为 73 !
参数总数有 11 个!
作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 !

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值