变:指的是事物的状态是可以发生变化的
量:指的是记录事物的状态
变量:本质就是一种数据存取的机制,变量的数据都是存放于内存中的
程序运行的本质就是一系列状态的变化
程序=数据+功能,
程序执行的本质就是一系列状态的变化,变是程序执行的直接体现,所以我们需要有一种机制能够反映或者说是保存下来程序执行时状态以及状态的变化。
# 比如:
英雄的等级为1,打怪升级(变)为10
僵尸的存活状态True,被植物打死了,于是变为False
人的名字tom,也可以修改为tom
# 1、语法:变量名=值
# 2、注意:等号左右两边不能有空格!!!
# 3、例如:
[root@web ~]# name="mmmm"
[root@web ~]# echo $name
mmmm
[root@web ~]# linu12=2000
[root@web ~]# echo $linu12
2000
注意:如果是打印百分比,建议使用${变量名}%
[root@web shell]# percent=33
[root@web shell]# echo ${percent}%
33%
[root@web shell]# x=125
[root@web shell]# unset x
[root@web shell]# echo $x
1、变量名:用来访问到变量值的
2、赋值符号:将变量值的内存地址绑定给变量名
3、变量值: 记录事物的状态,即数据
定义变量把数据存到内存中不是目的,目的是以后要取出来用;
而变量名就是用来取变量值的,而变量的名字直接表明了所存值的意义,可见变量名的命名非常重要的
# 变量名的命令应该见名知意,同时遵循如下规则
以字母或下划线开头,剩下的部分可以是:字母、数字、下划线,最好遵循下述规范:
1.以字母开头
2.使用中划线或者下划线做单词的连接
3.同类型的用数字区分
4.对于文件名的命名最好在末尾加上拓展名
例如: sql_bak.tar.gz,log_bak.tar.bz2
5、不要带有空格、?、*等特殊字符
6、不能使用中的关键字,例如if,for,while,do等
7、不要和系统环境变量冲突
8、 不要使用中文和拼音
# 变量名的命名风格
1、纯小写字母加下划线
age_oldboay=18
2、驼峰体
Ageoldboay=18
(1)直接赋值
# 1. 显式赋值:变量名=变量值
示例:
ip1="10.0.4.10"
school=" oldboy "
day1=`date +%F`
day2=$(date +%F)
# 2、应用示例
[root@web ~]# url="www.baidu.com"
[root@web ~]# echo $url
www.baidu.com
[root@web ~]# url="www.sina.com.cn"
[root@web ~]# echo $url
www.sina.com.cn
(2)从位置参数获取变量值
从调用脚本时传入的位置参数获取变量值:./b.sh 11 22 33
需要用到$n获取第n个位置参数值,超过10需要用${n},如下
$0 $1 $2 $3
# 示例1
[root@web ~]# cat a.sh
#!/usr/bin/env
echo $1
echo $2
echo $3
-rw-r--r-- 1 root root 44 May 31 17:54 a.sh
# 运行1
[root@web ~]# chmod +x a.sh
[root@web ~]# ./a.sh 11 22 44
11
22
44
# 示例2
[root@web ~]# cat a.sh
#!/usr/bin/env
if [ $1 = "start" ];then
echo "start"
elif [ $1 = "stop" ];then
echo "stop"
elif [ $1 = "restart" ];then
echo "restart"
else
echo "usage: sh a.sh"
fi
# 运行2
[root@web ~]# ./a.sh stopd
usage: sh a.sh
# 企业使用:可以实现脚本的不同功能(服务程序管理脚本-启动功能 关闭功能 重启功能)
server.sh start|stop|restart
(3)与用户交互获取值
何为交互,即输入、输出
[root@web ~]# cat a.sh
#!/usr/bin/env
user=mm
pwd=123
read -p "请输入正确的用户名" name
read -p "请输入正确的密码" passwd
if [ $name = $user ] && [ $passwd = $pwd ];then
echo "登录成功"
else
echo "登录失败"
fi
[root@web ~]# ll
total 8
-rwxr-xr-x 1 root root 228 May 31 18:58 a.sh
[root@web ~]# ./a.sh
请输入正确的用户名mm
请输入正确的密码123
登录成功
[root@web ~]# ./a.sh
请输入正确的用户名12
请输入正确的密码12
登录失败
企业使用:可以根据需求调整变量值,可以便于新员工快速掌握企业脚本使用
# 二:输出
# 2.1 echo命令,详解情况:https://www.cnblogs.com/linhaifeng/articles/13976349.html
[root@mm ~~]# name="mm"
[root@mm ~~]# age=18
[root@mm ~~]# echo -e "my name is $name my age is $age"
my name is mm my age is 18
还可以输出带颜色(了解即可)
echo -e "\033[31m 红色字 \033[0m"
echo -e "\033[34m 黄色字 \033[0m"
echo -e "\033[41;33m 红底黄字 \033[0m"
echo -e "\033[41;37m 红底白字 \033[0m"
# 2.2 prinf命令(C语言风格)
%s
%d
%7.3f 打印浮点数,总宽度为7,小数位保留3位,并且四舍五入
[root@mm ~~]# name="mm"
[root@mm ~~]# age=18
[root@mm ~~]# printf "my name is %s my age is %s\n" $name $age
my name is mm my age is 18
[root@mm ~]# salary=3.3339
[root@mm ~]# printf "my name is %s my age is %7.3f\n" $name $salary
my name is mm my age is 3.334
aa=123
# 双引号 # 软应用,可以显示$aa里面的内容
# 单引号 # 硬应用, 只会显示$aa
[root@web ~]# aa=111
[root@web ~]# echo "name is $aa"
name is 111
[root@web ~]# echo 'name is $aa'
name is $aa
echo 和printf 一样
[root@web ~]# printf 'name is $aa'
name is $aa
[root@web ~]# printf "name is $aa"
name is 111
$# 参数的个数
$$ 当前进程的PID # 此外,可以使用只读变量来获取父进程的PID:$PPID、获取执行脚本的用户ID:$UID
$? 上一个命令的返回值 0表示成功 非0表示失败
$* 所有的参数,不加双引号与$@完全一致,都会把位置参数当成一个“个体”
"$*" # 此时把所有位置参数当成一个整体(以行的方式打印)
$@ 所有的参数,不加双引号与$*完全一致,都会把位置参数当成一个“个体”
"$#" # 此时会把所有位置参数当成一个单独的字段(以列的方式打印)
示例1:
[root@mm ~]# cat b.sh
#!/usr/bin/env
echo $*
echo $@
echo $#
echo $$
ping -c1 192.168.15.10 &>/dev/null
echo $?
[root@mm ~]# chmod +x b.sh
[root@mm ~]# ./b.sh 11 22 344 566
11 22 344 566
11 22 344 566
4
13239
1
示例2:
[root@mm ~]# vim ping.sh
#!/bin/
ping -c2 $1 &>/dev/null
if [ $? = 0 ];then
echo "host $1 is ok"
else
echo "host $1 is fail"
fi
[root@mm ~]# chmod +x ping.sh
[root@mm ~]# ./ping.sh 192.168.11.10
了解:
如果我们想从命令行中获取脚本调用者传入的参数值,用$n可以取到,但如果脚本调用者在命令行传入的参数个数不固定,那么此时就需要用$*或$@来获取了
$*与$@获取的是所有位置参数,$0除外
$* 与 $@ 不加引号情况下
针对for循环语句:for i in 元素,for循环会按照空格作为分隔符来一个个取元素,所以此时 $* 与 $@ 并无区别
[root@web ~]# cat script.sh
#!/bin/
for i in $*
do
echo $i
done
echo "=================="
for i in $@
do
echo $i
done
当脚本调用者的传参形式如下时,打印效果如下(无区别)
[root@web ~]# ./script.sh 命令1 命令2 命令3
命令1
命令2
命令3
==================
命令1
命令2
命令3
$* 与 $@ 不加引号情况下
针对for循环语句:for i in 元素,for循环会按照空格作为分隔符来一个个取元素,所以此时 $* 与 $@ 如果不加引号,第三个命令:"命令3 参数",会被以空格为分隔符识别成两部分
[root@web ~]# cat script.sh
#!/bin/
for i in $*
do
echo $i
done
echo "=================="
for i in $@
do
echo $i
done
当脚本调用者的传参形式如下时,打印效果为下
[root@web ~]# ./script.sh 命令1 命令2 "命令3 参数"
命令1
命令2
命令3
参数
==================
命令1
命令2
命令3
参数
所以需要为`$*`与`$@`加上引号
[root@web ~]# cat script.sh
#!/bin/
for i in "$*"
do
echo $i
done
echo "=================="
for i in "$@"
do
echo $i
done
当脚本调用者的传参形式如下时,打印效果为下
"$*"以行显示,且会被空格分隔符分开,将"命令3 参数"给识别为两个个体
"$@"以列显示,"命令3 参数"还是为一个整体
[root@web ~]# ./script.sh 命令1 命令2 "命令3 参数"
命令1 命令2 命令3 参数
==================
命令1
命令2
命令3 参数
当脚本调用者的传参形式如下时,脚本内容需要使用"$@"来分别获取一个个“完整”的命令,其余情况$*与$@完全一致!
[root@web ~]# ./script.sh 命令1 命令2 "命令3 参数"
命令1 命令2 命令3 参数
==================
命令1
命令2
命令3 参数
[root@web ~]# cat script.sh
for i in "$@"
do
echo $i
done
相对于变量,常量就是不可以被改变的量,即只能读不能改,所以又称之为只读变量
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
[root@mm ~]# x=111
[root@mm ~]# readonly x
[root@web ~]# echo $x
111
[root@mm ~]# x=666
-: x: 只读变量
[root@web ~]# readonly x=111
[root@web ~]# echo $x
111
[root@web ~]# x=222
-: x: readonly variable
-: x: 只读变量