变量

变量概述

  • 变量表示命名的内存空间,将数据放在内存空间中,通过变量名引用,获取数据

变量类型

内置变量

  • 即shell自带的变量,如:

    #bash shell自带的环境变量
    PS1
    PATH
    SHELL
    USER
    UID
    HOME
    PWD
    SHLVL #shell的嵌套层数,即深度
    LANG
    MAIL
    HOSTNAME
    HISTSIZE
    _   #下划线 表示前一命令的最后一个参数
    $$ #当前shell的PID
    PPID #父进程的PID
    $? #上一个命令的执行结果,成功为0,不成功为非0
  • $?

    0 #成功
    1 #失败(范围1-255)
    
    #自定义退出状态码
    [root@aliyun ~]# vim 123.sh 
    [root@aliyun ~]# cat 123.sh 
    #!/bin/bash
    exit 100
    [root@aliyun ~]# bash 123.sh 
    [root@aliyun ~]# echo $?
    100
  • $-

    • h:hashall,打开选项后,Shell 会将命令所在的路径hash下来,避免每次都要查询。通过set +h将h选项关闭
    • i:interactive-comments,包含这个选项说明当前的 shell 是一个交互式的 shell。所谓的交互式shell,在脚本中,i选项是关闭的
    • m:monitor,打开监控模式,就可以通过Job control来控制进程的停止、继续,后台或者前台执行等
    • B:braceexpand,大括号扩展
    • H:history,H选项打开,可以展开历史列表中的命令,可以通过!感叹号来完成,例如“!!”返回上最近的一个历史命令,“!n”返回第 n 个历史命令

按数据类型划分

  • 字符型:
    • abc…
  • 数值型:
    • 整数(bash不支持浮点数)

按生效范围划分

  • 普通变量(局部变量)

    • 生效范围为当前shell进程;对当前shell以外的其他进程,以及子进程均无效
  • 环境变量(全局变量)

    • 主要用于系统配置
    • 生效范围为当前shell进程和其子进程
    • 可以使子进程(包括孙子进程)继承父进程的变量
    • 一旦子进程修改从父进程继承过来的变量,将会将新的值传递给孙子进程
  • 本地变量

    • 生效范围为当前shell进程中某代码片段,通常指函数
  • 只读变量(常量)

    • 生效范围为当前shell进程;只能声明定义,但后续不能修改和删除(即退出终端重新登陆则消失,即退出当前shell)

位置变量

$1, $2, ... #对应第1个、第2个等参数,shift [n]换位置 (第十个参数$10错误${10}正确)
$0 #命令本身,包括路径(也可以配合`basename $0` 或 `dirname $0`来取基名和目录名)
$* #传递给脚本的所有参数,全部参数合为一个字符串
$@ #传递给脚本的所有参数,每个参数为独立字符串
$# #传递给脚本的参数的个数
#注意:$@ $* 只在被双引号包起来的时候才会有差异

#清空所有位置变量:
set --

shell中变量命名法则

  1. 只能使用数字、字母及下划线,且不能以数字开头(不支持短横线 “ - ”,(主机名支持-不支持_))
  2. 不能使用程序的保留字,如:if,for,then… 还有内部变量名:PS1,PATH,LANG…
  3. 见名知意,用英文命名,并体现出实际作用
  4. 统一命名法则;驼峰命名法:大驼峰,StudentName;小驼峰,studentName
  5. 变量名大写:VAR_NAME
  6. 局部变量小写
  7. 函数名小写:function

变量赋值

临时赋值

  • 临时生效,当退出终端后,变量会自动删除,无法持久保存

  • 子进程不能使用父进程定义的变量,如要使用则父进程需定义环境变量

  • 脚本中的变量会随着脚本结束,也会自动删除

普通变量赋值

#直接赋值
VAR_NAME="root"

#变量引用赋值
VAR_NAME="$USER" 

#命令引用赋值
VAR_NAME=`COMMAND`
VAR_NAME=$(COMMAND) #常用

#强赋值,其中的变量或命令不会被替换为变量值或命令输出结果,而保持原字符串
## VAR_NAME='$USER' 
## echo $VAR_NAME
$USER
## VAR_NAME='`pwd`'
## echo "$VAR_NAME"
`pwd`

