前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[Linux]shell基础教程4-变量详细讲解

[Linux]shell基础教程4-变量详细讲解

作者头像
祥知道
发布2020-03-10 15:56:43
6270
发布2020-03-10 15:56:43
举报
文章被收录于专栏:祥的专栏祥的专栏

原创文章,欢迎转载。转载请注明:转载自 祥的博客

原文链接:https://cloud.tencent.com/developer/article/1596384


文章目录

代码语言:txt
复制
- @[toc]环境概述环境变量2.1. 与环境变量相关的命令2.2. 自定义环境变量2.3. 让环境变量永久生效2.3.1. 用户环境变量配置2.3.2. 全局环境变量配置2.4. 启动顺序2.5. 小结普通变量3.1. 定义3.2. 输出及其显示3.2.1. 例子13.2.2. 例子23.3. 把命令的结果作为变量的内容赋值的方法3.4. 注意例子参考文献:

环境

  • ubuntu 16.04
  • GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)

1. 概述

变量可分为两类:环境变量(全局变量)普通变量(局部变量)

  • 环境变量也可称为全局变量,可以在创建它们的Shell及其派生出来的任意子进程Shell中使用,环境变量又可分为自定义环境变量bash内置的环境变量
  • 普通变量也可称为局部变量,只能在创建它们的Shell函数Shell脚本 中使用。普通变量 一般由开发者在开发脚本程序时创建。

默认情况下,在bash Shell中是 不会区分变量类型 的,例如常见的变量类型为整数字符串等。这和其他强类型语言(比如C语言等)是有区别的。当然,如果需要指定Shell变量的类型,也可以使用declare -p显示定义变量的类型,但在一般情况下没有这个需求。

代码语言:javascript
复制
root@vultr:~# echo $HOME
/root
root@vultr:~# declare -p HOME 
declare -x HOME="/root"

2. 环境变量

环境变量一般是指用export内置命令导出的变量(运行export -p可以查看)。

所有的环境变量都是系统全局变量,可用于所有子进程中,这包括编辑器Shell脚本各类应用

环境变量可以在命令行中设置和创建,但用户退出命令行时这些变量值就会丢失,如果希望 永久保存 环境变量,可在用户 家目录 下的.bash_profile.bashrc非用户登录模式特有,如远程SSH)文件中,或者全局配置/etc/bashrc非用户登录模式特有,如远程SSH)或 /etc/profile 文件中定义。在将环境变量放入上述的文件中后,每次用户登录时这些变量都将被初始化

按照系统规范,所有环境变量的名字均采用大写形式 。在将环境变量应用于用户进程程序之前,都应该用export命令导出定义。

有一些环境变量,比如HOMEPATHSHELLUIDUSER等,在用户登录之前就已经被/bin/login程序设置好了。通常环境变量被定义并保存在用户家目录下的.bash_profile文件或全局的配置文件/etc/profile中。

代码语言:javascript
复制
# 定义一个环境变量 MY_BLOG
root@vultr:~# export MY_BLOG="http://blog.csdn.net/humanking7/"

# 显示环境变量(中间删去了一些显示内容)
root@vultr:~# export -p
declare -x MY_BLOG="http://blog.csdn.net/humanking7/"
declare -x HOME="/root"
declare -x LANG="en_US.UTF-8"
declare -x LESSCLOSE="/usr/bin/lesspipe %s %s"
declare -x LESSOPEN="| /usr/bin/lesspipe %s"
declare -x LOGNAME="root"
declare -x MAIL="/var/mail/root"
declare -x OLDPWD
declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"
declare -x PWD="/root"
declare -x SHELL="/bin/bash"
declare -x SHLVL="1"
declare -x SSH_TTY="/dev/pts/2"
declare -x TERM="xterm"
declare -x USER="root"
declare -x XDG_DATA_DIRS="/usr/local/share:/usr/share:/var/lib/snapd/desktop"

2.1. 与环境变量相关的命令

5个命令都与变量有关

  • set
  • unset
  • env
  • declare
  • export
  • readonly

set 命令会输出所有的变量全局变量局部变量),直接在shell中输入set,会有很多的数据输出,建议用set | less进行查看,使用set | wc -l可以发现一共有2106行数据,而且本身set命令也有很多选项和玩法,以后在慢慢研究。其中set -o会显示bash shell的所有参数配置信息。

env命令只会显示全局变量

declare命令会输出所有的变量函数整数已经导出的变量。用declare | wc -l一查还是2106行,declare本身是可以声明、取消、查看变量类型的,也有很多玩法。

export命令,对于查看shell赋予程序的环境变量,我是特别喜欢用export -p进行显示,非常清爽。

readonly 变量名,将设置变量为只读变量,出于安全的原故,只读变量是不可以复位/取消的,只有等到shell注销。

unset命令可以清除环境变量,而且setenvexport设置的变量,都可以用它来清除。

