首页 > 系统相关 >2、shell变量

2、shell变量

时间:2022-12-29 09:48:47浏览次数:37  
标签:shell 变量 echo sh root localhost

变量基础

变量查看

语法解析

基本格式
	$变量名

示例

查看默认的shell类型
[root@localhost ~]# echo $SHELL
/bin/bash

4种查看变量的写法:
image

变量定义

普通语法解析

基本格式
	变量名=变量值
	
注意:
	= 两侧不允许有空格

示例

查看一个空值变量名
[root@localhost ~]#  echo $myname

定制变量实践
[root@localhost ~]# myname=shuji
[root@localhost ~]#  echo $myname
shuji
错误的定制变量命令
[root@localhost ~]#  echo $myage

[root@localhost ~]# myage = 18
bash: myage: 未找到命令
[root@localhost ~]#  echo $myage

image

类型变量定义

命令语法
	declare 参数 变量名=变量值
参数解析:
    -i 将变量看成整数 
    -r 使变量只读  readonly,==**该变量的值无法改变,并且不能为unset**==
    -x 标记变量为全局变量,类似于export
    -a	指定为索引数组(普通数组);查看普通数组
    -A 指定为关联数组;查看关联数组
注意:
	在生产场景中,这种方法比较鸡肋,使用频率 0-20次/3年
设定制定类型的变量值
[root@localhost ~]# declare -i mynum='shuzi'
[root@localhost ~]# echo $mynum
0
[root@localhost ~]# declare -i mynum='123456'
[root@localhost ~]# echo $mynum
123456

image

设定只读类型变量
[root@localhost ~]# declare -r myread1="aaa"
[root@localhost ~]# myread2=myread
[root@localhost ~]# readonly myread2

查看只读变量
[root@localhost ~]# declare -r | grep myread
declare -r myread1="aaa"
declare -r myread2="myread"
[root@localhost ~]# readonly -p | grep myread
declare -r myread1="aaa"
declare -r myread2="myread"

无法使用unset删除只读变量
[root@localhost ~]# unset myread1 myread2
bash: unset: myread1: 无法反设定: 只读 variable
bash: unset: myread2: 无法反设定: 只读 variable

借助于exit方式删除只读变量
[root@localhost ~]# exit
...... 重新登录后再次查看
[root@localhost ~]# declare -r | grep myread
[root@localhost ~]#

image
image
查看只读变量示例:
image
也可以使用管道然后过滤
image
删除只读变量示例:
先退出终端
image
重新连接就没了
image

变量移除

语法解析

基本格式
	unset 变量名

示例

查看刚才定制的变量名
[root@localhost ~]#  echo $myname
shuji

移除变量名
[root@localhost ~]# unset myname
[root@localhost ~]#  echo $myname

[root@localhost ~]#

image

本地变量

普通变量

变量分类

所谓的本地变量就是:在当前系统的某个环境下才能生效的变量,作用范围小。本地变量按照变量值的生成方式包含两种:
	普通变量:
		自定义变量名和变量值
	命令变量:
		自定义变量名,而变量值是通过一条命令获取的

基本格式

序号 样式 要点
方式一 变量名=变量值 变量值必须是一个整体,中间没有特殊字符
"=" 前后不能有空格
方式二 变量名='变量值' 原字符输出,我看到的内容,我就输出什么内容,
方式三 变量名="变量值" 如果变量值范围内,有可以解析的变量A,那么首先解析变量A,
将A的结果和其他内容组合成一个整体,重新赋值给变量
习惯:
	数字不加引号,其他默认加双引号
	因为bash属于弱类型语言,默认会将所有内容当成字符串

变量定义

查看默认的空值变量
[root@localhost ~]# echo $name

方法1设定变量
[root@localhost ~]# name=shuji
[root@localhost ~]# echo $name
shuji

方法2设定变量
[root@localhost ~]# name='shuji1'
[root@localhost ~]# echo $name
shuji1

方法3设定变量
[root@localhost ~]# name="shuji2"
[root@localhost ~]# echo $name
shuji2

清理变量
[root@localhost ~]# unset name

作用区别演示

查看默认的空值变量
[root@localhost ~]# echo $name2

方法1设定变量的要点,变量值必须是一个整体
[root@localhost ~]# name2=shuji haoshuai
bash: haoshuai: 未找到命令
[root@localhost ~]# echo $name2
原因解析:
	空格是一个特殊符号,表示两条命令的隔开
	它将shuji 和 haoshuai当成两条命令了,所以报错信息是命令找不到
	
