Shell变量

Shell 变量

环境变量

什么是环境变量?

右边一堆内容,用一个名字来代替称为环境变量
name="I am mengshiyu"

如何查看环境变量? 名称的前面加上$

echo $name

如何查看系统定义好的环境变量

env set

如何取消环境变量?

unset name

按照生存周期划分

永久性 修改配置文件 /etc/profile
临时性 使用export 变量名称 声明即可
不加export 只对当前的shell生效
加export 对当前登录窗口所有的shell生效

1. 定义变量

定义变量时,变量名不加美元符号($,PHP语言中变量需要),如:

your_name="runoob.com"

注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:和其他语言一样,比如java

字符 下划线 数字的组合 尽量以字母开头(禁止使用数字开头) 等号两端不允许有空格 见名知其意

书写方式:

  1. OLDBOY_AGE=18 系统中变量的定义格式
  2. oldboy_age=18
  3. oldboy_Age=18 小驼峰语法
  4. Oldboy_Age=18 大驼峰语法

有效的 Shell 变量名示例如下:

RUNOOB
LD_LIBRARY_PATH
_var
var2

无效的变量命名:

?var=123
user*name=runoob

2. 使用变量

使用一个定义过的变量,只要在变量名前面加美元符号即可,如:

your_name="qinjx"
echo $your_name
echo ${your_name}

变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:

for skill in Ada Coffe Action Java; do
    echo "I am good at ${skill}Script"
done

如果不给skill变量加花括号,写成echo "I am good at $skillScript",解释器就会把$skillScript当成一个变量(其值为空),代码执行结果就不是我们期望的样子了。
推荐给所有变量加上花括号,这是个好的编程习惯

3.shell变量和环境变量

shell有shell变量,环境变量两种。
shell变量只在正在执行的shell内部有效。环境变量对执行过的shell也是有效的。
从shell变量可以变成环境变量。

练习:环境变量做成

使用export命令,做成环境变量
    $ export abc
shell变量abc变成环境变量
    $ export xyz=234
        声明环境变量

第一行的命令是做成abc环境变量,abc中没有赋值。
第二行的命令是做成xyz环境变量,xyz被赋值234。
我们用下面的两个脚本 BBB.sh 和 CCC.sh来了解一下shell变量和环境变量的区别。

例子:

$ cat BBB.sh
#!/bin/bash
xxx=123
export yyy=234
./CCC.sh
$ cat CCC.sh
#!/bin/bash
echo xxx=$xxx
echo yyy=$yyy
(值表示)
$ ./BBB.sh
xxx=
yyy=234
(BBB.sh中执行CCC.sh,xxx没有被继承了, yyy被继承了)

这个shell脚本执行时,CCC.sh中的xxx值没有表示。是因为shell变量没有被继承。
另外,因为yyy是环境变量,所以在CCC.sh中被继承了,值也就被表示了。

重要的特殊位置变量

$0	脚本的名称,如果全路径执行脚本,则脚本名称也带全路径 basename 获取脚本的名称 重要
	    案例: 给用户提示如何使用此脚本
		echo $"Usage: $0 {start|stop|status|restart|force-reload}"