环境变量赋值

  • 环境变量即全局变量

  • 定义的变量会被子进程或孙子进程…所继承

#方法一
export VAR_NAME=VALUE

#方法二
declare -x VAR_NAME=VALUE

#方法三
VAR_NAME=VALUE
export VAR_NAME

设置只读变量

readonly VAR_NAME=VALUE
#或者
declare -r VAR_NAME=VALUE

查看只读变量

readonly [-p]
#或者
declare  -r

永久赋值

/etc/profile

/etc/profile.d/*.sh

变量引用

$name
${name} #推荐使用

#弱引用和强引用
VAR_NAME=$USER 
[root@centos ~]# echo $VAR_NAME #弱引用,其中的变量引用会被替换为变量值
root
[root@centos ~]# echo $VAR_NAME' #强引用,其中的变量引用不会被替换为变量值,而保持原字符串
$USER

范例:变量的各种赋值方式和引用

[root@centos8 ~]#TITLE='cto'
[root@centos8 ~]#echo $TITLE
cto
[root@centos8 ~]#echo I am $TITLE
I am cto
[root@centos8 ~]#echo "I am $TITLE"
I am cto
[root@centos8 ~]#echo 'I am $TITLE'
I am $TITLE
----------------------------------------------------------------------------
[root@centos8 ~]#NAME=$USER
[root@centos8 ~]#echo $NAME
root
[root@centos8 ~]#USER=`whoami`
[root@centos8 ~]#echo $USER
root
[root@centos8 ~]#FILE=`ls /run`
[root@centos8 ~]#echo $FILE
agetty.reload atd.pid auditd.pid autofs.fifo-misc autofs.fifo-net console 
cron.reboot cryptsetup dbus faillock fsck initctl initramfs lock log mount 
NetworkManager plymouth rsyslogd.pid screen sepermit setrans sshd.pid sssd.pid 
sudo systemd tmpfiles.d tuned udev user utmp vmware
----------------------------------------------------------------------------
[root@centos8 ~]#FILE=/etc/*
[root@centos8 ~]#echo $FILE
/etc/adjtime /etc/aliases /etc/alternatives /etc/anacrontab /etc/at.deny 
/etc/audit /etc/authselect /etc/autofs.conf /etc/autofs_ldap_auth.conf
----------------------------------------------------------------------------
[root@centos8 ~]#seq 10
1
2
3
4
5
6
7
8
9
10
[root@centos8 ~]#NUM=`seq 10`
[root@centos8 ~]#echo $NUM
1 2 3 4 5 6 7 8 9 10
[root@centos8 ~]#echo "$NUM"
1
2
3
4
5
6
7
8
9
10
-----------------------------------------------------------------------------------
[root@centos8 ~]#NAMES="wang
> zhang
> zhao
> li"
[root@centos8 ~]#echo $NAMES
wang zhang zhao li
[root@centos8 ~]#echo "$NAMES"
wang
zhang
zhao
li
--------------------------------------------------------------------------------------
[root@centos8 data]#NAME=mage
[root@centos8 data]#AGE=20
[root@centos8 data]#echo $NAME
mage
[root@centos8 data]#echo $AGE
20
[root@centos8 data]#echo $NAME $AGE
mage 20
[root@centos8 data]#echo $NAME$AGE
mage20
[root@centos8 data]#echo $NAME_$AGE
20
[root@centos8 data]#echo ${NAME}_$AGE
mage_20
--------------------------------------------------------------------------------------
#变量的间接赋值和引用
[root@centos8 ~]#TITLE=cto
[root@centos8 ~]#NAME=wang
[root@centos8 ~]#TITLE=$NAME
[root@centos8 ~]#echo $NAME
wang
[root@centos8 ~]#echo $TITLE
wang
[root@centos8 ~]#NAME=mage
[root@centos8 ~]#echo $NAME
mage
[root@centos8 ~]#echo $TITLE
wang
--------------------------------------------------------------------------------------
#变量追加值
[root@centos8 ~]#TITLE=CTO
[root@centos8 ~]#TITLE+=:wang
[root@centos8 ~]#echo $TITLE
CTO:wang
--------------------------------------------------------------------------------------
#利用变量实现动态命令
[root@centos8 ~]#CMD=hostname
[root@centos8 ~]#$CMD
centos8.wangxiaochun.com

设置只读变量

readonly VAR_NAME=VALUE
#或者
declare -r VAR_NAME=VALUE

查看只读变量

readonly [-p]
#或者
declare  -r

set 命令实现脚本安全

  • set命令可以用来定制shell环境

  • 生中建议在脚本中添加set -ue,也是一种安全策略

  • set选项说明:

    • **-e ** 如果一个命令返回一个非0退出状态值(失败)就退出, 等同set -o errexit **( 命令出了错就不继续执行 ) **
    • -u 在使用一个没有设置的变量时,显示错误信息, 等同set -o nounset**(变量没有被赋值就不去执行)**
    • -x 当执行命令时,打印命令及其参数,类似 bash -x
#显示选项
[root@aliyun ~]# set -o
allexport      	off
braceexpand    	on 
emacs          	on
...

#打开选项(需在脚本中添加,因为只能在当前shell中有效)
set -ue

#关闭选项(需在脚本中添加,因为只能在当前shell中有效)
set +ue

变量相关命令

set

set #显示系统自带的所有变量和函数

set -- #清空所有位置变量

unset

  • 删除变量
  • 删除只读变量只需退出终端即可
unset VARNAME [VARNAME...] #删除变量不用加$

env

  • 打印所有的环境变量(全局变量)

printenv

  • 打印所有的环境变量(全局变量)

export

export #显示所有的环境变量(全局变量)、声明环境变量

#范例
#不加export,变量不能被子进程所继承,即非环境变量
[root@dubbo-provider ~]# AAA=bbb
[root@dubbo-provider ~]# echo $AAA
bbb
[root@dubbo-provider ~]# bash
[root@dubbo-provider ~]# echo $AAA
    #无内容
#加export,变量可以被子进程所继承,即被export声明成环境变量了
[root@dubbo-provider ~]# echo $AAA
bbb
[root@dubbo-provider ~]# export AAA
[root@dubbo-provider ~]# bash
[root@dubbo-provider ~]# echo $AAA
bbb #可被继承

readonly

  • 只读变量管理
readonly VAR_NAME=VALUE #设置只读变量

readonly [-p] #查看只读变量

declare

  • 只读变量管理
declare -r VAR_NAME=VALUE #设置只读变量

declare  -r #查看只读变量

变量高级用法

  • 示例变量
## echo $AAA
2022-08-28

## echo $BBB
/usr/local/src/
  • 取变量左边的字段
  • 语法:
    • ${变量名%匹配规则} 从变量尾部进行规则匹配,将符合最短的数据删除
    • ${变量名%%匹配规则} 从变量尾部进行规则匹配,将符合最长的数据删除
## echo ${AAA%-*}
2022-08

## echo ${AAA%%-*}
2022

## echo ${BBB%/*}
/usr/local/src

## echo ${BBB%%/*}
空值
  • 取变量右边的字段
  • 语法:
    • ${变量名#匹配规则} 从变量开头进行规则匹配,将符合最短的数据删除
    • ${变量名##匹配规则} 从变量开头进行规则匹配,将符合最长的数据删除
## echo ${AAA#*-}
08-28

## echo ${AAA##*-}
28

## echo ${BBB#*/}
usr/local/src

