shell脚本基础

一、变量

1、变量的定义方式

变量名=值

2、变量的2个类型

1、普通变量

  • 存储用户相关的数据,用户的家目录,以及用户程序用到的登录信息

  • 作用域不同,普通变量仅在当前的shell有效

2、环境变量

  • 存储的系统核心数据,可执行文件的路径,系统的uid,系统的语言等

  • 当前shell和子shell都有效

  • export 变量名=值

[root@server ~]# export qq=q1
[root@server ~]# ww=q2
[root@server ~]# echo $qq
q1
[root@server ~]# echo $ww
q2
# 创建一个子shell
[root@server ~]# bash


Welcome to 5.10.0-182.0.0.95.oe2203sp3.x86_64

System information as of time: 	Tue May 27 09:12:20 PM CST 2025

System load: 	0.00
Processes: 	148
Memory used: 	9.1%
Swap used: 	0%
Usage On: 	8%
IP address: 	192.168.200.10
Users online: 	2

# 环境变量有效
[root@server ~]# echo $qq
q1
# 但是普通变量没有用
[root@server ~]# echo $ww


  • 将普通变量转换成环境变量

  • export 普通变量

#  
[root@server ~]# export ww

[root@server ~]# echo $ww
q2


3、变量的引用方式

1、$变量名和${}

[root@server ~]# A100=hell0
# $变量名,引用变量名的值
[root@server ~]# echo $A100
hell0
[root@server ~]# echo "$A100 123"
hell0 123

# ${变量名} 变量名的内容输出,括号外的内容正常输出,通常用来做字符串的拼接  
[root@server ~]# echo ${A100}123
hell0123


4、查看变量和取消变量

  • set查看所有变量
[root@server ~]# set | head 
A100=hell0
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:globasciiranges:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASHRCSOURCED=Y
BASH_ALIASES=()
BASH_ARGC=([0]="0")
BASH_ARGV=()
BASH_CMDS=()
BASH_COMPLETION_VERSINFO=([0]="2" [1]="11")
BASH_LINENO=()

  • 查看环境变量
[root@server ~]# env
SHELL=/bin/bash
HISTCONTROL=ignoredups
HISTSIZE=1000
HOSTNAME=server
qq=q1
PWD=/root
LOGNAME=root
MOTD_SHOWN=pam
HOME=/root
LANG=en_US.UTF-8


  • unset取消变量,环境变量和普通变量都可以进行取消
[root@server /]# unset A100
[root@server /]# echo $A100


1、重要的环境变量

  • PATH变量,存储了系统中所有可执行路径
# 创建一个命令
[root@server tmp]# vim qq
[root@server tmp]# chmod +x qq
[root@server tmp]# ls
qq
[root@server tmp]# ./qq
123
[root@server tmp]# cd 
[root@server ~]# qq
-bash: qq: command not found



# 加入到path路径下,这样就可以随时的使用这个命令了
[root@server ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@server ~]# PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/tmp/
[root@server ~]# q
qq              quote           quote_readline  
[root@server ~]# qq
123

  • HOME变量存储的家目录路径

二、bash shell中用户与脚本的交互方式

1、$1等符号

  • 使用位置化参数给脚本传参,执行脚本时后面接的参数
[root@server opt]# cat openeuler.sh 
echo hello $1

[root@server opt]# ./openeuler.sh  a1
hello a1

  • $1到$9和$

  • $1表示脚本的第一个参数

  • $0 表示脚本的路径

# 在哪里执行脚本,就显示脚本的路径
[root@server opt]# ./openeuler.sh 
./openeuler.sh
[root@server opt]# cd /
[root@server /]# /opt/openeuler.sh 
/opt/openeuler.sh

[root@server /]# cat /opt/openeuler.sh 
echo $0

  • $# 显示脚本一共有几个参数

  • 非常有用,就是创建用户的时候,需要传入三个参数,但是有的时候只传入了2个参数,因此使用$#判断是否传入了三个参数,判断成功了,就执行后面的操作

[root@server opt]# cat openeuler.sh 
echo $#

[root@server opt]# ./openeuler.sh  a1 12
2

2、接收用户输入

  • read -p "(提示信息)" 变量名

  • -s输入密码的时候,不可见

  • -t 设置超时时间,超时就直接跳过,执行下一行

[root@server opt]# cat openeuler.sh 
read -p "input name:" get_name
echo $get_name