$n  脚本的第n个参数 $0被脚本名称占用 从$1开始 $9以后 需要加{}
$#  代表了脚本的传参的总个数  重要
		案例:
		[ $# -ne 2 ] && echo "你请输入两个参数" && exit
$*  脚本的所有的传参的参数 如果不加双引号则和$@相同 加上双引号则把所有参数视为一个整体
$@  脚本的所有的传参的参数 如果不加双引号则和$*相同加上双引号则把所有参数视为独立的参数
$*  和$@ 正常情况下一样  循环体内不同
$?  获取上一条命令的结果 0为成功 非0 失败  重要   
$$  获取脚本的PID
		案例
		服务器运行大量的名称相同的脚本
		echo $$ > /tmp/count.pid
$!  上一个在后台运行脚本的PID 调试使用
$_   获取脚本的最后一个参数 相当于ESC .


$$  shell本身的PID(process ID) 几脚本运行当前进程ID号
$!  shell最后运行的后台Process的PID (后台运行的最后一个进程的ID号)
$?  最后运行的命令的结束码(返回值),即上一个指令的返回值
$-  显示shell 使用的当前选项,与set 命令功能相同
$*  所有的参数列表,如$*用 "括起来的情况,以 $1 $2形式输出的所有参数,此选项可以超过9个
$@  所有的参数列表,和 $* 一样,但是可以当做 数组 使用
$#  添加到shell的参数个数
`$0 | shell本身的文件名
$1 -$n  shell的参数值 $1 是第一个参数 $2 是第二个
[root@web01 scripts]# set -- "I am" lizhenya teacher
[root@web01 scripts]# echo $*
I am lizhenya teacher
[root@web01 scripts]# echo $@
I am lizhenya teacher
[root@web01 scripts]# for i in $*;do echo $i;done
I
am
lizhenya
teacher
[root@web01 scripts]# for i in $@;do echo $i;done
I
am
lizhenya
teacher
[root@web01 scripts]# for i in "$*";do echo $i;done
I am lizhenya teacher
[root@web01 scripts]# for i in "$@";do echo $i;done
I am
lizhenya
teacher

4.传参的三种方式

1)直接传参
2)赋值传参
3)read传参

第一种传参方式

echo $1 $2

第二种传参方式

name=$1

age=$2

echo $ name $age

read -p "请输入名字和年龄" name1 age1
echo $name1 $age1

案例:
	使用read 传参的方式 更改系统的主机名称和IP地址的最后一位 192.168.12.X
	#!/bin/sh
	sdir="/etc/sysconfig/network-scripts/ifcfg-eth0"
	sip=`cat /etc/sysconfig/network-scripts/ifcfg-eth0|awk -F. '/IPADDR/{print $NF}'|cut -c1`
	read -p "请输入主机名称: " name
	hostnamectl set-hostname $name
	read -p "请输入IP地址的最后一位: " ip
	sed -i "s#$sip#$ip#g"  $sdir
	案例:
	sh ping.sh www.baidu.com
	ping www.baidu.com is ok
	sh ping.sh www.xxxxx.com is error
	[root@web01 scripts]# cat ping.sh 
	#!/bin/sh
	read -p "请输入一个网址: " url
	ping -c 1 -W 1 $url >/dev/null 2>&1
	[ $? -eq 0 ] && echo "ping $url is ok" || echo "ping $url is error"

5.变量字串知识

#统计变量的长度
[root@web01 scripts]# name="I am lizhenya"
[root@web01 scripts]# echo $name
	I am lizhenya
[root@web01 scripts]# echo "I am lizhenya"
	I am lizhenya
[root@web01 scripts]# echo "I am lizhenya"|wc -L
	13
[root@web01 scripts]# echo $name|wc -L
	13
[root@web01 scripts]# echo ${#name}
	13
	
#变量的切片
[root@web01 scripts]# echo ${name:0:1}
	I
[root@web01 scripts]# echo ${name:2:2}
	am
[root@web01 scripts]# echo ${name:0:1}
	I
[root@web01 scripts]# echo ${name:1}
	am lizhenya
[root@web01 scripts]# echo ${name:2:5}
	am li
	
	
	I am lizhenya teacher I am 18
#取字符串长度
	方法1
	echo I am lizhenya teacher I am 18|wc -L
	方法2
	name="I am lizhenya teacher I am 18"
	echo ${#name}
	方法3
	[root@web01 scripts]# expr length "$name"
	29
	方法4
	[root@web01 scripts]# echo $name|awk '{print length}'
	29	

面试题:取字符串长度小于3的

方法1 
	for循环方式
		[root@web01 scripts]# cat for.sh 
		#!/bin/sh
		for i in I am lizhenya teacher I am 18
		do
			[ ${#i} -lt 3 ] && echo $i
		done
	方法2
	[root@web01 scripts]# echo I am lizhenya teacher I am 18|xargs -n1|awk '{if(length<3)print}'
	I
	am
	I
	am
	18
	方法3
	[root@web01 scripts]# echo I am lizhenya teacher I am 18|awk '{for(i=1;i<=NF;i++)if(length($i)<3)print $i}'

6.变量的删除和替换

#从前往后删除变量内容
		[root@web01 scripts]# echo $url
		www.sina.com.cn
		[root@web01 scripts]# echo ${url#*.}
		sina.com.cn
		[root@web01 scripts]# echo ${url#*.*.}
		com.cn
		[root@web01 scripts]# echo ${url##*.}
		cn

#从后往前删除变量内容
		[root@web01 scripts]# echo $url
		www.sina.com.cn
		[root@web01 scripts]# echo ${url%.*}
		www.sina.com
		[root@web01 scripts]# echo ${url%%.*}
		www

#变量的替换
		[root@web01 scripts]# echo $url
		www.sina.com.cn
		[root@web01 scripts]# echo ${url/w/a}
		aww.sina.com.cn
		[root@web01 scripts]# echo ${url/w/aa}
		aaww.sina.com.cn
		[root@web01 scripts]# echo ${url//w/a}
		aaa.sina.com.cn
		[root@web01 scripts]# echo ${url/sina/baidu}
		www.baidu.com.cn

面试题:显示出whoami?

[root@shell /server/scripts]# cat oldboy.sh
#!/bin/bash
name=`whoami`
[root@shell /server/scripts]# echo $name

[root@shell /server/scripts]# . oldboy.sh     让他在父进程中出来
[root@shell /server/scripts]# echo $name
root

面试题:已知如下命令返回结果,请问echo $used的返回结果为()?

[root@web01 /server/scripts]# cat test.sh
#!/bin/bash
##############################################################
# File Name: test.sh
# Version: V1.0
# Author: oldboy
# Organization: www.oldboyedu.com
##############################################################
user=`whoami`
[root@web01 /server/scripts]# sh test.sh
[root@web01 /server/scripts]# echo $user

参考答案如下:
a)当前用户
b)root
c)没有内容输出

选c,因为使用sh执行脚本会导致当前shell无法获得变量。

表.7

变量语法 解释
$ 获取变量值的长度
$ 从头开始匹配,最短删除(非贪婪)
$ 从头开始匹配,最长删除(贪婪)
$ 从尾开始匹配,最短删除(非贪婪)
$ 从尾开始匹配,最长删除(贪婪)
$ 替换变量内的旧字符串为新字符串,只替换第一个
$ 替换变量内的旧字符串为新字符串,全部替换
$ 以STR开头的,则用来替换匹配到的SUBSTR
$ 以STR结尾的,则用来替换匹配到的SUBSTR
$ VAR未定义或者为空则打印$MSG
$ 索引及切片
$ 变量的间接引用 a=b;b=12345;echo ${! a}``结果为12345 而非 b
$ 小写字母转大写(string前面没有$)
$ 大写字母转小写(string前面没有$)
posted @ 2019-11-18 14:05  干瘪的柠檬  阅读(227)  评论(0)    收藏  举报