Shell 变量

变量的本质:变量是内存中的一块空间,变量名字==> 内存空间地址。

变量命名

变量名字命名要求:

  • 不能以数字开头
  • 不能以除了字母或_ 以外开头
  • 推荐使用:单词 并以_分隔 为变量命名 (如:person_of_name)

变量赋值

赋值方式

方式 格式 描述
直接赋值 name=jiang 最常见方式
命令结果赋值 hostname=`hostname` 获取命令的结果 ` `或 $()
通过脚本命令行传参进行复制 user_name=$1 脚本的第一个参数 一般用于命令行内容传入脚本
交互式赋值 通过read 命令实现 与用户有个交互过程
读取文件内容赋值给变量 脚本读取文件的时候使用

read 赋值

read 是一个命令,可以通过read实现交互式赋值

选项 描述
-p 交互的时候提示信息
-t 超过这个时间没有操作,则自动退出
-s 不显示用户的输入(记录密码的时候使用)

⚠️ -p 参数需要在所有参数的最后

  • 基本用法
[root@devops-shell ~]# read -p '请输入密码:' pass
请输入密码:123456
[root@devops-shell ~]#
[root@devops-shell ~]# echo $pass
123456
  • -t
# 5 秒无操作,则自动退出
[root@devops-shell ~]# read -t 5 -p '请输入密码:' pass
请输入密码:
  • -s
[root@devops-shell ~]# read -s -p '请输入密码:' pass
请输入密码:                          # 不显示输入的内容
[root@devops-shell ~]# echo $pass
123456
  • 同时向2个变量赋值
[root@devops-shell ~]# read  -p '请输入2个数字 num1 num2:' num1 num2
请输入2个数字 num1 num2:111 222
[root@devops-shell ~]# echo $num1
111
[root@devops-shell ~]# echo $num2
222

变量分类

普通变量
环境变量(全局变量)
特殊变量

普通变量

⚠️ $ 与 ${} 作用都是调用变量,只有一些细微差别。

[root@devlops ~]# day=996
[root@devlops ~]# echo $day
996

[root@devlops ~]# echo $day111

[root@devlops ~]# echo ${day}111
996111

环境变量

  • 全局变量: 1处定义,处处使用.

  • 大部分都是系统定义的,我们一般就是修改.

  • 查看环境变量命令: env 、export 、declare

  • 修改环境变量命令:export

常见环境变量

环境变量 描述 应用场景
PATH 记录命令位置的环境变量,运行命令的时候bash会在PATH的路径中查找 通过二进制,编译,安装软件时
增加命令路径
LANG 设置系统语言与字符集 LANG=zh_CN.UTF8 LANG=en_US.UTF8 修改语言或字符集
PS1 命令行格式 修改命令行格式
UID 或 EUID 用户的uid,用于判断当前用户是否为root 用于脚本判断用户是否为root
HOSTNAME 主机名
  • 安全相关变量
环境变量 描述 应用场景
HISTSIZE history 命令,记录命令的最大数量,生产中尽量少 安全优化
HISTFILESIZE history 历史记录文件大小
~/.bash_history生产环境尽量少
安全优化
HISTCONTROL 控制历史命令记录或不记录哪些内容
生产环境 ignorespace 以空格开头的命令不记录
安全优化
HISTFILE 指定历史命令的记录文件的名字和位置,默认当前用户家目录 .bash_history 安全优化
PROMPT_COMMAND 存放命令,命令行执行命令后会运行这个变量的内容,用于实现行为审计(记录用户操作) 安全优化
IFS 类似于 awk -F 指定分隔符(指定每一列的分隔符) 一般与循环配合读取文件内容
TMOUT 超时自动退出时间 安全优化

修改环境变量

  • 临时修改(永久的就是写入到 /etc/profile最后即可)
# 把当前系统语言改为中文,字符集改为UTF-8
[root@devlops ~]# export LANG=zh_CN.UTF-8
[root@devlops ~]# env | grep -i lang
LANG=zh_CN.UTF-8

环境变量相关文件及目录

执行优先级:/etc/profile > /etc/bashrc > ~/.bashrc > ~/.bash_profile