代码语言:javascript
复制
# 设置环境变量
root@vultr:~# export MY_BLOG="http://blog.csdn.net/humanking7/"
root@vultr:~# env | grep MY_BLOG
MY_BLOG=http://blog.csdn.net/humanking7/
root@vultr:~# set | grep MY_BLOG
MY_BLOG=http://blog.csdn.net/humanking7/
root@vultr:~# export -p | grep MY_BLOG
declare -x MY_BLOG="http://blog.csdn.net/humanking7/"
root@vultr:~# declare | grep MY_BLOG
MY_BLOG=http://blog.csdn.net/humanking7/

# 将变量设置为只读
root@vultr:~# readonly MY_BLOG 

# 只读变量无法改变和删除
root@vultr:~# export MY_BLOG="csdn"
-bash: MY_BLOG: readonly variable
root@vultr:~# unset MY_BLOG 
-bash: unset: MY_BLOG: cannot unset: readonly variable

# 设置一个环境变量,然后清除
root@vultr:~# export WEB_SITE=google.com
root@vultr:~# env | grep WEB_SITE
WEB_SITE=google.com
root@vultr:~# unset WEB_SITE 
root@vultr:~# env | grep WEB_SITE
root@vultr:~# 

2.2. 自定义环境变量

代码语言:javascript
复制
# 方法1
export variableName=value

# 方法2
declare -x variableName=value

上述的两个方法也是重新赋值的方法,示例如下:

代码语言:javascript
复制
root@vultr:~# export MY_NAME=Q
root@vultr:~# env | grep MY_NAME
MY_NAME=Q
root@vultr:~# declare -x MY_NAME=F
root@vultr:~# env | grep MY_NAME
MY_NAME=F
root@vultr:~# export MY_NAME=A
root@vultr:~# env | grep MY_NAME
MY_NAME=A

2.3. 让环境变量永久生效

如果希望环境变量永久生效,则可以将 环境变量 放在用户环境变量文件全局环境变量文件里。

让环境变量永久生效的常用设置文件

2.3.1. 用户环境变量配置

家目录(比如说家目录是/root/)下的两个文件中写入环境变量(随便一个就可以)

代码语言:javascript
复制
/root/.bashrc
/root/.bash_profile

2.3.2. 全局环境变量配置

常见的全局环境变量的配置文件如下:

代码语言:javascript
复制
/etc/bashrc      # 推荐在此文件中优先设置
/etc/profile
/etc/profile.d/

2.4. 启动顺序

Shell初始化过程是这样的:

  1. bash 检查文件/etc/profile(默认的Shell主环境变量文件,每个用户登录都会加载)是否存在,存在就读取环境变量,否则跳过;
  2. 当加载完/etc/profile文件后,才会执行/etc/profile.d/目录下的脚本文件,这个目录下的脚本文件有很多
  3. 之后bash 检查家目录$HOME下的文件.bash_profile (用户环境变量文件)是否存在,存在就读取环境变量,否则跳过;
  4. 又会去找$HOME/.bashrc(用户环境变量文件),存在就读取环境变量,否则跳过。
  5. $HOME/.bashrc文件中又会去找/etc/bashrc(全局环境变量文件),存在就读取环境变量,否则跳过。

注意:

如果用户的Shell不是登录时启动的(比如手动敲下bash时启动 或者 其他不需要输入密码的登录远程SSH连接情况),那么这种非登录Shell只会加载$HOME/.bashrc(用户环境变量文件),并会去找/etc/bashrc(全局环境变量文件)。因此如果希望在非登录Shell下也可读到设置的环境变量等内容,就需要将变量设定等写入$HOME/.bashrc或者/etc/bashrc,而不是$HOME/.bash_profile/etc/profile

2.5. 小结

环境变量的知识(见参考文献1 ):

  1. 变量名通常要大写。
  2. 变量可以在自身的Shell及子Shell中使用。
  3. 常用export来定义环境变量
  4. 执行env默认可以显示所有的环境变量名称对应的值
  5. 输出时用“$变量名”,取消时用“unset变量名”
  6. 书写crond定时任务时要注意,脚本要用到的环境变量最好先在所执行的Shell脚本中重新定义。
  7. 如果希望环境变量永久生效,则可以将其放在用户环境变量文件全局环境变量文件里。

3. 普通变量

3.1. 定义

本地变量在用户当前Shell生存期的脚本中使用。如果在Shell中启动另一个进程退出,那么变量将会失效。

3种定义方法:

代码语言:javascript
复制
# 赋值时不加引号
variableName=value 

# 赋值时加单引号
variableName='value'       

# 赋值时加双引号
variableName="value"       

变量的内容可以用单引号双引号引起来,也可不加引号,但是这三者的含义是不同的。

3.2. 输出及其显示

$变量名表示输出变量,可以用$变量名${变量名}两种用法。

3.2.1. 例子1

代码语言:javascript
复制
#!/bin/bash
# author:Q
# url:http://blog.csdn.net/humanking7/

var1=2018
var2='2018'
var3="2018"

echo "var1=$var1"
echo "var2=$var2"
echo "var3=${var3}"

运行结果:

代码语言:javascript
复制
root@vultr:~# ./t2.sh 
var1=2018
var2=2018
var3=2018

3.2.2. 例子2

