Linux之Shell编程

shell是什么

shell是一个命令行解释器,他为用户提供一个向linux内核发送请求以便运行程序的界面系统级程序,用户可以用shell来启动,挂起,停止甚至编写一些程序。


shell脚本的执行方式

脚本格式要求

  1. 脚本以#!/bin/bash开头
  2. 脚本需要有执行权限

编写第一个shell脚本

shell 复制代码
vim hello.sh
#!/bin/bash
echo "hello,shell"

执行脚本

  1. hello.sh赋予执行权限
  2. 使用相对路径执行脚本./hello.sh,或者使用绝对路径执行脚本./home/shcode/hello.sh,或者使用sh hello.sh也可以使用绝对路径。

shell变量

linux shell中的变量可以分为系统变量和用户自定义变量

系统变量:$HOME, $PWD, $SHELL, $USER等等,比如 echo $SHELL

显示当前shell中的所有变量:set

shell变量的定义

语法
  1. 定义变量:变量名=值
  2. 撤销变量:unset 变量
  3. 声明静态变量:readonly 变量

静态变量无法unset

shell 复制代码
#!/bin/bash
# 定义变量A
A=100
#输出变量需要使用$
echo A=$A
echo "A=$A"
# 撤销变量A
unset A
echo "A=$A"
# 声明静态变量B=2,不能unset
readonly B=2
echo "B=$B"
#unset B
# 将指令的结果赋给变量,使用``或者$()
C=`date`
D=$(date)
echo "C=$C"
echo "D=$D"
# 使用环境变量 SHELL
echo "shell=$SHELL"

vim中多行注解

shell 复制代码
:<<!
xxx
...
!
定义变量的规范
  1. 变量名称可以由字母,数字和下划线组成,但是不能以数字开头。
  2. 等号两侧不能由空格
  3. 变量名一般习惯大写

设置环境变量

  1. vim /etc/profile
  2. export 变量名=变量值 (将shell变量输出为环境变量/全局变量)
  3. source 配置文件 (让修改后的配置信息生效)
  4. echo $变量名

在/etc/profile文件中定义TOMCAT_HOME环境变量


位置参数变量

当我们执行一个shell脚本时,如果希望获取到命令行的参数信息,就可以使用到位置参数变量。例如./myshell.sh 100 200这个就是一个执行shell的命令行,可以在myshell脚本中获取到参数消息(100和200)。

语法
  1. $n:n为数字,$0表示命令本身,$1- 9 表示第一到第九个参数,十以上的参数需要使用大括号包含, 9表示第一到第九个参数,十以上的参数需要使用大括号包含, 9表示第一到第九个参数,十以上的参数需要使用大括号包含,{10}
  2. $*:代表命令行中所有参数,把所有的参数看成一个整体
  3. @ :也代表命令行中所有参数,不过 @:也代表命令行中所有参数,不过 @:也代表命令行中所有参数,不过@把每个参数区分对待
  4. $#:代表命令行中所有参数的个数
shell 复制代码
#!/bin/bash
echo "0=$0, 1=$1,2=$2"
echo "所有的参数=$*"
echo "$@"
echo "参数个数=$#"

预定义变量

就是shell设计者事先已经定义好的变量,可以直接在shell脚本中使用。

语法
  1. :表示当前进程的进程号

  2. $?:最后一次执行的命令的返回状态,如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值非0,则证明上一个命令执行不正确。
shell 复制代码
#!/bin/bash
echo "当前进程的进程号id=$$"
# 以后台的方式运行一个脚本,并获取他的进程号
/home/shcode/hello.sh &
echo "最后一个后台方式运行的进程id=$!"
echo "执行的结果是=$?"

运算符

语法

  1. $((运算式)) 或 $[运算式] 或 expr m + n
  2. 注意expr运算符间要有空格,如果希望将expr结果赋给某个变量,使用``
  3. expr m - n
  4. expr *, /, % (乘,除,求余)

案例

shell 复制代码
#!/bin/bash
# 案例1:计算(2+3)* 4
# 使用第一种方式
RES1=$(((2 + 3)*4))
echo "res1=$RES1"
# 使用方式2,推荐使用
RES2=$[(2+3)*4]
echo "res2=$RES2"
# 使用方式3 expr
TEMP=`expr 2 + 3 `
RES4=`expr $TEMP \* 4`
echo "temp=$TEMP"
echo "res4=$RES4"
# 案例2:求命令行的两个参数的和 20 50
SUM=$[$1+$2]
echo "sum=$SUM"

流程控制

判断语句

语法

[ condition ]

注意condition前后要有空格,非空返回true, 可以使用$?验证(0为true,>1 为fasle)

判断语句:

  • = 字符串比较
  • 整数比较
    • -lt 小于
    • -le 小于等于 little equal
    • -eq 等于
    • -gt 大于
    • -ge 大于等于
    • -ne 不等于
  • 按照文件权限比较
    • -r 有读权限
    • -w 有写权限
    • -x 有执行权限
  • 按文件类型比较
    • -f 文件存在且是常规文件
    • -e 文件存储
    • -d 文件存在且是目录