文件或目录 描述
/etc/profile 全局生效,存放函数,环境变量,别名
/etc/bashrc 全局生效,存放别名
~/.bashrc 局部生效
~/.bash_profile 局部生效
/etc/profile.d/ 目录,每个用户登录的时候(远程连接与su切换),加载目录下面 .sh 结尾的文件
常用于设置一些登录后提示
  • 案例:书写脚本每次用户登录后显示系统的基本信息。(将脚本放入 /etc/profile.d/ 目录下)
[root@devops-shell ~]# cat /etc/profile.d/01.sys_login_info.sh
#!/bin/bash
##############################################################
# File Name:01.sys_login_info.sh
# Version:V1.0
# Author:jiang
# Organization:2934xxx@qq.com
# Desc: 通过远程登录系统时,显示一些系统基本信息。
##############################################################

##########
##1.取值##
##########
sys_hostname=`hostname`
sys_ip_addr=`hostname -I`
sys_mem_total=`free -h | awk 'NR==2 {print $2}'`
sys_mem_free=`free -h | awk 'NR==2 {print $NF}'`
sys_load_average=`w | awk  -F "age: " 'NR==1 {print $2} '`


##########
##2.输出##
##########
cat <<EOF
主机名  :$sys_hostname
IP地址  :$sys_ip_addr
总内存  :$sys_mem_total
可用内存:$sys_mem_free
系统负载:$sys_load_average
EOF
  • 登录效果(bug:希望只有登录后提示,切换用户的时候不要提示。)

    在这里插入图片描述

特殊变量-位置变量

变量 描述 应用场景
$n 脚本的第 n 个参数 命令行与脚本内部桥梁
$0 脚本的名称 用于输出脚本的格式或帮助的时候
$# 脚本参数的个数 一般与判断结合,检查脚本参数个数
$@ 取出脚本所有参数 数组中或循环中
$* 取出脚本所有参数 数组中或循环中

$n 示例

避坑-$n调用

脚本使用位置参数的时候:位置参数数量 ≥10,则需要使用${10} 不能使用$10

[root@devops-shell devops-shell]# cat 03.show_args.sh
#!/bin/bash
##############################################################
# File Name:03.show_args.sh
# Version:V1.0
# Author:jiang
# Organization:2934xxx@qq.com
# Desc:
##############################################################
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
echo ${1} ${2} ${3} ${4} ${5} ${6} ${7} ${8} ${9} ${10} ${11} ${12} ${13} ${14} ${15}


[root@devops-shell devops-shell]# sh 03.show_args.sh {a..z}
a b c d e f g h i a0 a1 a2 a3 a4 a5
a b c d e f g h i j k l m n o

请添加图片描述

案例01:执行脚本的时候输入用户名,判断用户名是否存在

[root@devops-shell devops-shell]# cat 02.check_user.sh
#!/bin/bash
##############################################################
# File Name:02.check_user.sh
# Version:V1.0
# Author:jiang
# Organization:2934xxx@qq.com
# Desc:
##############################################################
id $1


[root@devops-shell devops-shell]# sh 02.check_user.sh root
uid=0(root) gid=0(root) groups=0(root)

[root@devops-shell devops-shell]# sh 02.check_user.sh jiang
id: jiang: no such user

请添加图片描述

$0 示例

如果脚本执行出错了,需要输出脚本的使用帮助脚本名 {start|stop|restart}

温馨提示:先略过如何检查是否出错

[root@devops-shell devops-shell]# cat  03.check_err.sh
#!/bin/bash
##############################################################
# File Name:03.check_err.sh
# Version:V1.0
# Author:jiang
# Organization:2934xxx@qq.com
# Desc:
##############################################################
echo "请输入正确的格式: sh $0 {start|stop|restart}"


[root@devops-shell devops-shell]# sh 03.check_err.sh
请输入正确的格式: sh 03.check_err.sh {start|stop|restart}

$# 示例

判断脚本参数的格式

[root@devops-shell devops-shell]# sh 02.check_user.sh jc
脚本参数个数是:1
uid=1000(jc) gid=1000(jc) groups=1000(jc)

[root@devops-shell devops-shell]# sh 02.check_user.sh jc root
脚本参数个数是:2
uid=1000(jc) gid=1000(jc) groups=1000(jc)