方法2设定变量
[root@localhost ~]# name2='shuji haoshuai'
[root@localhost ~]# echo $name2
shuji haoshuai

方法3设定变量
[root@localhost ~]# name2="shuji haoweiwu"
[root@localhost ~]# echo $name2
haoweiwu	

清理变量
[root@localhost ~]# unset name2
定制基础变量
[root@localhost ~]# name=shuji
[root@localhost ~]# echo $name
shuji

方法2设定变量
[root@localhost ~]# name2='dan-$name'
[root@localhost ~]# echo $name2
dan-$name

方法3设定变量
[root@localhost ~]# name2="shuang-$name"
[root@localhost ~]# echo $name2
shuang-shuji

命令变量

基本格式

定义方式一:
	变量名=`命令`
    注意:
    ` 是反引号

定义方式二:推荐使用
	变量名=$(命令)
执行流程:
	1、执行 ` 或者 $() 范围内的命令
	2、将命令执行后的结果,赋值给新的变量名A

简单实践

命令变量实践

查看默认的空值变量
[root@localhost ~]# echo $myuser

方法1设定变量名
[root@localhost ~]# myuser=`whoami`
[root@localhost ~]# echo $myuser
root

image

查看默认的空值变量
[root@localhost ~]# echo $mydir

方法2设定变量名
[root@localhost ~]# mydir=$(pwd)
[root@localhost ~]# echo $mydir
/root

清理变量
[root@localhost ~]# unset mydir myuser

image

其他常见的实践

自动生成一系列数字
[root@localhost ~]# NUM=`seq 10`
[root@localhost ~]# echo $NUM
1 2 3 4 5 6 7 8 9 10

文件备份添加时间戳
[root@localhost ~]# touch file-a
[root@localhost ~]# cp file-a file-a-$(date +%F)
[root@localhost ~]# ls file-a*
file-a  file-a-2022-06-08

image

简单小综合实践

[root@localhost ~]# cat get_netinfo_v2.sh
#!/bin/bash
# 功能:获取当前主机的网卡设备信息
# 作者:wangshuji
# 版本:V0.2
# 联系:www.superopsmsb.com

# 定制基础变量
RED="\E[1;31m"
GREEN="echo -e \E[1;32m"
END="\E[0m"

# 获取ip地址信息
IPDDR=$(ifconfig eth0 | grep -w inet | awk '{print $2}')
# 获取掩码地址信息
NETMAST=$(ifconfig eth0 | grep -w inet | awk '{print $4}')
# 获取广播地址信息
BROADCAST=$(ifconfig eth0 | grep -w inet | awk '{print $6}')
# 获取MAC地址信息
MACADDR=$(ifconfig eth0 | grep ether | awk '{print $2}')

# 打印网络基本信息
$GREEN---------主机网卡基本信息---------$END
echo -e  "HOSTNAME:     $RED `hostname` $END"
echo -e  "IP:           $RED $IPDDR $END"
echo -e  "NetMask:      $RED $NETMAST $END"
echo -e  "Broadcast:    $RED $BROADCAST $END"
echo -e  "MAC Address:  $RED $MACADDR $END"
$GREEN---------主机网卡基本信息---------$END

全局变量

基本定义

全局变量是什么
	全局变量就是:在当前系统的所有环境下都能生效的变量。

基本语法

查看全局环境变量
	env			只显示全局变量,一般结合 grep 和管道符来使用
	printenv	效果与env等同
	
	export		查看所有的环境变量,包括声明的过程等信息,一般不用
	declare -x	效果与export类似
定义全局变量方法一:
	变量=值
	export 变量
定义全局变量方法二:(最常用)
	export 变量=值

简单实践

查看所有的全局变量
[root@localhost ~]# env
XDG_SESSION_ID=4
HOSTNAME=localhost
SHELL=/bin/bash
TERM=xterm
HISTSIZE=1000
...

查看制定的全局变量,grep筛选
[root@localhost ~]# env | grep SHELL
SHELL=/bin/bash
定制本地变量
[root@localhost ~]# envtype=local
[root@localhost ~]# echo $envtype
local

从全局变量中查看
[root@localhost ~]# env | grep envtype
[root@localhost ~]#
结果显示:
	无法从全局变量中查看本地变量的名称
方法1定制全局变量
[root@localhost ~]# echo $envtype
local
[root@localhost ~]# env | grep envtype
[root@localhost ~]# export envtype
[root@localhost ~]# env | grep envtype
envtype=local

方法2定制全局变量
[root@localhost ~]# export myuser=root
[root@localhost ~]# env | grep myuser
myuser=root