案例
shell 复制代码
#!/bin/bash
# 案例1:字符串是否相等
if [ "ok" = "ok" ]
then
        echo "equal"
fi
# 案例2:23是否大于等于22
if [ 23 -gt 22 ]
then
        echo "大于"
fi
# 案例3:/home/shcode/oper.sh 文件是否存在
if [ -f /home/shcode/oper.sh ]
then
        echo "存在"
fi
#案例4:条件不为空
if [ root ]
then
        echo "root"
fi

if判断

语法
shell 复制代码
if [ condition ]
then
	语句块
fi
# 或,多分支
if [ condition ]
then
	语句块
elif [ condition ]
then
	语句块
fi
案例
shell 复制代码
#!/bin/bash
# 如果输入的参数大于等于60输出"及格了"否则输出"不及格"
if [ $1 -ge 60 ]
then
        echo "及格了"
elif [ $1 -lt 60 ]
then
        echo "不及格"
fi

case语句

语法
shell 复制代码
case $变量名 in
"值1")
语句块
;;
"值2")
语句块
;;
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
案例
shell 复制代码
#!/bin/bash
# 当命令行参数为1,输出周一,是2输出周二,其他情况输出other
case $1 in
"1")
echo "周一"
;;
"2")
echo "周二"
;;
*)
echo "other"
;;
esac

for循环

语法
shell 复制代码
for (( 初始值; 循环控制条件; 变量变化))
do
	代码
done
案例
shell 复制代码
#!/bin/bash
# 打印命令行输入的参数
# $*是把输入的参数,当做一个整体,所以只会输出一句
for i in "$*"
do
        echo "num is $i"
done
# $@获取输入的参数,是分开处理的
for j in "$@"
do
        echo "num is $j"
done
shell 复制代码
#!/bin/bash
SUM=0
for(( i=1; i<=$1; i++))
do
        SUM=$[$SUM+$i]
done
echo "SUM=$SUM"

while循环

语法
shell 复制代码
while [ condition ]
do
代码块
done
案例
shell 复制代码
#!/bin/bash
# 求1到n的值
SUM=0
i=0
while [ $i -le $1 ]
do
        SUM=$[$SUM+$i]
        i=$[$i+1]
done
echo "SUM=$SUM"

read读取控制台输入

语法

shell 复制代码
read (选项)(参数)

选项:

  • -p:指定读取值时的提示符
  • -t:指定读取值时等待的时间(秒),如果没有在指定的时间内输入,就不再等待。

参数:

  • 指定读取值的变量名

案例

shell 复制代码
#!/bin/bash
# 案例1:读取控制台输入的num1
read -p "请输入一个数NUM1=" NUM1
echo "你输入的NUM1="$NUM1
# 案例2:读取控制台输入的NUM2值,在10s内输入
read -t 10 -p "请输入一个数NUM2=" NUM2
echo "你输入的NUM2="$NUM2

函数

shell中既有系统函数也有自定义函数

系统函数

语法
shell 复制代码
basename [pathname] [suffix]

功能:返回完整路径最后/的部分,常用于获取文件名


shell 复制代码
dirname 文件绝对路径

自定义函数

语法
shell 复制代码
function functionName() {
  	Action;
    [return int;]
}
案例
shell 复制代码
#!/bin/bash
# 案例1:计算输入两个参数的和
function getSum() {
        SUM=$[$n1+$n2]
        echo "和是=$SUM"
}
# 输入两个值
read -p "请输入一个数n1=" n1

read -p "请输入一个数n2=" n2
# 调用自定义函数
getSum $n1 $n2
相关推荐
cominglately1 小时前
centos单机部署seata
linux·运维·centos
魏 无羡1 小时前
linux CentOS系统上卸载docker
linux·kubernetes·centos
CircleMouse1 小时前
Centos7, 使用yum工具,出现 Could not resolve host: mirrorlist.centos.org
linux·运维·服务器·centos
木子Linux2 小时前
【Linux打怪升级记 | 问题01】安装Linux系统忘记设置时区怎么办?3个方法教你回到东八区
linux·运维·服务器·centos·云计算
mit6.8242 小时前
Ubuntu 系统下性能剖析工具: perf
linux·运维·ubuntu
鹏大师运维2 小时前
聊聊开源的虚拟化平台--PVE
linux·开源·虚拟化·虚拟机·pve·存储·nfs
watermelonoops2 小时前
Windows安装Ubuntu,Deepin三系统启动问题(XXX has invalid signature 您需要先加载内核)
linux·运维·ubuntu·deepin
滴水之功3 小时前
VMware OpenWrt怎么桥接模式联网
linux·openwrt
ldinvicible3 小时前
How to run Flutter on an Embedded Device
linux
YRr YRr4 小时前
解决Ubuntu 20.04上编译OpenCV 3.2时遇到的stdlib.h缺失错误
linux·opencv·ubuntu