首页 > 系统相关 >Shell脚本基本功

Shell脚本基本功

时间:2023-02-11 23:23:50浏览次数:43  
标签:脚本 case shell name echo Shell 参数 基本功 循环

1. Shell脚本基本功

1.1. 概述

工作时项目发布与部署会用到shell脚本,有时需要自己写一部分自定义脚本,自己学习了一段时间,通过这段时间的了解与实践,发现其学习起来并不难,学会后还可以节省自己很多时间,此处整理总结下,大致能满足工作上的要求。

Shell 脚本的优势在于处理偏操作系统底层的业务,例如,Linux 内部的很多应用(有的是应用的一部分)都是使用 Shell 脚本开发的,因为有 1000 多个 Linux 系统命令为它作支撑,特别是 Linux 正则表达式以及三剑客 grep、awk、sed 等命令。

1.2. 变量

1.2.1. 变量类型

运行shell时,会同时存在三种变量:

1) 局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。

2) 环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。

3) shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行

1.2.2. 定义变量

your_name="11111.com"

注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:

  1. 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头;
  2. 中间不能有空格,可以使用下划线 _;
  3. 不能使用标点符号;
  4. 不能使用bash里的关键字(可用help命令查看保留关键字);

有效的 Shell 变量名

RUNOOB
LD_LIBRARY_PATH
_var
var2

无效的变量命名:

?var=123
user*name=runoob

1.2.3. 变量使用

#使用一个定义过的变量,只要在变量名前面加美元符号即可
your_name="Hello World!"
echo $your_name

#用语句给变量赋值
for file in `ls /etc`;do
        echo $file
done

1.2.4. 字符串变量

单引号&双引号

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

str='this is a string'

单引号字符串的限制:

  • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
  • 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。

双引号

your_name="runoob"
str="Hello, I know you are \\"$your_name\\"! \\n"
echo -e $str

双引号的优点:

  • 双引号里可以有变量
  • 双引号里可以出现转义字符

拼接字符串

示例:

your_name="runoob"
# 使用双引号拼接
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting  $greeting_1
# 使用单引号拼接
greeting_2='hello, '$your_name' !'
greeting_3='hello, ${your_name} !'
echo $greeting_2  $greeting_3

结果:

hello, runoob ! hello, runoob !
hello, runoob ! hello, ${your_name} !

获取字符串长度