[root@server opt]# ./openeuler.sh 
input name:asd
asd

三、bash shell中的条件测试语句

  • 命令的返回值为0到255,0表示命令执行成功,非0表示命令执行失败

  • $? 表示上一个命令的返回值为多少

1、逻辑运算符

1、逻辑与

  • && 逻辑与,命令1 && 命令2

  • 当第一条命令的返回值为0时,则执行第二条命令,若第一条命令不为0时,第二条命令不执行

  • 2个命令都为真,表达式就为真

# 判断主机能不能上网

# 访问一次
[root@server opt]# ping -c 1 qq.com && ifconfig

# 判断用户是否存在
[root@server opt]# id root &> /dev/null && echo ok
ok

2、逻辑或

  • 命令1 || 命令2

  • 当命令1返回值为0时,则不执行命令2,若返回值不为0时,则执行命令2

  • 一个结果为真,整个表达式的结果为真

# 判断用户是否存在,不存在创建,存在输出用户信息
[root@server opt]# id root || useradd root 
uid=0(root) gid=0(root) groups=0(root)


# 判断某个文件是否存在,如果文件存在,则输出文件信息,,如果文件不存在则创建文件

[root@server opt]# ls file.sh || touch file.sh
ls: cannot access 'file.sh': No such file or directory
[root@server opt]# ls
file.sh       nginx-1.22.1.tar.gz  nginx-1.25.4.tar.gz
nginx-1.22.1  nginx-1.25.4         openeuler.sh

3、结合起来

# 编写一个检测ip地址是否存活的脚本,如果ip地址正在被使用,则输出ip ok ,如果ip 地址没有被使用的话,则输出ip error ,要求该ip地址是用户手工输入通过脚本接收

[root@server opt]# cat openeuler.sh 
#!/bin/bash
ping -c 1 -W 1 $1 &> /dev/null && echo $1 is ok || echo $1 is error

[root@server opt]# ./openeuler.sh  192.168.200.10
192.168.200.10 is ok


4、条件测试语句

  • test 在linux中专门用来进行条件测试

  • test 表达式

  • [条件表达式]

  • [[条件表达式]]

  • 比较数值

img

# [[]] 这个是非常重要的,可以适合多种条件测试

# 逻辑与和逻辑或都在这个双层括号里面使用

[root@server opt]# a1=100
[root@server opt]# a2=100
[root@server opt]# a3=200

[root@server opt]# [[ $a1 -eq $a2 && $a3 -gt $a1 ]]
[root@server opt]# echo $?
0
  • 比较字符串

img

  • $()引用一条命令的执行结果作为变量的值
[root@server opt]# [ $(ifconfig ens33 | grep netmask | awk '{print $2}') == "192.168.200.10" ]
[root@server opt]# echo $?
0

# 因此的话,写脚本的时候可以这样定义
get_ip = $(ifconfig ens33 | grep netmask | awk '{print $2}')

# get_ip变量名=值

  • 文件测试

img

  • 布尔运算符,在[] 里面可以使用

  • test里面使用的

  • -a 逻辑与,当2个或者多个表达式同时成立,结果为真

  • -o 逻辑或,有一个成立,结果为真

  • -! 逻辑非,结果为真,取假

[root@server opt]# [ -f /etc/hostname -a -d /opt ]
[root@server opt]# echo $?
0

# 对结果取反
[root@server opt]# [ ! -f /etc/hostname ]
[root@server opt]# echo $?
1

四、程序语句

1、判断语句

1、if语句

  • if适合未知结果的判断

  • if 的格式

if 条件表达式;then
    执行代码

elif 条件表达式;then
    执行代码

else
    执行代码

fi

# 单分支结构

[root@server opt]# cat openeuler.sh 
#!/bin/bash
if id root &> /dev/null
then
	echo "root"
fi


[root@server opt]# cat openeuler.sh 
#!/bin/bash
if id asd &> /dev/null;then
	echo "存在"
else
	echo "不存在"
fi

[root@server opt]# cat openeuler.sh 
#!/bin/bash
if [ -d /opt/test ];then
	echo "test is d"
elif [ -f /opt/test ];then
	echo "test is f"
else
	echo "test other"
fi

2、case语句

  • 已知的结果

  • 适合于程序菜单

  • 语句结束,用分号结束即可