鸡肋方法定制全局变量,别用,不好
[root@localhost ~]# declare -x mydir=/root
[root@localhost ~]# env | grep mydir
mydir=/root

清理全局变量
[root@localhost ~]# unset envtype myuser mydir

image

文件体系

变量文件

变量文件

在linux环境中,有很多目录下的文件都可以定制一些作用范围更广的变量,这些文件或文件所在的目录有:
	作用范围在制定的用户范围:
        ~/.bashrc
        ~/.bash_profile
    作用的范围在系统范围:
        /etc/profile
        /etc/profile.d/env_file_name

简单实践

bashrc 或 bash_profile 实践

查看未知的变量名
[root@localhost ~]# echo $NAME

定制变量名到文件中
[root@localhost ~]# echo NAME=shuji >> ~/.bashrc
[root@localhost ~]# source ~/.bashrc
[root@localhost ~]# echo $NAME
shuji

新开一个终端查看效果
[root@localhost ~]# echo $NAME
shuji

新开一个普通用户的终端查看效果
[root@localhost ~]# su - python
[python@localhost ~]$ echo $NAME

[python@localhost ~]$
清理.bashrc 文件里的变量,然后清除当前环境下的变量名
unset NAME

image
新开一个普通用户的终端查看效果
image

profile实践
系统下的所有用户都能查到变量

查看未知的变量名
[root@localhost ~]# echo $PROFILE

定制变量名到文件中
[root@localhost ~]# echo PROFILE=shuji >> /etc/profile
[root@localhost ~]# source /etc/profile
[root@localhost ~]# echo $PROFILE
shuji

新开一个终端查看效果
[root@localhost ~]# echo $PROFILE
shuji

新开一个普通用户的终端查看效果
[root@localhost ~]# su - python
[python@localhost ~]$ echo $PROFILE
shuji
[python@localhost ~]$

嵌套shell

export原理

原理解析

用户登录时:
	用户登录到Linux系统后,系统将启动一个用户shell。
	在这个shell中,可以使用shell命令或声明变量,也可以创建并运行 shell脚本程序。

运行脚本时:
	运行shell脚本程序时,系统将创建一个子shell。	此时,系统中将有两个shell
		- 一个是登录时系统启动的shell,另一个是系统为运行脚本程序创建的shell。
		当一个脚本程序运行完毕,它的脚本shell将终止,可以返回到执行该脚本之前的shell。
意义解读
	从这种意义上来说,用户可以有许多 shell,每个shell都是由某个shell(称为父shell)派生的。
在子shell中定义的变量只在该子shell内有效。如果在一个shell脚本程序中定义了一个变量,当该脚本程序运行时,这个定义的变量只是该脚本程序内的一个局部变量,其他的shell不能引用它,要使某个变量的值可以在其他shell中被改变,可以使用export命令对已定义的变量进行输出。 

	export命令将使系统在创建每一个新的shell时定义这个变量的一个拷贝。这个过程称之为变量输出。

实践解读

	当前父shell中定义变量中,分为局部变量和全局变量,不同点是:
		- 局部变量只能作用于本父shell,子shell无法继续使用
		- 如果使用了export将局部变量定义为全局变量,那么子shell创建的时候会继承父shell的全局变量

嵌套实践

简单实践

查看父shell的脚本
[root@localhost ~]# cat father.sh
#!/bin/bash
# 定制全局变量
export _xing='王'
_name="书记"
_age="42"
echo "父shell信息: $_xing$_name,$_age"
sleep 3

# 调用child.sh进行验证,最好放在同一目录下
/bin/bash child.sh
echo "父shell信息: $_xing$_name,$_age"
查看子shell的脚本
#!/bin/bash
# 显示父shell的全局变量
echo "子shell信息: $_xing$_name,$_age"

# 同名变量 子shell 的优先级高于父shell,但是不会传递给父shell
_xing="王胖胖"
echo "子shell修改后的信息: $_xing"
执行测试效果
[root@localhost ~]# /bin/bash father.sh
父shell信息: 王书记,42
子shell信息: 王,
子shell修改后的信息: 王胖胖
父shell信息: 王书记,42

image
执行脚本
image

验证子脚本的同名变量是否会覆盖父脚本
image

验证子脚本修改变量后,父脚本是否受影响
image

内置变量

脚本相关

基础知识

脚本相关的变量解析

序号 变量名 解析
1 $0 获取当前执行的shell脚本文件名
2 \(n | 获取当前执行的shell脚本的第n个参数值,n=1..9,<br />当n为0时表示脚本的文件名,如果n大于9就要用大括号括起来\){10}
3 $# 获取当前shell命令行中参数的总个数
4 $? 获取执行上一个指令的返回值(0为成功,非0为失败)

