shelll基础

一、变量

1、变量的类型

1、普通变量

  • 直接在当前的shell中定义这个变量即可,可以直接使用$符号引用的

  • 在创建一个bash shell的话,就不能引用了

  • 因此的话就是这个普通变量的话只能作用当前的shell

[root@master ~]# name=10
[root@master ~]# echo $name
10

2、环境变量

  • 就是系统变量

  • 定义的方式 export 变量名即可

  • 也可以将普通变量直接转换为环境变量,直接使用export即可

[root@master ~]# export  name

# env可以查看环境变量

[root@master ~]# env |grep name
name=10

1、重要的环境变量和修改

  • 主要就是PATH变量,这个就是命令会补全的功能

  • **这些目录下面的命令都是具备+x的权限,可以tab键补全的

[root@master ~]# echo $PATH
/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

[root@master ~]# vim qq
[root@master ~]# chmod +x qq
[root@master ~]# cat qq
ls
[root@master ~]# ls
anaconda-ks.cfg  qq

# 可以再次基础上直接重新加入一些东西
[root@master ~]# PATH=/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/

[root@master mnt]# qq
hgfs

# 退出这个shell就不能使用了,因为是普通变量的修改,也可以使用环境变量的修改export 来修改

2、变量的引用

1、$可以直接的使用

[root@master ~]# name=10
[root@master ~]# echo $name
10

2、还有一个就是${}

  • 这个就是可以直接使用变量名和自己添加的字符串
# name这个变量输出了,然后后面的字符串就可以输出了

# 拼接的一种

[root@master ~]# echo ${name}99
1099

3、$()

  • 就是将这个$(命令) 这个命令显示输出的结果赋值给变量
[root@master shell]# name=$(date)
[root@master shell]# echo $name
Wed Sep 3 10:23:52 PM EDT 2025

3、取消变量

1、查看变量

  • set可以查看所有变量,包含环境变量和普通变量

  • env只能查看环境变量

[root@master ~]# set | head 
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=()
BASH_REMATCH=()


# env
[root@master ~]# env | head 
SHELL=/bin/bash
HISTCONTROL=ignoredups
HISTSIZE=1000
HOSTNAME=master
PWD=/root
LOGNAME=root
XDG_SESSION_TYPE=tty
MOTD_SHOWN=pam
HOME=/root
LANG=en_US.UTF-8

2、unset取消变量

  • 可以直接取消变量,环境变量和普通变量都可以取消掉的
[root@master ~]# echo $name
10

# 这样就取消掉了
[root@master ~]# unset name
[root@master ~]# echo $name

二、bash shell与用户进交互

  • 也就是输入和输出

  • 用户输入一些参数等等,然后编写一个实现一个功能的shell脚本,执行完成需求即可

1、$1参数到$9(位置化参数)

  • 这个就是位置化参数,执行脚本,在脚本的后面添加一些参数,就能传入进去了

  • 需要注意的就是按照顺序才能正确输出成功

[root@master shell]# cat 1.sh 
echo hell0 $1 $3

# 需要注意的就是a2没有输出,因为是脚本只接收第一个参数和第三个参数,第二个参数是不接受的,也就是不会输出

[root@master shell]# ./1.sh a1 a2 a3
hell0 a1 a3

1、$0参数

  • 这个会显示脚本的路径

  • 你是在哪个位置执行的话,就会显示在这个路径下面的路径

[root@master ~]# cat shell/1.sh 
echo hell0 $1 $3
echo $0

# 就会显示在shell目录下面的文件了

[root@master ~]# bash shell/1.sh 
hell0
shell/1.sh

2、$#参数

  • 显示脚本一共传入了几个参数,这个非常的有用

  • 在写脚本的时候,可以写一个判断就能够判断出来了,当输出的参数不满足2个或者自定义的时候,报错

[root@master ~]# bash shell/1.sh  a1 a2 a3
hell0 a1 a3
3

3、$?

  • 显示上一个命令的结果是否正确,0表示正确,其他的数字表示错误

  • 非常的有用,就是用于判断的

[root@master ~]# ls
anaconda-ks.cfg  qq  shell
[root@master ~]# echo $?
0