代码语言:javascript
复制
#!/bin/bash
# author:Q
# url:http://blog.csdn.net/humanking7/

var1=2018
var1=2018-$var1
var2='2018-$var1'
var3="2018-$var1"

echo "var1=$var1"
echo "var2=$var2"
echo "var3=${var3}"

运行结果:

代码语言:javascript
复制
root@vultr:~# ./t2.sh 
var1=2018-2008
var2=2018-$var1
var3=2018-2018-2008

分析:

1种定义方式,var1,是不加任何引号直接定义变量的内容(值)。当内容简单连续的数字字符串路径名时,可以这样用。不加引号时,里有变量会被解析后再输出,上述变量定义中因为$var1的值被解析为2018,因此新的var1值就是2018-2018

2种定义方式,通过单引号定义。这种定义方式的特点就是,单引号里面是什么,输出内容就是什么,即使内容(值)里面有变量或者命令(命令需要反引号引起来)。所以对var2定义是2018-$var1,最终也是原样输出。

3种定义方式,通过双引号定义。这种定义方式的特点是,输出变量内容时引号里的变量及命令会经过解析后再输出内容。这种方式比较适合于字符串中附带有变量命令且想将其解析后再输出的变量定义。

Tip:

  1. 数字内容的变量定义可以不加引号
  2. 其他没有特别要求的字符串等定义最好都加上双引号
  3. 如果真的需要原样输出就加单引号

3.3. 把命令的结果作为变量的内容赋值的方法

对需要获取命令结果的变量内容赋值的常见方法有2种:

代码语言:javascript
复制
# 方法1
# 把命令用反引号引起来,不推荐使用这种方法,因为容易和单引号混淆
variableName=`ls`

# 方法2
# 把命令用$()括起来,推荐使用这种方法
variableName=$(ls)

方法1:

代码语言:javascript
复制
root@vultr:~# ls -1
code
control_vpn
restart_ss.sh
showUsed_ss.sh
t2.sh
root@vultr:~# cmd=`ls -1`
root@vultr:~# printf "$cmd"
code
control_vpn
restart_ss.sh
showUsed_ss.sh

方法2:

代码语言:javascript
复制
root@vultr:~# cmd2=$(ls -1)
root@vultr:~# printf "$cmd2"
code
control_vpn
restart_ss.sh
showUsed_ss.sh

3.4. 注意

单独拎出来写一个小节,觉得是这个有点重要。

变量名前加$可以取得该变量的值,使用echoprintf命令可以显示变量的值$变量名${变量名} 的写法不同,但效果是一样的。

变量后面连接有其他字符的时候,必须给变量加上大括号{},如下面的例子:

代码语言:javascript
复制
root@vultr:~# var1='my '
root@vultr:~# var1name=csdn

root@vultr:~# echo $var1name
csdn
root@vultr:~# echo ${var1}name
my name

Tip:

  1. 数字内容的变量定义可以不加引号
  2. 其他没有特别要求的字符串等定义最好都加上双引号
  3. 如果真的需要原样输出就加单引号
  4. 希望变量值引用命令并获取命令的结果时就用反引号$()

4. 例子

例子1:

代码语言:javascript
复制
root@vultr:~# echo "today : `date`"
today : Thu Nov 29 14:07:43 UTC 2018

root@vultr:~# echo "today : $(date)"
today : Thu Nov 29 14:07:57 UTC 2018

例子2:

代码语言:javascript
复制
# test.txt 文件里面有6行内容
# 其中有2行包含变量var1的值"csdn"
# 其中有2行包含"$var1",这个字符串
root@vultr:~# cat test.txt 
csdn
https://blog.csdn.net/humanking7/
baidu.com
google.com
$var1
$var1name

# 定义一个变量
root@vultr:~# var1=csdn

# 查找变量"值" 与 文件匹配的内容
root@vultr:~# grep $var1 test.txt 
csdn
https://blog.csdn.net/humanking7/

root@vultr:~# grep ${var1} test.txt 
csdn
https://blog.csdn.net/humanking7/

root@vultr:~# grep "$var1" test.txt 
csdn
https://blog.csdn.net/humanking7/

# 查找字符串"$var1" 与 文件匹配的内容
root@vultr:~# grep '$var1' test.txt 
$var1
$var1name

参考文献1

5. 参考文献:

  1. 跟老男孩学运维:Shell编程实战

OK!

以上,Enjoy~

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 环境
  • 1. 概述
  • 2. 环境变量
    • 2.1. 与环境变量相关的命令
      • 2.2. 自定义环境变量
        • 2.3. 让环境变量永久生效
          • 2.3.1. 用户环境变量配置
          • 2.3.2. 全局环境变量配置
        • 2.4. 启动顺序
          • 2.5. 小结
          • 3. 普通变量
            • 3.1. 定义
              • 3.2. 输出及其显示
                • 3.2.1. 例子1
                • 3.2.2. 例子2
              • 3.3. 把命令的结果作为变量的内容赋值的方法
                • 3.4. 注意
                • 4. 例子
                • 5. 参考文献:
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档