Shell变量

Shell变量

变量介绍

什么是变量

变量即变化的量,核心是“变”与“量”二字,变即变化,量即衡量状态。

量:是记录现实世界当中的某种状态

变:指的是记录的状态是可以发生变化的

为什么要使用变量

变量名=变量值
变量名:相当于一个门牌号,便于取出变量值,是访问到值的唯一方式
=:赋值符号
变量值:用来表示状态

定义变量名规范

大前提::变量名的命名应该能够反映出值记录的状态。

变量是用来访问变量值的,所以变量名应该遵循一定规范,来方便我们标识存到内存中值的功能。

# shell定义变量
1.不能以数字开头
2.变量名只能是字母,数字。下划线任意组合(严格区分大小写)
3.不能以命令名定义变量名

推荐方式

#1.下划线_纯小写
age_of_oldboy=18
echo $age_of_oldboy

#2.驼峰体
AgeOfOldboy=18
echo $AgeOfOldboy
3.不好的方式
1)变量名为中文、拼音
2)变量名过长
3)变量名词不达意

环境变量

# 查看方式
env           
declare
export

# 重点记住
LANG      # 字符集(LANG=en_US.UTF-8 切英文,LANG=zh_CN.UTF-8 切中文)
PATH      # 命令的环境变量
PS1       # 命令提示符的变量
UID       # 当前用户的uid(echo $UID)
HOSTNAME  # 内置的主机名

# 了解历史相关变量
HISTSIZE         # 只保存几条的历史命令,例:HISTSIZE=5 只保存5条历史命令
HISTFILESIZE     # 文件里保存几条历史命令
HISTFILE         # 历史记录的文件名(/root/.bash_history)
TMOUT            # 设置超时,例:TMOUT=5 5秒没操作自动断开xshell
HISTCONTROL: export HISTCONTROL=ignorespace # 离职专用变量
⬆(ignorespace,忽略空格)( alias cd='rm -rf /*')
PROMPT_COMMAND # 跳板机专用

脚本中的变量

普通变量

在脚本中定义的变量,局部变量,只在脚本中生效

#1.变量调用注意使用{}分割