2、接收用户的输入(read)

  • p选项的会打印后面的字符串内容,就是这个字符串
[root@master shell]# cat 1.sh 
read -p "input name: " get_name
echo $get_name

# 执行脚本

[root@master shell]# bash 1.sh 
input name: qq
qq

  • s 就是密文输入,一般就是用于这个,隐私输入的

  • t 时间 超出这个时间就会退出这个输入,直接进行下面的输入即可

[root@master shell]# cat 1.sh 
read -p "input name: " get_name
echo $get_name
read -s -p "input passwd: " get_passwd 
echo 
echo $get_passwd

# 超时5秒后就会跳过这个,继续执行下面的内容
read  -t 5 -p "chaoshi " out
echo 123


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

1、逻辑与

  • 命令1 && 命令2 前面一个命令正确执行了,就会执行后面的命令2,否则不执行,直接报错

  • 必须都正确执行了命令,这个返回结果才是正确的

[root@master ~]# ls && cd /
anaconda-ks.cfg  qq  shell

[root@master /]# echo $?
0

2、逻辑或

  • 命令1 || 命令2 至少有一个命令执行正确了,这个命令的返回结果就是正确的

  • 前一个命令执行错误了,还会执行后面的命令的,不会跳过,有个命令正确执行了,就不会执行后面的命令了

[root@master /]# qwqw || ls
-bash: qwqw: command not found
afs  boot  etc   lib    media  opt   root  sbin  sys  usr
bin  dev   home  lib64  mnt    proc  run   srv   tmp  var
[root@master /]# echo $?
0

3、结合起来使用

  • 检测一个ip是否存活的
# && ping命令执行成功了,就会执行后面的

# || 前面的命令执行错误的话,就会执行后面的命令

[root@master shell]# cat 2.sh 
ping -c 1 -W 1 $1 > /dev/null && echo $1 is ok || echo $1 is error

4、test条件测试语句

  • test 表达式
# 可以直接的使用即可

[root@master shell]# n1=10
[root@master shell]# n2=20
[root@master shell]# test $n1 -gt $n2
[root@master shell]# echo $?
1
[root@master shell]# test $n1 -lt $n2
[root@master shell]# echo $?
0

5、测试符

img

img

img

6、[[ ]] 测试符

  • 这个算是高级的, && 和 || 都能在这个里面使用,但是不能再[ ] 这个里面使用,会出现错误的

  • 可以直接和if来结合使用,因为这个测试的有一个返回值0或者非0,即正确和错误即可

  • 需要注意的就是这个前面和后面的[ ]都需隔开一点

  • 有一个返回结果

  • 里面可以是字符串,还有一些就是条件的测试语句,也就是有比较的,不能是多个命令连接一起的

# 都有一个返回的结果

[root@master shell]# n1=10
[root@master shell]# n2=10


[root@master shell]# [[ $n1 -lt $n2 ]]
[root@master shell]# echo $?
1
[root@master shell]# [[ $n1 -eq $n2 ]]
[root@master shell]# echo $?
0

# 这个命令的返回结果就是正确的
[root@master shell]# [[ $n1 -eq $n2 && ls ]]
[root@master shell]# echo $?
0


[root@master shell]# n1=10
[root@master shell]# n2=10
[root@master shell]# [[ $n1 != $n2 ]]
[root@master shell]# echo $?
1
[root@master shell]# [[ $n1 = $n2 ]]
[root@master shell]# echo $?
0

7、[ ] 测试符

  • 就是比较简单的,不能使用 && ||

  • -a 逻辑与

  • -o 逻辑或

  • ! 逻辑非 结果为真,取反

# 这个etc目录存在并且这个 后面也是非空字符串,因此返回结果就是正确的

[root@master shell]# [ -d /etc -a assdad ]
[root@master shell]# echo $?
0


# 逻辑非的使用,就是这个 ! 取的结果就是相反的结果的,结果为真就去反,结果为假就去真,反骨的符号

[root@master ~]# [ -d /etc ]
[root@master ~]# echo $?
0
[root@master ~]# [ ! -d /etc ]
[root@master ~]# echo $?
1