## echo ${BBB##*/}
空值
  • 如果变量未赋值,则输出其它字符
## 如果之前没有给var这个变量赋值,则输出10
${var:-10}
  • 其它只显示部分变量的方法
${var: -10} #输出var这个变量中的最后十个字符


#显示变量后几位的内容
aaa=史蒂芬周星驰
echo ${aaa:3:3} #第一个3表示变量数值的位置 从左到右 并且这里的3是从0开始 所以是第4,第二个3表示显示几个字符
周星驰
  • 如果变量未赋值,则显示定义的内容;如果变量被赋值,则显示赋值的内容;
## echo ${HOSTNAME:-xiangzheng.com}
xiangzheng.com

## HOSTNAME=azheng.com

## echo ${HOSTNAME:-xiangzheng.com}
azheng.com
user  nginx;
worker_processes  ${WORK_PROC:-auto};

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

获取分隔符左右两边的子串

在Bash shell中,您可以使用字符串操作来提取变量中的子字符串。对于给定的变量 $a,您可以使用以下方法来分别获取 www.torhub.com/zqf_clientv2

a="www.torhub.com/zqf_client-v2"

## 提取 www.torhub.com/zqf_client
part1="${a%-*}"
echo "$part1"  # 输出: www.torhub.com/zqf_client

