前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux Shell基础篇二 - 变量

Linux Shell基础篇二 - 变量

作者头像
兜兜转转
发布2023-03-08 13:51:31
2.7K1
发布2023-03-08 13:51:31
举报
文章被收录于专栏:CodeTime

Shell变量

在Shell中包括有三种变量类型:系统环境变量、自定义变量和特殊符号变量。

系统环境变量

系统环境变量是系统提供的共享变量,是linux系统加载Shell的配置文件中定义的变量共享给所有的Shell程序使用。环境变量按照其作用范围不同大致可以分为系统级环境变量用户级环境变量

  • 系统级环境变量:Shell环境加载全局配置文件中的变量共享给所有用户所有Shell程序使用,全局共享
  • 用户级环境变量:Shell环境加载个人配置文件中的变量共享给当前用户的Shell程序使用,登录用户使用

Shell的配置文件分类:

  • 全局配置文件 /etc/profile /etc/profile.d/*.sh /etc/bashrc
  • 个人配置文件 当前用户/.bash_profile 当前用户/.bashrc

环境变量加载初始化过程:

  • 登录Shell环境:需要用户名\密码登录的Shell环境,配置在:/etc/profile/当前用户/.bash_profile
  • 非登录Shell环境:不需要用户名,密码进入的Shell环境或执行脚本文件,配置在:/当前用户/.bashrc/etc/bashrc

查看当前Shell环境:

1

echo $0

输出-bash表示shell登录环境,输出bash表示shell非登录环境。注意:这个 $0 环境变量如果用在子shell中(shell脚本文件)输出Shell脚本本身的文件名。

切换shell环境:

直接切换用户

12345

#切换到指定用户,加载Shell登录环境变量su 用户名 --login #或 su 用户名 -l# 切换到指定用户,加载Shell非登录环境变量su 用户名

切换Shell环境执行脚本文件

123456

#先加载Shell登录环境流程初始化环境变量, 再执行脚本文件sh/bash -l/--login 脚本文件#先执行加载Shell非登录环境流程初始化环境变量, 再执行脚本文件bash # 加载Shell非登录环境sh/bash 脚本文件

退出shell当前环境:

  • logout:只能退出Shell登录环境。
  • exit:可以退出Shell登录与非登录环境

查看系统环境变量:

  • env:查看当前Shell系统环境变量。
  • set:查看Shell变量(系统环境变量+自定义变量+函数)。

常用系统环境变量介绍:

变量名称

含义

PATH

与windows环境变量PATH功能一样,设置命令的搜索路径,以冒号为分割

HOME

当前用户主目录:/root

SHELL

当前shell解析器类型:/bin/bash

HISTFILE

显示当前用户执行命令的历史列表文件:/root/.bash_history

PWD

显示当前所在路径:/root

OLDPWD

显示之前的路径

HOSTNAME

显示当前主机名:itheima

HOSTTYPE

显示主机的架构,是i386、i686、还是x86、x64等:x86_64

LANG

设置当前系统语言环境:zh_CN.UTF-8

自定义变量

自定义变量分为三种类型:

  1. 自定义局部变量:就是定义在一个脚本文件中的变量, 只能在这个脚本文件中使用的变量, 就是局部变量
  2. 自定义常量:就是变量设置值以后不可以修改的变量叫常量, 也叫只读变量
  3. 自定义全局变量:就是在当前脚本文件中定义全局变量,这个全局变量可以在当前Shell环境与子Shell环境中都可以使用

变量的定义:

1

var_name=value

变量定义规则:

  1. 变量名称可以有字母,数字和下划线组成, 但是不能以数字开头
  2. 等号两侧不能有空格
  3. 在bash环境中, 变量的默认类型都是字符串类型, 无法直接进行数值运算
  4. 变量的值如果有空格, 必须使用双引号括起来
  5. 不能使用Shell的关键字作为变量名称

变量的取值:

12345

# 语法1: 直接使用变量名查询$var_name# 语法2: 使用花括号${var_name}# 区别: 花括号方式适合拼接字符串

注意: 如果echo "My name is

变量删除:

1

unset var_name

设置自定义常量:

1

readonly var_name

在定义好局部变量之后,执行readonly var_name即可把变量设置为只读,之后不可再对该变量进行赋值操作。

设置自定义全局变量:

1

export var_name1 var_name2

全局变量可以在当前shell环境的子环境中也可以使用,例如,我们创建2个脚本文件:parent.shchild.sh

123456

#!/bin/bash#parent.shvar_global=testexport var_globalecho "parent.sh中输出var_global变量:${var_global}"bash child.sh

123

#!/bin/bash#child.shecho "child.sh中输出var_global变量:${var_global}"

然而直接在交互式Shell环境中打印${var_global}是得不到结果的,说明全局变量在当前Shell环境与子Shell环境中可用,父Shell环境中不可用。

特殊符号变量

特殊变量

含义

$n

获取输入参数的$0, 获取当前Shell脚本文件名字$1~$9, 获取第一个输入参数到第九个输入参数${10} 获取10和10以上的参数需要使用花括号

$#

获取所有输入参数的个数

$* 与 $@

获取所有输入参数数据区别: 如果不使用双引号, 功能一样, 获取所有参数数据为一个字符串, 如果使用了双引号, $@获取的就是参数列表对象, 每个参数都是一个独立字符串。

$?

获取上一个命令的退出状态码, 一般;来说0代表命令成功,非0代表执行失败。

$$

获取当前shell环境进程的ID号。

$n用于接收脚本文件执行时传入的参数:

1

sh 脚本文件 输入参数1 输入参数2 ...

  • $0 用于获取当前脚本文件名称的
  • 1~9, 代表获取第一输入参数到第9个输入参数
  • 第10个以上的输入参数获取参数的格式: ${数字},否则无法获取

#获取所有输入参数的个数(脚本文件本身并不计算再内),也就是从1开始计数。

*和@都是获取所有输入参数, 用于以后输出所有参数。

区别:

  1. 不使用双引号括起来, 功能一样 *和@获取所有输入参数,格式为: 1 2 …
  2. 使用双引号括起来 “*“获取的所有参数拼接为一个字符串, 格式为: “1 2 … n” “@“获取一组参数列表对象, 格式为: “1” “2” … “n” 使用循环打印所有输入参数可以看出区别

演示:

直接输出所有输入参数, 与循环方式输出所有输入参数(使用双引号包含 * 与 @ ),创建test.sh:

1234567891011121314151617181920212223242526272829303132

#!/bin/bash# 命令1: 打印当前脚本文件名字echo "当前脚本文件名称:$0"# 命令2: 打印第1个输入参数echo "第一个输入参数:$1"# 命令3: 打印第2个输入参数echo "第二个输入参数:$2"# 命令4: 打印第10个输入参数echo "第十个输入参数不带花括号获取:$10"echo "第十个输入参数带花括号获取:${10}"# 命令5 打印所有输入参数的个数echo "所有输入参数个数:${#}"# 增加命令: 实现直接输出所有输入后参数echo '使用$*直接输出:'$*echo '使用$@直接输出:'$@# 增加命令: 使用循环打印输出所有输入参数echo '循环遍历输出$*所有参数'for item in "$*"do echo $itemdoneecho '循环遍历输出$@所有参数'for item in "$@"do echo $itemdone

执行效果:

$?用于获取上一个Shell命令的退出状态码, 或者是函数的返回值,每个Shell命令的执行都有一个返回值, 这个返回值用于说明命令执行是否成功,一般来说, 返回0代表命令执行成功, 非0代表执行失败。

$$用于获取当前Shell环境的进程ID号:

自定义系统环境变量

当前用户进入Shell环境初始化的时候会加载全局配置文件/etc/profile里面的环境变量,供给所有Shell程序使用,以后只要是所有Shell程序或命令使用的变量就可以定义在这个文件中。

演示:

添加设置变量VAR1=VAR1并导出成为环境变量, 在系统级全局配置文件/etc/profile末尾添加如下命令:

123

# 创建环境变量VAR1=VAR1export VAR1

保存/etc/profile退出,重新加载/etc/profile文件数据更新系统环境变量。(注意:如果这一步不执行,无法读取更新的环境变量)

1

source /etc/profile

在交互式Shell中输出环境变量

1

echo $VAR1

Shell字符串变量

字符串是 Shell 编程中最常用的数据类型之一,除了数字和字符串,也没有其他类型了,Shell的变量默认就是字符串。

变量的赋值

字符串变量有3种格式表示,我们先设置一个变量var1=abc,然后比较3种格式的效果:

单引号:任何字符都会原样输出,在其中使用变量是无效的。

123

var2='abc${var1}'echo $var2#输出:abc${var1}

双引号(推荐):其中包含了变量,那么该变量会被解析得到值,而不是原样输出。如果字符串中还包含了双引号则需要转义。

1234567

var2="abc${var1}"echo $var2#输出:abcabcvar3="hello,\"${var1}\""echo $var3#输出:hello,"abc"

不用引号:不被引号包围的字符串中出现变量时也会被解析,这一点和双引号" "包围的字符串一样。但字符串中不能出现空格,否则空格后边的字符串会作为其他变量或者命令解析。

1234567

var2=abc${var1}echo $var2#输出:abcabcvar2=abc ${var1}echo $var2#报错:-bash: abc: command not found

字符串拼接:

  1. 无符号拼接:echo {var1}{var2}
  2. 双引号拼接:echo "
  3. 混合拼接:echo {var1}"&"{var1}'&'

变量的取值

设置变量var=abc

变量取值:

1

echo ${var} #输出:abc

获取字符串长度:

1

echo ${#var} #输出:3

截取语法:

格式

说明

${变量名:start:length}

从 string 字符串的左边第 start 个字符开始,向右截取 length 个字符。

${变量名:start}

从 string 字符串的左边第 start 个字符开始截取,直到最后。

${变量名:0-start:length}

从 string 字符串的右边第 start 个字符开始,向右截取 length 个字符。

${变量名:0-start}

从 string 字符串的右边第 start 个字符开始截取,直到最后。

${变量名#*chars}

从 string 字符串第一次出现*chars的位置开始,截取*chars右边的所有字符。

${变量名##*chars}

从 string 字符串最后一次出现*chars的位置开始,截取*chars右边的所有字符。

${变量名%chars*}

从 string 字符串最后一次出现chars*的位置开始,截取chars*左边的所有字符。

${变量名%%chars*}

从 string 字符串第一次出现chars*的位置开始,截取chars*左边的所有字符。

示例,截取path变量的值

操作

结果

${path#/*:}

/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

${path##/*:}

/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

${path%:*bin}

/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

${path%%:*bin}

/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

替换语法:

格式

说明

示例

${变量名/旧字符串/新字符串}

将旧字符串替换成新字符串,仅替换第一个

${path/sbin/SBIN}将sbin替换成SBIN,仅替换第一个

${变量名//旧字符串/新字符串}

将旧字符串替换成新字符串,替换所有

${path//sbin/SBIN}将sbin替换成SBIN,所有的都替换

变量的测试及默认值:

变量设定方式

str没有设定

str为空字符串

str已设定非为空字符串

var=${str-expr}

var=expr

var=$str=空

var=$str

var=${str:-expr}

var=expr

var=expr

var=$str

var=${str+expr}

var=空

var=expr

var=expr

var=${str:+expr}

var=空

var=空

var=expr

var=${str=expr}

str=exprvar=expr

str不变var=$str=空

str不变var=$str

var=${str:=expr}

str=exprvar=expr

str=exprvar=expr

str不变var=$str

var=${str?expr}

expr输出至stderr

var=$str=空

var=$str

var=${str:?expr}

expr输出至stderr

expr输出至stderr

var=$str

-=?都是测试str变量是否设定,如果str没有设定则将表达式的值赋值给var,有设定则赋值str的值。区别就在于-只会更新val的值,而=会同时更新str?则只会将表达式的值输出到标准错误,并不会赋值给var+与上面的规则相反,它表示只有str有设定值时才会将表达式的值赋值给var,如果没有设定值,则var赋值为空。 :的意义在于,如果不加:默认空字符串也表示str有设定值,而加上:则表示如果str设定了值,但值为空字符串,依然当作str没有设定值处理。

Shell索引数组变量

定义:

1234

arr=(29 100 13 8 91 44)arr=(20 56 "abc")arr=([0]=1 [2]=100 [4]=aa) #可直接对索引赋值进行初始化,由于上面只赋值了3个元素, 所以数组的长度是3arr[6]=100 #Shell数组元素定义后不是固定的, 定义后还可以赋值

获取:

1234

${arr[1]} #通过下标获取${arr[@]} #获取数组所有元素,也可以使用${arr[*]}${#arr[@]} #获取数组的长度或个数,也可以使用${#arr[*]}${#arr[1]} #获取数组索引1元素的字符长度

拼接:

12

array_new=(${array1[@]} ${array2[@]} ...)array_new=(${array1[*]} ${array2[*]} ...)

注:拼接后,新数组的索引为重新排列

删除:

12

unset array_name[index] #删除数组指定元素数据unset array_name #删除整个数组

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-01-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Shell变量
    • 系统环境变量
      • 自定义变量
        • 特殊符号变量
          • 自定义系统环境变量
          • Shell字符串变量
            • 变量的赋值
              • 变量的取值
              • Shell索引数组变量
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档