Shell编程

Shell是什么

  1. Shell是一门脚本语言(简单),属于解释性语言
  2. Shell脚本语言需要由解释器来解释执行,默认的解释器是Bash

Shell入门

#!/bin/bash #该语句可以升序,默认解释器就是 /bin/bash
echo ‘Hello World!’

解释

  • shell文件名可以有后缀(.sh),也可以没有后缀
  • shell除了第一行的#之外,在任何地方#就是注释
  • echo 其实等于与 System.out.println() 和 print

Shell的运行方式

方式一:sh 执行脚本

sh hello.sh # 这种方式不需要脚本文件有可执行权限

方式二:工作目录执行

cd /export/data/shell/
chmod +x hello.sh 或 chmod 111 hello.sh
./hello.sh # 这种方式需要脚本文件有可执行权限

方式二:绝对路径执行(推荐)

chmod +x hello.sh 或 chmod 111 hello.sh
/export/shell/hello.sh # 这种方式需要脚本文件有可执行权限

变量

变量就是存放变化数据的符号

变量的分类
  • 用户变量:用户自己定义的变量符号
  • 系统变量:系统已经定义的变量,在整个Linux系统起作用
  • 特殊变量
变量的数据类型
  • 字符串类型
  • 数字类型(属于特殊的字符串类型)

变量的定义格式

变量名=变量值 #注意,"="左右两侧不能有空格

变量的赋值方式
  • 直接赋值

    username="lft"
    
  • 从键盘赋值

    read username
    
  • 执行命令的结果赋值

    str=$(pwd)
    str=$(ll)
    str=$(ps -ef)
    
    str=`pwd`  #这里不是引号,是tab键上边的符号
    str=`ll`
    str=`ps -ef`
    
变量的访问

方式1:

echo $username

方式2:

echo ${username}xxx  #如果后边还有其他的字符,则必须使用该方式
只读变量

如果你定义了一个变量,不想让这个变量被再次赋值,则可以标记为只读变量

readonly username
删除变量

定义了一个用户变量之后, 默认的作用域是从变量定义开始到脚本结束,如果想让这个变量的空间提前释放,则可以用unset来设置

unset username

变量-环境变量

介绍
  • 环境变量都是Linux系统已经好的变量
  • 每一个环境变量都有特殊的含义,PWD
  • 环境变量的变量名都是大写字母
  • 我们也可以自己定义环境变量: /etc/profile

查看所有的环境变量

env

常见的环境变量

PATH 决定了shell将到哪些目录中寻找命令或程序
HOME 当前用户主目录
HOSTNAME 指主机的名称
PWD 当前用户的所在路径

如何访问环境变量

echo $PWD
echo $PATH

如何定义环境变量

  1. vi /etc/profile ,在文件末尾加上要定义的环境变量

export SERVICE_HOST=www.itcast.cn

  1. 将/etc/profile保存退出
  2. source /etc/profile 让配置生效
  3. 查看自定义环境变量
env
  1. 使用环境变量
echo $SERVICE_HOST

变量-特殊变量

特殊变量主要用于脚本的传参

变量解释
$#命令行参数的个数
$n$1表示第一个参数,$2表示第二个参数,以此类推
$0当前程序的名称
$?前一个命令或许或函数的返回码
$*以“参数1 参数2 。。。”形式保存所有参数

字符串

字符串的表达方式
  • 第一种: hello
  • 第二种: ‘hello’
  • 第三种: “hello” (推荐)
不同表达方式的区别

结论:推荐大家使用双引号

str=hello
str='hello'
str="hello"


str2='I am ${str}'   #单引号不会解释字符串中包含的变量
str2=I am ${str}"  #双引号引号可以解释字符串中包含的变量

字符串的处理

求字符串长度