string="abcd"
echo ${#string} #输出 4

提取子字符串

以下实例从字符串第 2 个字符开始截取 4 个字符:

string="runoob is a great site"
echo ${string:1:4} # 输出 unoo

注意:第一个字符的索引值为 0。

查找子字符串

查找字符 i 或 o 的位置(哪个字母先出现就计算哪个):

string="runoob is a great site"
echo `expr index "$string" io`  # 输出 4

注意: 以上脚本中 ` 是反引号,而不是单引号 ',不要看错了哦。

1.2.5. Shell 数组

bash支持一维数组(不支持多维数组),并且没有限定数组的大小。类似于 C 语言,数组元素的下标由 0 开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于 0。

定义数组

在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的一般形式为:

数组名=(值1 值2 ... 值n)

例如:

array_name=(value0 value1 value2 value3)

或者

array_name=(
value0
value1
value2
value3
)

还可以单独定义数组的各个分量:

array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen

可以不使用连续的下标,而且下标的范围没有限制。

读取数组

读取数组元素值的一般格式是:

${数组名[下标]}

例如:

valuen=${array_name[n]}

使用 @ 符号可以获取数组中的所有元素,例如:

echo ${array_name[@]}

获取数组的长度

获取数组长度的方法与获取字符串长度的方法相同,例如:

# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}

1.3. 流程控制

1.3.1. if语句

和 Java、PHP 等语言不一样,sh 的流程控制不可为空

语法:

if condition
then
    command1 
    command2
elif condition2
then
    command2
fi

示例:

if [ $(ps -ef | grep -c "ssh") -gt 1 ];
 then echo "true"; 
fi

a=10
b=20
if [ $a == $b ]
then
   echo "a 等于 b"
elif [ $a -gt $b ]
then
   echo "a 大于 b"
elif [ $a -lt $b ]
then
   echo "a 小于 b"
else
   echo "没有符合的条件"
fi


if else 语句经常与 test 命令结合使用,如下所示:

示例:

num1=$[2*3]
num2=$[1+5]
if test $[num1] -eq $[num2]
then
    echo '两个数字相等!'
else
    echo '两个数字不相等!'
fi

1.3.2. for 循环

for循环一般格式为:

for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done

当变量值在列表里,for 循环即执行一次所有命令,使用变量名获取列表中的当前取值。命令可为任何有效的 shell 命令和语句。in 列表可以包含替换、字符串和文件名。in列表是可选的,如果不用它,for循环使用命令行的位置参数。

示例:

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

1.3.3. while 语句

while 循环用于不断执行一系列命令,也用于从输入文件中读取数据。其语法格式为:

while condition
do
    command
done

以下是一个基本的 while 循环,测试条件是:如果 int 小于等于 5,那么条件返回真。int 从 1 开始,每次循环处理时,int 加 1。运行上述脚本,返回数字 1 到 5,然后终止。

示例:

int=1
while(( $int<=5 ))
do
    echo $int
    let "int++"
done

1.3.4. until 循环

until 循环执行一系列命令直至条件为 true 时停止。until 循环与 while 循环在处理方式上刚好相反。一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。

until 语法格式:

until condition
do
    command
done

condition 一般为条件表达式,如果返回值为 false,则继续执行循环体内的语句,否则跳出循环。

以下实例我们使用 until 命令来输出 0 ~ 9 的数字:

示例:

a=0
until [ ! $a -lt 10 ]
do
   echo $a
   a=`expr $a + 1`
done

1.3.5. case 语句

case ... esac 为多选择语句,与其他语言中的 switch ... case 语句类似,是一种多分枝选择结构,每个 case 分支用右圆括号开始,用两个分号 ;; 表示 break,即执行结束,跳出整个 case ... esac 语句,esac(就是 case 反过来)作为结束标记。可以用 case 语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。

case 语法格式如下:

case 值 in
模式1)
    command1
    command2
    ...
    commandN
    ;;
模式2)
    command1
    command2
    ...
    commandN
    ;;
esac

case 工作方式如上所示,取值后面必须为单词 in,每一模式必须以右括号结束。取值可以为变量或常数,匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。

示例:

echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
    1)  echo '你选择了 1'
    ;;
    2)  echo '你选择了 2'
    ;;
    3)  echo '你选择了 3'
    ;;
    4)  echo '你选择了 4'
    ;;
    *)  echo '你没有输入 1 到 4 之间的数字'
    ;;
esac

1.3.6. 跳出循环

在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell使用两个命令来实现该功能:break和continue。

break命令: break命令允许跳出所有循环(终止执行后面的所有循环)。

实例:脚本进入死循环直至用户输入数字大于5

while :
do
    echo -n "输入 1 到 5 之间的数字:"
    read aNum
    case $aNum in
        1|2|3|4|5) echo "你输入的数字为 $aNum!"
        ;;
        *) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
            break
        ;;
    esac
done

continue: continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。

示例:

while :
do
    echo -n "输入 1 到 5 之间的数字: "
    read aNum
    case $aNum in
        1|2|3|4|5) echo "你输入的数字为 $aNum!"
        ;;
        *) echo "你输入的数字不是 1 到 5 之间的!"
            continue
            echo "游戏结束"
        ;;
    esac
done

1.4. 函数

linux shell 可以用户定义函数,然后在shell脚本中可以随便调用

1.4.1. 定义格式

shell中函数的定义格式如下:

[ function ] funname [()]

{

    action;

    [return int;]

}

说明:

  • 1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
  • 2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255

下面的例子定义了一个函数并进行调用:

实例

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

输出结果:

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

下面定义一个带有return语句的函数:

funWithReturn(){
    echo "这个函数会对输入的两个数字进行相加运算..."
    echo "输入第一个数字: "
    read aNum
    echo "输入第二个数字: "
    read anotherNum
    echo "两个数字分别为 $aNum 和 $anotherNum !"
    return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"

函数返回值在调用该函数后通过 $? 来获得。

注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。

1.4.2. 函数参数

在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数...

带参数的函数示例:

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 !

注意,$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数

参数注意点

img

标签:脚本,case,shell,name,echo,Shell,参数,基本功,循环
From: https://www.cnblogs.com/yq12138/p/17112786.html

相关文章

  • linux基本功系列之tar命令实战
    前言大家好,又见面了,我是沐风晓月,本文是专栏【linux基本功-基础命令实战】的第44篇文章。此专栏是沐风晓月对Linux常用命令的汇总,希望能够加深自己的印象,以及帮助到其他的......
  • 自学shell的笔记
    shell理论:第一章了解shell用法、变量、字符、特殊字符、自增的用法shell变量程序运行时候,内存空间的某些值是变化的,这个内存空间就理解为变量。变量的类型自定义变量(局......
  • Linux xsync命令脚本
    功能:在主机上分发文件到其他机器在主机machine136上进行如下操作(master)1、安装rsyncyuminstall-y rsync2、bin下创建xsync转自:(82条消息)Linuxxsync命令脚本_h......
  • thttpd 2.27(最新)移植指南(官方安装脚本好多坑,我只想说)
    PS:要转载请注明出处,本人版权所有。PS:这个只是基于《我自己》的理解,如果和你的原则及想法相冲突,请谅解,勿喷。前置说明  本文作为本人csdnblog的主站的备份。(BlogID......
  • Ubuntu(Linux) PyQt5 QtUIFile 转换为 PythonModule (pyuic.py/pyuic脚本)
    PS:要转载请注明出处,本人版权所有。PS:这个只是基于《我自己》的理解,如果和你的原则及想法相冲突,请谅解,勿喷。前置说明  本文作为本人csdnblog的主站的备份。(BlogID......
  • Ubuntu14.04 apache2 配置 CGI(并测试:shell,可执行文件,python)
    PS:要转载请注明出处,本人版权所有。PS:这个只是基于《我自己》的理解,如果和你的原则及想法相冲突,请谅解,勿喷。前置说明  本文作为本人csdnblog的主站的备份。(BlogID......
  • Shell 编写摘要 (一)
    PS:要转载请注明出处,本人版权所有。PS:这个只是基于《我自己》的理解,如果和你的原则及想法相冲突,请谅解,勿喷。前置说明  本文作为本人csdnblog的主站的备份。(BlogID......
  • Linux手动启动、关闭、重启jar包相关shell脚本
    1、启动文件start.sh#!/bin/sh###APP_NAME=$(basename$(dirname"$PWD"))JAVA_OPTS="-Djava.awt.headless=true-Djava.net.preferIPv4Stack=true"JAVA_DEBUG_......
  • Windbg脚本采摘
    "usestrict";//32bitletarr=["xxxx"];functioninitializeScript(){return[newhost.apiVersionSupport(1,7)];}functionlog(str){host.diagnostics.d......
  • 750~751 JSP脚本,入门学习
    JSP的脚本:JSP定义Java代码的方式1.<% 代码%>:定义的java代码,在service方法中。service方法中可以定义什么,该脚本中就可以定义什么。2.<%!代码%>:定义的java......