$@ $* 示例

[root@devops-shell devops-shell]# cat 02.check_user.sh
#!/bin/bash
##############################################################
# File Name:02.check_user.sh
# Version:V1.0
# Author:jiang
# Organization:2934xxx@qq.com
# Desc:
##############################################################
echo "脚本参数个数:$#"
echo "脚本所有参数:$@"
echo "脚本所有参数:$*"

[root@devops-shell devops-shell]# sh 02.check_user.sh {a..z}
脚本参数个数:26
脚本所有参数:a b c d e f g h i j k l m n o p q r s t u v w x y z
脚本所有参数:a b c d e f g h i j k l m n o p q r s t u v w x y z
  • $@$* 区别

仅仅在加上双引号后才有区别

符号 共同点 区别
$@ 取出脚本所有的参数 加上双引号 会识别 合并在一起的参数,独立参数
$* 取出脚本所有的参数 加上双引号 所有参数合并为1个参数
# 演示
set "I am oldboy" techer lidao

for  i in "$*"
do 
    echo $i
done 

for  j  in  "$@"
do 
    echo $j
done

演示结果

请添加图片描述

特殊变量-状态变量

变量 描述 应用场景
$? 上一个命令/脚本的返回值,0表示正确,非0即错误 判断/检查 命令结果
$$ 当前脚本的 pid 写在脚本中获取脚本 pid
$! 上一个脚本/命令(持续运行)的pid
$_ 上一个命令的最后一个参数,
(其实下划线是个位置变量,记录上一个命令/脚本的最后一个参数)
类似于 esc + .

$? 示例

输入任何一个命令并执行,检查这个命令的执行结果是否正确。

[root@devops-shell devops-shell]# cat 05.check_cmd.sh
#!/bin/bash
##############################################################
# File Name:05.check_cmd.sh
# Version:V1.0
# Author:jiang
# Organization:2934xxx@qq.com
# Desc:
##############################################################
echo "您输入的命令是:$1"
$1
echo "命令执行的返回值:$?"
cat <<EOF
提示:
    0 表示正常
    非0 则错误
EOF

[root@devops-shell devops-shell]# sh 05.check_cmd.sh hostname
您输入的命令是:hostname
devops-shell
命令执行的返回值:0
提示:
    0 表示正常
    非0 则错误

$$ 示例

[root@devops-shell devops-shell]# cat 04.sleep999.sh
#!/bin/bash
##############################################################
# File Name:04.sleep999.sh
# Version:V1.0
# Author:jiang
# Organization:2934xxx@qq.com
# Desc:
##############################################################
echo $$
sleep 999


[root@devops-shell devops-shell]# sh 04.sleep999.sh
6493
^C

$! 示例

[root@devops-shell devops-shell]# sleep 888 &
[1] 6595
[root@devops-shell devops-shell]# echo $!
6595
[root@devops-shell devops-shell]# echo $!
6595

$_ 示例

[root@devops-shell ~]# ls -a -l -h -d
dr-xr-x---. 4 root root 179 Aug 22 22:19 .

[root@devops-shell ~]#
[root@devops-shell ~]# echo $_
-d

特殊变量-变量子串

  • 变量子串 parameter expension 变量扩展

  • 格式:${变量}$变量 形式不识别)

  • 作用:用于对变量处理(统计变量中字符数量,对变量内容进行替换、删除…)

  • 应用:变量子串执行效率较高