[root@server opt]# cat openeuler.sh 
#!/bin/bash
echo "1 启动服务"
echo "2 停止服务"
echo "3 重启服务"
read -p "input number:" get_num
case $get_num in
	1)
		systemctl start httpd
		;;
	2)
		systemctl stop httpd
		;;
	3)
		systemctl restart httpd
		;;
	*) # 不符合以上结果的话,执行这个
 		echo "输入有问题"
		;;
esac


[root@server opt]# ./openeuler.sh 
1 启动服务
2 停止服务
3 重启服务
input number:6
输入有问题

2、循环语句

1、for循环

  • 基于列表的循环
for 变量名 in 列表元素
do
	循环体
done


# 使用for完成用户列表的批量创建,并且设置用户密码为openeuler

[root@server opt]# cat user_list 
it_001
it_002
it_003
[root@server opt]# cat for_daemon.sh 
#!/bin/bash
for i in $(cat user_list)
do
	useradd $i
	echo user $i create 
done


# 检测主机ip是否存活

[root@server opt]# cat ip_check.sh 
#!/bin/bash
for i in {1..10}
do
	ping -c 1 -W 1 192.168.200.$i &>/dev/null && echo $i is ok || echo $i is error
done


2、while循环

  • 条件满足,则循环,不满足则不循环
while 条件表达式
do
	循环体

done

  • 编写一个创建用户的脚本,脚本要求用户输入uid,如果用户输入的uid已经存在,则提示用户重新输入,如果输入的uid不存在,则创建用户
[root@server opt]# cat while_user.sh 
#!/bin/bash
read -p "input_name:" get_name
read -p "input_uid:" get_uid
while id $get_uid &> /dev/null # 检测uid是否重复,重复则执行循环
do
	read -p "input_uid:" get_uid # 重复则,再次输入uid
done
useradd -u $get_uid $get_name
echo "$get_name is create"

3、until循环

  • 条件满足不循环,条件不满足则循环
until 条件表达式
do

	循环体

done

  • 通常用在服务器开机检测,或者自动化脚本等待开机场景
#!/bin/bash
until ping -c 1 192.168.200.10  &> /dev/null
do
        sleep 3
        echo wait configure
done
echo 192.168.200.10 is ok

# 这个ip如果通了,就结束了循环了

# 如果这个ip通不了,一直循环,

# 适合与服务器开机检测

4、循环中断

  • break,立刻中断所有的循环,当循环几次后,没有意义就退出整个循环
# 循环到第五次后就退出整个循环

[root@server opt]# cat break.sh 
#!/bin/bash
for i in $(seq 1 10)
do
	echo $i
	if [ $i -eq 5 ];then
		break
	fi		
done
12

  • continue中断本次循环,继续下次循环
# 循环到第五次的时候,退出,进行下一次循环
#!/bin/bash
for i in $(seq 1 10)
do
        if [ $i -eq 5 ];then
                continue
        fi
        echo $i 
done

  • 用户存在,不创建,不存在,创建用户
[root@server opt]# cat user.sh 
#!/bin/bash
for i in $(cat user_list)
do
# 用户存在中断了循环,继续下次循环
	id $i &> /dev/null && echo $i is error && continue
	useradd $i
	echo $i user create
done
[root@server opt]# cat user_list 
it_001
it_002
it_003
it_004

五、shell脚本运行方式

  • 绝对路径,需要脚本具有执行权限

  • 相对路径,脚本需要执行权限

  • bash 脚本不需要执行权限

  • source 在当前shell中执行,或者 . 来执行脚本,不需要执行权限

source 脚本

. 脚本

  • bash -x 脚本文件名

  • 跟踪脚本怎么运行的


[root@server opt]# bash -x user.sh 
++ cat user_list
+ for i in $(cat user_list)
+ id it_001
+ echo it_001 is error
it_001 is error  # 终端显示的
+ continue
+ for i in $(cat user_list)
+ id it_002
+ echo it_002 is error
it_002 is error
+ continue
+ for i in $(cat user_list)
+ id it_003
+ echo it_003 is error
it_003 is error
+ continue
+ for i in $(cat user_list)
+ id it_004
+ echo it_004 is error
it_004 is error
+ continue

脚本的三要素

  • 解释器,注释,程序语句
posted @ 2025-05-28 20:37  乔的港口  阅读(15)  评论(0)    收藏  举报