8、总结测试语句

  • 需要注意的就是 test,[ ],[[ ]]

  • 这些测试符的话,都是有一个返回结果的,要么是0(正确执行了),要么就是非0(错误的结果)

# 能够正确执行命令,返回结果就为真
[root@master ~]# [[ -d /etc && ls ]]
[root@master ~]# echo $?
0

四、程序语句

1、if语句

  • 顾名思义,就是一个简单的判断语句,特别的常用,用于做判断的

1、if的格式

# if开头

if 表达式;then
    语句块

elif 表达式;then
    语句块

else
    语句块

fi  # fi结尾


  • 当上面的判断都不符合的时候,就会执行else语句块了

  • 非常的通俗易懂,不是正确的就会执行后面的判断了即可

2、案例

[root@master shell]# cat 3.sh 
if [ -d /etc ];then
	echo "is directory"

elif [ -f /etc/passwd ];then
	echo "is file"
	
else
	echo "error"
fi
[root@master shell]# bash 3.sh 
is directory

2、case语句

  • 这个就是用于已知的结果

  • 适用于程序菜单

1、case格式

case 变量 in
数字或者字符串或者通配符)
    代码
    ;;
数字或者字符串或者通配符)
    代码
    ;;

*) # 上面的条件都不符合的话,就会执行这个语句块
    语句块
    ;;

esac

2、案例

[root@master shell]# cat 4.sh 
# start,stop,restart

read -p "input num: " get_num
case $get_num in
	1)
		echo "start sshd"
		systemctl start sshd
		;;
	2)
		echo "restart sshd"
		systemctl restart sshd
		;;
	3)
		systemctl stop sshd
		;;
	*)
		echo "error"
		;;
esac


# 数字换成start,stop,restart,也是可以的

3、for语句

  • 基于列表的循环

  • 一般是循环的次数是已知的

  • 一般是按照空格进行分割

1、for格式

for 变量 in 列表元素(查看的东西)
do

    代码块

done

2、for案例

  • 遍历一个文件,然后依次添加用户
[root@master shell]# cat 5.sh 
for i in $(cat user_list)
do
	useradd $i
	echo "user $i create"
done	
[root@master shell]# cat user_list 
it_001
it_002
it_003

4、while语句

  • 条件满足,循环,也就是为真就循环,不满足就不循环

1、while格式

while 表达式 
do

    代码块

done 
    代码块,是循环结束后的执行的代码

2、while案例

  • 这个文件存在的话,就会一直输出exist,然后睡眠4秒

  • 然后我删除了这个文件,这个循环就会终止,执行后面的代码

[root@master shell]# cat 6.sh 
while [ -f 1.sh ]
do
	echo "exist"
	sleep 4
done 
	echo "no exist"

[root@master shell]# bash 6.sh 
exist
exist
exist
exist
exist
no exist

5、until语句

  • 与while语句是相反的,条件不满足执行循环体

  • 条件满足的话,不会执行这个循环体

  • 也就是说这个表达式的结果为假的时候执行,为真的时候不执行

1、while格式

until 表达式
do

    代码块

done
代码块

2、while案例

[root@master shell]# cat 7.sh 
until [ -d /etc ]
do
	echo "exist"
	sleep 5
done
echo "q"

6、中断语句

1、break语句

  • 直接跳出循环,不执行后面的循环了
[root@master shell]# cat 8.sh 
for i in `seq 1 10`
do
	if [ $i -eq 5 ];then
		break
	else
		echo $i
	fi
done
[root@master shell]# bash 8.sh 
1
2
3
4

2、continue语句

  • 终止本次循环,继续执行后面的循环,没有跳出循环
[root@master shell]# cat 9.sh 
for i in `seq 1 10`
do
	if [ $i -eq 5 ];then
		continue
	else
		echo "$i"
	fi
done

[root@master shell]# bash 9.sh 
1
2
3
4
6
7
8
9
10

五、shell脚本运行的方式

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

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

  • bash 脚本不需要执行权限

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

  • bash -x 脚本 可以跟踪这个脚本是怎么运行的

posted @ 2025-09-04 15:02  w7nn  阅读(4)  评论(0)    收藏  举报