#!/bin/bash
string="jobs"
echo ${#string}   # 输出结果: 4

对字符串进行截取

#!/bin/bash
string="敢于亮剑决不后退"
echo ${string:2:4}    # 输出结果为: 亮剑决不  从索引(从0开始)为2的字符开始截取,截取4个字符

算术运算符

计算-方式1

echo `expr 3 + 2`  # + 变量必须留空格,否则报错
echo `expr 3 \* 2` # * 是乘法 ,必须转义
echo `expr 3 % 1` # 

a=3
b=2
echo `expr $a + $b`

计算-方式2 (推荐)

echo $((3+2))  #  +两边不用留空格
echo $((3*2)) # * 是乘法,不用转义
echo $((3%2)) # 

a=3
b=2
echo $(($a+$b))
echo $((a+b)) # 括号里面的$可以省略

计算-方式3(推荐)

echo $[3+2]  # +两边不用留空格
echo $[3*2] # *是乘法 ,不用转义
echo $[3%2] #

a=3
b=2
echo $[$a+$b]
echo $[a+b] #$可以省略

数值的比较

== #比较两个数是否相同
!= #比较两个数字是否不同

流程控制语句

if语句-if

方式1

#!/bin/bash
if [ $(ps -ef | grep -c "ssh") -gt 1 ]
then 
 echo "true" 
fi

方式2

#!/bin/bash
if [ $(ps -ef | grep -c "ssh") -gt 1 ] ; then  #将if和then放在一行上,中间用分号隔开
 echo "true" 
fi

if语句-if else

方式1

#!/bin/bash
read -p "Enter your age(1-100):" age  #-p是输入的提示信息,提示信息和输入是在同一行进行
if [ $age -ge 18 ]
then
     echo '已经成年!'
else
     echo '未成年!'
fi

方式2

#!/bin/bash
read -p "Enter your age(1-100):" age  #-p是输入的提示信息,提示信息和输入是在同一行进行
if test $age -ge 18  #这里的test就等价于 []
then
     echo '已经成年!'
else
     echo '未成年!'
fi

if语句-if elif else

#!/bin/bash 
read -p "请输入a的值:"   a

read -p "请输入b的值:"  b
if [ $a -eq $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的特殊写法

#以下两种方式等价
#方式1
[ -n "$pid" ] && kill -9 $pid
test -n "$pid"  && kill -9 $pid

#方式2
if [-n "$pid" ]
then
 kill -9 $pid
fi

#!/bin/bash
[ -e "hello.sh" ] && rm -fr hello.sh   #如果前边成立,则会执行后边的操作
test -e "hello.sh"  && rm -fr hello.sh  #如果前边成立,则会执行后边的操作
test ! -e "hello.sh"  || rm -fr hello.sh #如果前边不成立,则会执行后边的操作


#未解决问题
if modprobe sunrpc || strstr "$(cat /proc/filesystems)" rpc_pipefs; then

for循环

格式1

#1、打印/root目录下所有文件的名字
#!/bin/bash  
for file in $(ls /root)
do 
        echo $file  
done

格式2

#!/bin/bash
s=0
#从1加到100
for(( i=1;i<=100;i=i+1))
#定义循环100次
do
 #每次循环给变量s赋值
 #s=$((s+i))  #传统写法
 let s+=i     #一种简写(和其他高级语言接轨)
done
#输出从1加到100的和
echo "The sum of 1+2+..+100 is : $s"

while循环

案例

#!/bin/bash
num=1
while [ $num -le 5 ]    # [] 需要使用   -le  推荐
#while (( $num <= 5 ))    # (()) 需要使用 <=
do
    echo $num
    #num=$((num+1))      #传统写法
    let num++            #一种简写(和其他高级语言接轨)
done

死循环

while的死循环

#!/bin/bash
while :
do
 echo "hello world"
 sleep 1  #休眠1秒钟
done

for的死循环

#!/bin/bash

for((;;))  ; do   #for和do可以放在同一行
 echo "hello world"
 sleep 1
done

case语句

#!/bin/bash
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  #结束关键字

跳出循环

break

#跳出本层循环
#!/bin/bash

while :
do
    echo -n "输入 1 到 5 之间的数字:"   #### -n表示不换行输出

    read  aNum

    case $aNum in
        1|2|3|4|5) echo "你输入的数字为 $aNum!"     ###case的穿透
        ;;
        *) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
            break                                 ###跳出while循环,不是跳出break
        ;;
    esac