格式 描述
基础
${parameter} $para 变量取值
${#parameter} 统计字符长度(变量中有多少个字符)
删除(开头,结尾) word表示要删除的内容
${parameter#word} 从变量边开始删除,按照最短匹配删除
${parameter##word} 从变量边开始删除,按照最长匹配删除
${parameter%word} 从变量边开始删除,按照最短匹配删除
${parameter%%word} 从变量边开始删除,按照最长匹配删除
截取(切片)
${var:5}
${var:5:2} 从下标5字符开始向后截取2个字符
替换(阉割版的sed)
${para/word/replace} 把word替换为replace 仅替换第一个
${para//word/replace} 把word替换为replace 替换全部

统计-示例

  • 统计字符串长度
[root@devops-shell devops-shell]# jiang="123456789"
[root@devops-shell devops-shell]# echo ${#jiang}
9
[root@devops-shell devops-shell]# jiang="12345 6789"
[root@devops-shell devops-shell]# echo ${#jiang}
10
注:空格也算
  • 案例:要求:bash for循环打印下面这句话中字母数不大于6的单词
  • I am oldboy teacher welcome to oldboy training class.
[root@devops-shell devops-shell]# cat 06.count_world.sh
#!/bin/bash
hua="I am oldboy teacher welcome to oldboy training class."

# 循环
for i in $hua
do
    # 判断
    if [ ${#i} -le 6 ]; then
        # 输出
        echo "单词字符数≤6:${i}"
    fi
done

[root@devops-shell devops-shell]# sh 06.count_world.sh
单词字符数≤6:I
单词字符数≤6:am
单词字符数≤6:oldboy
单词字符数≤6:to
单词字符数≤6:oldboy
单词字符数≤6:class.
awk书写:
[root@devops-shell devops-shell]# echo "I am oldboy teacher welcome to oldboy training class." | xargs -n1 | awk 'length($1)<=6'
I
am
oldboy
to
oldboy
class.

删除-示例

  • 删除变量中的内容(仅影响输出)
[root@devops-shell devops-shell]# var=oldboylidao996
[root@devops-shell devops-shell]# echo ${var#oldboy}
lidao996
[root@devops-shell devops-shell]# echo ${var#o}
ldboylidao996
[root@devops-shell devops-shell]# echo ${var#l}
oldboylidao996
[root@devops-shell devops-shell]# echo ${var#*l}
dboylidao996
[root@devops-shell devops-shell]# echo ${var#*o}
ldboylidao996
[root@devops-shell devops-shell]# echo ${var##*o}
996
  • 取出文件名 或 目录

温馨提示:取出文件名和目录 变量子串的方法可以,也可用 dirname , basename 更方便

dir=/etc/sysconfig/network-scripts/ifcfg-eth0

取出文件名
echo ${dir##*/}
ifcfg-eth0

取出路径名
echo ${dir%/*}
/etc/sysconfig/network-scripts

截取-示例

var=oldboy拆分
切片的时候,每个字符都有个位置从 0 开始 o l d b o y
位置0 位置1 位置2 位置3 位置4 位置5

请添加图片描述

替换-示例

[root@devops-shell ~]# name=oldboylidao996
[root@devops-shell ~]# echo ${name/o/-}
-ldboylidao996
[root@devops-shell ~]# echo ${name//o/-}
-ldb-ylida-996

特殊变量-变量扩展

给变量设置默认值.

格式 描述
${parameter:-word} 变量parameter没定义或为空,把word作为默认值,不修改变量内容(输出)
${parameter:=word} 变量parameter没定义或为空,把word作为默认值,修改变量内容
${parameter:?word} 变量parameter没定义或为空,显示word,错误输出
${parameter:+word} 变量parameter没定义或为空,则啥也不做,否则把word替换变量内容

:-

变量没有值或没创建,则显示指定字符
[root@devops-shell devops-shell]# echo $name

[root@devops-shell devops-shell]# echo ${name:-root}
root

变量有值,则显示变量原本的值
[root@devops-shell devops-shell]# name=jiang
[root@devops-shell devops-shell]# echo ${name:-root}
jiang

:=

[root@devops-shell devops-shell]# echo $lidao

[root@devops-shell devops-shell]# echo ${lidao:=996}
996
[root@devops-shell devops-shell]# echo $lidao
996

:?

[root@devops-shell devops-shell]# echo $name

[root@devops-shell devops-shell]# echo ${name:?Undefined}
-bash: name: Undefined
[root@devops-shell devops-shell]# name=lidao996
[root@devops-shell devops-shell]# echo ${name:?Undefined}
lidao996

:+

[root@devops-shell devops-shell]# echo $name

[root@devops-shell devops-shell]# echo ${name:+root}

[root@devops-shell devops-shell]# name=jiang
[root@devops-shell devops-shell]# echo ${name:+root}
root

相关文章

学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习...
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面...
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生...
Can’t connect to local MySQL server through socket \'/v...
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 ...
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服...