## 提取 v2
part2="${a##*-}"
echo "$part2"  # 输出: v2

在上面的示例中,${a%-*} 表示从变量 $a 的末尾开始删除匹配的最短字符串,这里是 - 及其之后的内容。${a##*-} 表示从变量 $a 的开头开始删除匹配的最长字符串,这里是 - 及其之前的内容。这样就能够分别提取出所需的子字符串。

docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/zqf_guard:v2
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/zqf_rp:v2
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/sncli:v1
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/cfshs:v1
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/sniper_client:v1
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/zqf_producer:v1
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/zrmmysql:v1
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/zqf_modify_rp:zqf_modify_rp
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/zqf_modify_hs:zqf_modify_hs
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/zqf_modify_guard:zqf_modify_guard
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/zqf_modify_producer:zqf_modify_producer
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/zqf_modify_cient:zqf_modify_client
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/zqf:producer
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/zrm:zrm
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/snow_probe:1.0
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/snow_stun:1.0
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/snow_proxy:1.0
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/snow_broker:1.0
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/snser:v1
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/snow_server:1.0
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/wfpc:k82
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/wfphs:v3
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/tor_exit:4.4.6
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/tor_relay:4.4.6
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/tor_exit:4.6.8
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/tor_relay:4.6.8
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/tor_exit:4.6.9
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/tor_relay:4.6.9
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/tor_da:4.6.10
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/tor_exit:4.3
docker rmi 172.16.0.120:30002/darknet-target/www.torhub.com/tor_relay:4.3

tag

docker tag SOURCE_IMAGE[:TAG] 172.16.0.120:30002/darknet-target/REPOSITORY[:TAG]




docker tag www.torhub.com/zqf_client:v2 172.16.0.120:30002/darknet-target/zqf_client:v2


docker tag www.torhub.com/zqf_hs:v2
docker tag www.torhub.com/zqf_guard:v2
docker tag www.torhub.com/zqf_rp:v2
docker tag www.torhub.com/sncli:v1
docker tag www.torhub.com/cfshs:v1
docker tag www.torhub.com/sniper_client:v1
docker tag www.torhub.com/zqf_producer:v1
docker tag www.torhub.com/zrmmysql:v1
docker tag www.torhub.com/zqf_modify_rp:zqf_modify_rp
docker tag www.torhub.com/zqf_modify_hs:zqf_modify_hs
docker tag www.torhub.com/zqf_modify_guard:zqf_modify_guard
docker tag www.torhub.com/zqf_modify_producer:zqf_modify_producer
docker tag www.torhub.com/zqf_modify_cient:zqf_modify_client
docker tag www.torhub.com/zqf:producer
docker tag www.torhub.com/zrm:zrm
docker tag www.torhub.com/snow_probe:1.0
docker tag www.torhub.com/snow_stun:1.0
docker tag www.torhub.com/snow_proxy:1.0
docker tag www.torhub.com/snow_broker:1.0
docker tag www.torhub.com/snser:v1
docker tag www.torhub.com/snow_server:1.0
docker tag www.torhub.com/wfpc:k82
docker tag www.torhub.com/wfphs:v3
docker tag www.torhub.com/tor_exit:4.4.6
docker tag www.torhub.com/tor_relay:4.4.6
docker tag www.torhub.com/tor_exit:4.6.8
docker tag www.torhub.com/tor_relay:4.6.8
docker tag www.torhub.com/tor_exit:4.6.9
docker tag www.torhub.com/tor_relay:4.6.9
docker tag www.torhub.com/tor_da:4.6.10
docker tag www.torhub.com/tor_exit:4.3
docker tag www.torhub.com/tor_relay:4.3
docker tag www.torhub.com/tor_da:4.3

push

docker push 172.16.0.120:30002/darknet-target/REPOSITORY[:TAG]