done

continue

#跳出本次循环
#!/bin/bash
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

函数

格式

[ function ] funname()  # function关键字可以省略 ,不管有没有形参,函数名后的后边都写()
{
    action;        #函数体
    [return int;]  #return不是返回函数的返回值,返回的是函数的执行状态码(只能是整数)
}

入门案例
1.没有参数,没有返回值

#!/bin/bash

function demoFun(){
  echo "Hello World"
}

#调动函数
demoFun

2.没有参数,有返回状态码

#!/bin/bash
funWithReturn(){

    echo "这个函数会对输入的两个数字进行相加运算..."

    echo "输入第一个数字: "
read aNum

    echo "输入第二个数字: "

    read anotherNum
    echo "两个数字分别为 $aNum$anotherNum !"

    echo "两个数的和为:$((aNum+anotherNum))"
    return 100  ###返回函数的执行状态码 (范围:0-255 , 0表示成功,非0就表示失败)
}

funWithReturn ###调用函数
  
echo "函数的返回状态码:$?"   ###获取函数的返回状态码

3.有返回值的方法

#!/bin/bash
funWithReturn(){
  s=0
  for((i=1;i<=100;i++))
  do
    let s+=i
  done
  
  echo $s  ###函数的返回值通过这个echo返回,当有返回值时,函数内部只能有一个echo
}

result=$(funWithReturn)  ###调用有返回值的函数,返回值赋给result
#funWithReturn

echo "函数的返回值:${result}"
echo "函数的返回状态码:$?"

4.有参数,又有返回值

#!/bin/bash
funWithReturn(){
  s=0
  for((i=$1;i<=$2;i++))
  do
    let s+=i
  done
  echo $s
}

result=$(funWithReturn $1 $2)
#funWithReturn

echo "函数的返回值:${result}"
echo "函数的返回状态码:$?"

###执行脚本
sh  test31.sh 10 20 # $1就是10 $2就是20

数组的操作

定义数组

#!/bin/bash

my_array=("A" "B" "C" "D")

#我们也可以使用下标来定义数组:

array_name[0]=value0

array_name[1]=value1

array_name[2]=value2

获取数组中的所有元素和长度

#!/bin/bash
my_array[0]="A"
my_array[1]="B"
my_array[2]="C"
my_array[3]="D"

#获取数组元素
echo "数组的元素为: ${my_array[*]}"
echo "数组的元素为: ${my_array[@]}" #两种方式等价

#获取数组长度
echo "数组元素个数为: ${#my_array[*]}"
echo "数组元素个数为: ${#my_array[@]}"

遍历数组

#!/bin/bash

my_arr=('AA BB' 'CC')  
my_arr_num=${#my_arr[*]}  #获取数组长度
for((i=0;i<my_arr_num;i++));
do
  echo "----------------- ------------"
  echo ${my_arr[$i]}  # 通过索引获取每一个元素
done

脚本的相互调用

脚本之间可以进行导入
demo0.sh

#!/bin/bash

func1(){
  echo "Hello World0"
}

demo1.sh

#!/bin/bash
#定义数组
array=("AA" "BB" "CC" "DD")

#定义方法
func1(){
  echo "Hello World1"
}

demo2.sh

#!/bin/bash

######方式1############
#. /export/shell/demo1.sh          #导入demo1.sh脚本-绝对路径(推荐)
#. ./demo1.sh                      #导入demo1.sh脚本-相对路径

######方式2############
#source ./demo1.sh                 #导入demo1.sh脚本-相对路径

######调入多个脚本######
source /export/shell/demo0.sh      #导入demo0.sh脚本-绝对路径
source /export/shell/demo1.sh      #导入demo1.sh脚本-绝对路径

my_arr_num=${#array[*]}  #获取数组长度
for((i=0;i<my_arr_num;i++));
do
  echo "----------------- ------------"
  echo ${array[$i]}  # 通过索引获取每一个元素
done

func1 #当多个脚本中有同名函数,则导入方式是就近原则
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值