简单实践

实践1 - $0 获取脚本的名称

[root@localhost ~]# cat get_name.sh
#!/bin/bash
# 获取脚本的名称
echo "我脚本的名称是: file.sh"
echo "我脚本的名称是:$0"

image

实践2 - $n 获取当前脚本传入的第n个位置的参数

[root@localhost ~]# cat get_args.sh
#!/bin/bash
# 获取指定位置的参数
echo "第一个位置的参数是: $1"
echo "第二个位置的参数是: $2"
echo "第三个位置的参数是: $3"
echo "第四个位置的参数是: $4"

image

实践3 - $# 获取当前脚本传入参数的数量

[root@localhost ~]# cat get_number.sh
#!/bin/bash
# 获取当前脚本传入的参数数量
echo "当前脚本传入的参数数量是: $#"

image

实践4 - $? 获取文件执行或者命令执行的返回状态值

[root@localhost ~]#  bash nihao
bash: nihao: No such file or directory
[root@localhost ~]#  echo $?
127

[root@localhost ~]#  ls
get_name.sh get_args.sh get_number.sh
[root@localhost ~]#  echo $?
0

image

字符串相关

基础知识

字符串相关的变量解析

字符串计数
	${#file}			获取字符串的长度

字符串截取	
	- 语法为${var:pos:length}   表示对变量var从pos开始截取length个字符,pos为空表示0
    ${file:0:5}			从0开始,截取5个字符
    ${file:5:5}			从5开始,截取5个字符
    ${file::5}			从0开始,截取5个字符
    ${file:0-6:3}		从倒数第6个字符开始,截取之后的3个字符
    ${file: -4}			返回字符串最后四个字节,-前面是"空格"

简单实践

字符串实践

定制字符串内容
[root@localhost ~]# string_context="dsjfdsafjkldjsklfajkdsa"
[root@localhost ~]# echo $string_context
dsjfdsafjkldjsklfajkdsa

获取字符串长度
[root@localhost ~]# echo ${#string_context}
23
从0开始,截取5个字符
[root@localhost ~]# echo ${string_context:0:5}
dsjfd

从5开始,截取5个字符
[root@localhost ~]# echo ${string_context:5:5}
safjk	

从0开始,截取5个字符
[root@localhost ~]# echo ${string_context::5}
dsjfd

从倒数第6个字符开始,截取之后的3个字符
[root@localhost ~]# echo ${string_context:0-6:3}
ajk

返回字符串最后四个字节,-前面是"空格"
[root@localhost ~]# echo ${string_context: -4}
kdsa	

image

默认值相关

基础知识

语法解读

格式一:${变量名:-默认值}	
	变量a如果有内容,那么就输出a的变量值
	变量a如果没有内容,那么就输出默认的内容

格式二:${变量名+默认值}	
	无论变量a是否有内容,都输出默认值

实践1 - 有条件的默认值

购买手机的时候选择套餐:
	如果我输入的参数为空,那么输出内容是 "您选择的套餐是: 套餐 1"
	如果我输入的参数为n,那么输出内容是 "您选择的套餐是: 套餐 n"	
[root@localhost ~]# select_default_value.sh
#!/bin/bash
# 套餐选择演示
a="$1"
echo "您选择的手机套餐是: 套餐 ${a:-1}"

image

实践2 - 强制默认值

国家法律强制规定:
	不管我说国家法定结婚年龄是 多少岁,都输出 国家法定结婚年龄(男性)是 22 岁	
[root@localhost ~]# froce_default_value.sh
#!/bin/bash
# 默认值演示示例二
a="$1"
echo "国家法定结婚年龄(男性)是 ${a+22} 岁"

image

其他相关

基础知识

脚本相关的变量解析

序号 变量名 解析
1 $_ 在此之前执行的命令或脚本的第一个内容
2 $@ 传给脚本的所有参数
3 $* 是以一个单字符串显示里所有向脚本传递的参数,与位置参数不同,参数可超过9个
4 $$ 是脚本运行的当前进程的ID号,作用是方便以后管理它杀掉他
5 $! 前一条命令进程的ID号,作用是方便以后管理它杀掉他

简单实践

实践1 - 其他变量的作用

[root@localhost ~]# cat get_other.sh
#!/bin/sh
echo "脚本执行命令的第一个内容: $_"
echo "传递给当前脚本的所有参数是: $@"
echo "单字符串显示所有参数: $*"
echo "当前脚本执行时候的进程号是: $$"
sleep 5 &
echo "上一条命令执行时候的进程号是: $!"

image

实践2 - $$ 获取当前的进程号

查看当前的进程号
[root@localhost ~]# echo $$
4759
[root@localhost ~]# ps aux | grep 4759
root       4759  0.0  0.0 116712  3356 pts/1    Ss   00:11   0:00 -bash
root       5547  0.0  0.0 112828   984 pts/1    S+   02:00   0:00 grep --color=auto 4759

杀死当前的进程,等于正在使用的bash被杀死了
[root@localhost ~]# kill -9 4759
───────────────────────────────────────────
Session stopped
    - Press <return> to exit tab
    - Press R to restart session
    - Press S to save terminal output to file

实践3 - $@ 和 $* 的区别

定制father脚本
[root@localhost ~]# cat father.sh
#!/bin/bash
echo "$0: 所有的参数 $@"
echo "$0: 所有的参数 $*"
echo '将 $* 值传递给 child-1.sh 文件'
/bin/bash child-1.sh "$*"

echo '将 $@ 值传递给 child-2.sh 文件'
/bin/bash child-2.sh "$@"
定制两个child脚本
[root@localhost ~]# cat child-1.sh
#!/bin/bash
echo "$0: 获取所有的参数 $1"

[root@localhost ~]# cat child-2.sh
#!/bin/bash
echo "$0: 获取所有的参数 $1"
执行 father.sh 脚本
[root@localhost ~]# /bin/bash father.sh 1 2 3
father.sh: 所有的参数 1 2 3
father.sh: 所有的参数 1 2 3
将 $* 值传递给 child-1.sh 文件
child-1.sh: 获取所有的参数 1 2 3
将 $@ 值传递给 child-2.sh 文件
child-2.sh: 获取所有的参数 1

image
验证结果:
image

标签:shell,变量,echo,sh,root,localhost
From: https://www.cnblogs.com/abiu/p/17007317.html

相关文章

  • PE格式:手工给程序插入ShellCode
    PE格式是Windows下最常用的可执行文件格式,理解PE文件格式不仅可以了解操作系统的加载流程,还可以更好的理解操作系统对进程和内存相关的管理知识,而有些技术必须建立在了......
  • #yyds干货盘点#Linux设置环境变量
    我们通过设置Linux的环境变量,可以方便我们的程序调用,比如我想把NodeJs加入环境变量/root/nodejs/bin/永久性更改对所有用户生效加入环境变量vim/etc/profile我们在最后一行......
  • mongodb shell 统计相关命令
    mongodbshell统计相关命令1countdb.tbPosition.find().count(); #集合的总记录数db.tbPosition.find({Acnt_Id:437}).count() #符合条件的记录总数db.tbPosition.co......
  • 宝塔上加shell定时任务
      脚本内容:#!/bin/bashPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/binexportPATHstep=5for((i=0;i<60;i=(i+step)));do......
  • linux配置java环境变量(详细)
    一.解压安装jdk 在shell终端下进入jdk-6u14-linux-i586.bin文件所在目录, 执行命令./jdk-6u14-linux-i586.bin这时会出现一段协议,连继敲回车,当询问是否同意的时候,输入......
  • shell
      Shell-set命令-Anliven-博客园(cnblogs.com)set-n或者set-onoexec语法检查模式,读取脚本并检查语法错误,但不执行set-e或者set-oerrexit如果命......
  • shell内置字符串替换
    shell变量赋值语法:使用规则 解释单引号 所见即所得,即输出时会将单引号内的所有內容都原样输出,或者描述为单引号里面看到的是什么就会输出什么,这称为强引用双引号(默认) ......
  • Java千问10:你知道Java语言boolean类型的变量到底占多大空间吗?
    ​我们都知道,Java语言中有个boolean类型。每个boolean类型的变量中存储的是一个true或者是false的逻辑值。那么存储这个逻辑值,需要多大的空间呢?从理论上来讲,存储这个逻辑值......
  • Java千问05:Java语言中为byte和short类型变量赋值为啥会报错?
    咱们先来看一段很简单的Java代码这段代码非常简单,没有任何技术含量。但是,如果我们把这段代码改成下面的样子大家可以看到,我们只是用一个变量a代替了原来赋值表达式当中的常......
  • Java千问07:你真的会用Java的int型变量吗?有些坑你真的不知道!
    ​我们在进行Java编程的时候,使用最频繁的数据类型基本上就是int型了。平时在使用这种数据类型的过程中,我们似乎也并没有感觉到有什么太多需要注意的地方,其实int类型的变量在......