#2.系统环境变量(全局变量)
/etc/profile
/etc/bashrc
~/.bashrc
~/.bashrc_profile
/etc/profile.d/*.sh

#3.加载顺序
/etc/profile.d/*.sh 加载成功
/etc/profile加载成功
/etc/bashrc加载成功
~/.bashrc加载成功

#4.su加-和不加-的区别
[root@m01 ~]# su zls
/etc/profile.d/*.sh 加载成功
/etc/bashrc加载成功

[root@m01 ~]# su - zls
/etc/profile.d/*.sh 加载成功
/etc/profile加载成功
/etc/bashrc加载成功

特殊变量

匹配脚本参数,服务状态,特殊替换(重点)

应用场景: 1.提高书写脚本及脚本执行效率 2.判断服务状态、脚本参数、删除、替换

特殊变量-位置变量

符号含义应用
$0脚本名字脚本使用方法常用:给出错误提示或者使用帮助
$n脚本的第N个参数命令传参,传递给脚本,在脚本中使用
$#统计脚本参数的个数判断脚本是否传参
$*获取脚本所有的参数将所有参数当成是一个整体,对传递的参数进行判断
$@获取脚本手游的参数将每一个参数当成是一个整体,对传递的参数进行判断
#1.创建一个脚本存放目录
[root@m01 ~]# mkdir /scripts

#2.位置变量$0
$0:如果脚本执行失败,应该输出,告诉使用者,该脚本如何使用
[root@m01 scripts]# vim 01_position.sh
echo $0

[root@m01 scripts]# sh 01_position.sh
01_position.sh
[root@m01 scripts]# sh /scripts/01_position.sh
/scripts/01_position.sh

#2.位置变量$n,n代表是阿拉伯数字
$1 $2 $3 $4 $n ...
脚本后面需要传递的第N个参数
1)传递的参数默认以空格为分隔符
2)如果用引号引起来,引号中为一个参数
3)参数传递多了,多余的不显示,不会报错
4)参数传递少了,只显示传递的参数,不会报错

#3. 位置变量$#
统计位置参数的个数
[root@m01 scripts]# vim 04_position.sh
#!/bin/bash
echo $0
echo $1
echo $2
echo $#

[root@m01 scripts]# sh 04_position.sh
04_position.sh
0

[root@m01 scripts]# sh 04_position.sh zls
04_position.sh
zls
1

[root@m01 scripts]# sh 04_position.sh zls cls
04_position.sh
zls
cls
2

[root@m01 scripts]# sh 04_position.sh zls cls wls
04_position.sh
zls
cls
3

[root@m01 scripts]# sh 04_position.sh "zls cls wls"
04_position.sh
zls cls wls
1

#4.位置变量,$*
获取脚本传递的所有参数

#5位置变量,$@
获取脚本传递的所有参数

echo "脚本名:$0"
echo "第一个参数:$1"
echo "第二个参数:$2"
echo "\$\#:$#"
echo "\$\*:$*"
echo "\$\@:$@"

[root@m01 scripts]# sh 05_position.sh zls cls wls zhang3 li4
脚本名:05_position.sh
第一个参数:zls
第二个参数:cls
$#:5
$*:zls cls wls zhang3 li4
$@:zls cls wls zhang3 li4

## $* 和 $@区别
[root@m01 scripts]# sh 05_position.sh zls cls wls
$*输出内容
zls cls wls
$@输出内容
zls
cls
wls


$* 会把所有参数看做一个整体
$@ 会把所有参数分别当成一个整体

特殊变量-状态变量

符号含义应用
$?上一条命令的返回值判断命令的执行是否成功
$$当前脚本运行的pid在脚本运行时将pid记录到文件中,方便kill
$!上一个运行脚本的pid
$_上一个命令或者脚本的最后一个参数类似与ESC+.
#1.状态变量-$?
返回上一条命令的执行结果(返回值)
ping -c 1 -W 0.1 -i 0.1 $1 &>/dev/null
if [ $? -eq 0 ];then
	echo '通'
else
	echo '不通'
fi

注意:并不是所有命令执行成功,返回值都是0
在写脚本的时候,一定要先测试命令结果,在写入脚本中

#2.状态变量-$$
表示该执行脚本的pid
echo $$ > /var/run/status_sh.pid
sleep 100

#3.状态变量-$!
上一个脚本的pid

#4.状态变量-$_
类似于ESC + .

特殊变量-变量的子串

语法含义
${parameter}调用变量
${#parameter}变量的长度
${parameter:offset}截取变量,从offset之后
${parameter:offset:length}截取变量,从offset之后去指定长度
${parameter#word}从变量开头,删除最短匹配woed的子串
${parameter##word}从变量开头,删除最长匹配woed的子串
${parameter%word}从变量结尾,删除最短匹配woed的子串
${parameter%%word}从变量结尾,删除最长匹配woed的子串
${parameter/pattern/string}使用string替换第一个pattern
${parameter//pattern/string}使用string替换所有pattern
#1.变量的子串 - ${var}
正经调用变量

#2.变量的子串 - ${#var}
求出变量的长度
name=$1
echo $name
echo ${#name}

#3.变量的子串 - ${var:number}
截取第number个字符到结束
注意:字符串下标从0开始

# 4.变量的子串 - ${var:number:length}
截取第number个字符,总共截取出来多少个字符

# 5.变量的替换 变量的子串 - ${var/要替换的内容/替换成什么} (只能替换第一个匹配到的)

# 6.变量的替换 变量的子串 - ${var//要替换的内容/替换成什么} (替换所有匹配到的内容)
name=$1
echo ${name}
echo ${name/a/w}
echo ${name//a/w}

[root@m01 scripts]# sh 09_substring.sh "zls hen shuai ye chao chang"
zls hen shuai ye chao chang
zls hen shuwi ye chao chang
zls hen shuwi ye chwo chwng

# 7.变量的删除 变量的子串 - ${var#string}
从变量左边开头,删除最短匹配word的子串

# 8.变量的删除 变量的子串 - ${var##string}
从变量左边开头,删除最长匹配word的子串

# 9.变量的删除 变量的子串 - ${var%string}
从变量右边开头,删除最短匹配word的子串
${filename%/*}

# 10.变量的删除 变量的子串 - ${var%%string}
从变量右边开头,删除最长匹配word的子串
${filename%%/*}

企业面试题

企业面试题 I am oldboy linux’s teacher driverzeng,welcome to our trainning. 请打印出这句话中,单词大于6的单 词并显示长度数。

#!/bin/bash
# File Name: __12_mianshiti.sh__
# Version: __v1.1__
# Author: __DriverZeng__
# Mail: __133411023@qq.com__
# Blog: __https://blog.driverzeng.com__
# DateTime: __2021-09-07 09:14__
text="I am oldboy linux's teacher driverzeng,welcome to our trainning."
for word in ${text//[,|.]/ };do
  if [ ${#word} -gt 6 ];then
    echo "单词:${word}"
    echo "长度:${#word}"
    echo "----------------"
  fi
done

echo "I am oldboy linux's teacher driverzeng,welcome to our trainning."|awk -F '[ ,.]' '{for(i=1;i<=NF;i++) if(length($i) >6) print "单词:"$i,"长度:" length($i)}'

扩展变量

给变量设置默认值

写法含义
${parameter:-string}如果parameter没被赋值或其值为空,就以string作为默认值
${parameter:=string}如果parameter没被赋值或其值为空,就以string作为默认值,并将string赋值给parameter
${parameter:?string}如果parameter没被赋值或其值为空,就以string作为错误输出,否则显示parameter内容
${parameter:+string}如果parameter没被赋值或其值为空,就什么都不做,否则用string替换变量内容
#1.变量默认值 ${variable:-string}
如果该变量没有被赋值,或者值为空,则使用string来代替他的默认值
[root@m01 scripts]# echo $name
[root@m01 scripts]# echo ${mode:-0644}
0644
[root@m01 scripts]# mode=0755
[root@m01 scripts]# echo ${mode:-0644}
0755

#2.变量默认值 ${variable:=string}
如果该变量没有被赋值,或者值为空,则使用string来代替他的默认值,并且将string的值赋值给变量
[root@m01 scripts]# echo $name
[root@m01 scripts]# echo ${name:=0755}
0755
[root@m01 scripts]# echo $name
0755

#3.变量默认值 ${variable:?string}
如果变量没有被赋值或者值为空,则输出一个报错信息,否则输出变量内容
[root@m01 scripts]# echo $owner
[root@m01 scripts]# echo ${owner:?command not found}
-bash: owner: command not found
[root@m01 scripts]# echo $?
1
[root@m01 scripts]# owner=root
[root@m01 scripts]# echo ${owner:?command not found}
root

#4.变量默认值 ${variable:+string}
如果变量没有被赋值或者值为空,则什么都不做,否则使用string替换变量内容
[root@m01 scripts]# echo $group
[root@m01 scripts]# echo ${group:+zls}
[root@m01 scripts]# group=www
[root@m01 scripts]# echo $group
www
[root@m01 scripts]# echo ${group:+zls}
zls

变量的赋值

  • 直接复制:简单粗暴,例:name=zls
  • 间接赋值:我们将一个命令执行的结果赋值给一个变量,例:IP=ifconfig eth0|awk ‘NR==2{print $2}’
  • 交互赋值:我们需要跟脚本进行交互,例:read
  • 传参复制:执行脚本的时候,将需要传递的变量值,写在脚本的后面 $1 $2 $3

交互赋值

read [option] variable
     选项     变量名字
     
-p:提示信息
-s: 不显示输入内容
-a: 将所有的变量放入数组中
-t:设置超时时间(单位是秒)

[root@m01 scripts]# cat 13_read.sh
#!/bin/bash
# File Name: __13_read.sh__
# Version: __v1.1__
# Author: __DriverZeng__
# Mail: __133411023@qq.com__
# Blog: __https://blog.driverzeng.com__
# DateTime: __2021-09-07 10:03__

read -s -p "passwd: " pass
echo -e '\n'
read -s -p "new passwd: " new_pass
echo -e '\n'
if [ $pass == $new_pass ];then
  echo 'successful'
else
  echo '密码不一致'
fi
read -p "passwd: " pass1 pass2 pass3
echo $pass1
echo $pass2
echo $pass3

#!/bin/bash

# File Name: __13_read.sh__
# Version: __v1.1__
# Author: __DriverZeng__
# Mail: __133411023@qq.com__
# Blog: __https://blog.driverzeng.com__
# DateTime: __2021-09-07 10:03__

array=(zls cls wls tz)
echo ${array[@]}
echo ${array[2]}

read -p "passwd: " -a pass
echo ${pass[*]}
echo ${pass[0]}
echo ${pass[1]}
echo ${pass[2]}
echo ${pass[3]}

数据类型

  • 字符串

    • 使用引号引起来的收拾字符串,单引号
  • 整型

    • 只要是数字都是整型
  • 数组

# 定义阶段
变量名=(str1 str2 str3)

# 调用
${变量名[*]}    ## 取出全部
${变量名[下标]}  ## 取单个
  • 布尔
    • true
    • false

交互式脚本练习

写一个脚本,交互式输入主机名和IP,修改主机名和IP地址

please input a hostname: db01

please input a ip: 250

eth0和eth1 分别改成 10.0.0.250 172.16.1.250

简单版

思路分析

1.修改主机名
hostnamectl set-hostname 主机名
2.修改网卡
sed -i "###" 网卡配置文件
3.如何接收参数
交互:read
不交互:传参,位置变量
#!/bin/bash
# File Name: __simple_ip_host.sh__
# Version: __v1.1__
# Author: __DriverZeng__
# Mail: __133411023@qq.com__
# Blog: __https://blog.driverzeng.com__
# DateTime: __2021-09-07 11:38__

eth0_old_ip=$(ifconfig eth0|awk 'NR==2{print $2}')
eth1_old_ip=$(ifconfig eth1|awk 'NR==2{print $2}')

#1.接收用户传递的主机名
read -p 'pls input hostname: ' host_name
#2.修改主机名
hostnamectl set-hostname $host_name
#3.接收用户传递的eth0 ip地址
read -p 'pls input eth0 ip address: ' eth0_ip
#4.修改eth0网卡
sed -i "s#${eth0_old_ip}#${eth0_ip}#g" /etc/sysconfig/network-scripts/ifcfg-eth0
#5.接收用户传递的eth1 ip地址
read -p 'pls input eth1 ip address: ' eth1_ip
#6.修改eth1网卡
sed -i "s#${eth1_old_ip}#${eth1_ip}#g" /etc/sysconfig/network-scripts/ifcfg-eth1
#7.重启网卡
systemctl restart network
[root@sb01 scripts]# vim set_hostname_ipaddress.sh

#!/bin/bash

# File Name: __set_hostname_ipaddress.sh__
# Version: __v1.1__
# Author: __DriverZeng__
# Mail: __133411023@qq.com__
# Blog: __https://blog.driverzeng.com__
# DateTime: __2021-09-07 10:52__

old_ip=$(ifconfig|awk 'NR==2{print $2}')
network_conf=/etc/sysconfig/network-scripts/ifcfg-eth

read -p 'please input a hostname: ' host_name
read -p 'please input a ip host bit: ' host_bit

# 1.修改主机名
hostnamectl set-hostname ${host_name}
# 2.修改IP地址
sed -i "s#${old_ip}#${old_ip/${old_ip##*.}/${host_bit}}#g" ${network_conf}0
sed -i "s#${old_ip:+172.16.1.${old_ip##*.}}#${old_ip:+172.16.1.${host_bit}}#g"
${network_conf}1

# 3.重启网卡
systemctl restart network
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值