1. 变量设置
<variable>=<value> #为变量赋值
echo $<variable> #输出变量的值
echo ${<variable>} #输出变量的值,效果同上
unset variable #取消变量的值
- 变量与值之间以一个
=
连接 - 等号两边不能有空格
- 变量名称只能是英文字母与数字,且不能以数字开头
- 变量内容如果有空格可以使用双引号或者单引号将内容包裹起来。一般情况下,变量内容中含有变量的引用,也就是包含
$<variable>
,则用双引号包裹,一般字符则用单引号包裹。 - 可以使用转义字符“\”来使特殊符号变为一般符号。
-
假如变量内容中包含其他命令提供的信息,则需要使用以下两种形式:
-
`\ `
-
$(<command>)
-
-
若为变量增加内容时,可以使用
$(<variable>)addition
或者$<variable>addition
形式。
例如:8. `export`关键字用来设置环境变量,可以传递给当前bash和子进程。 9. 通常大写字母为系统默认变量,小写字母为自己设置的变量。例如`PATH,HOME,SHELL`等,均为系统变量。 下面写一个简单的例子来验证上面的语法: ```shell tmp="I am tmp" #*定义变量,=两边不能有空格,否则报错 echo "first type $tmp" #*"$<variable>"形式输出变量 echo "second type ${tmp}" #*"${<variable>}"另一种形式输出变量 echo 'third type ${tmp}' #*'$<variable>'不能输出变量 echo "with acutual '$' is \$tmp" #*用转义字符输出特殊字符 version=$(uname -r) #*$(command)方式获取函数的值 echo "first $version" version=`pwd` #*`command`方式获取函数的值 echo "second $version" unset version #*删除变量的值 echo "no version $version" #*不输出任何内容 tmp="${tmp} add new words" #*为tmp添加内容,注意$取变量的格式 echo $tmp #*输出添加后的内容 var="parent process var" export var #*输出变量var到子线程 echo "parent pid=?"
注释已经解释的很好了,查看输出内容:
first type I am tmp
second type I am tmp
third type ${tmp}
with acutual '$' is $tmp
first 17.4.0
second /Users/saka/Downloads/Markdown/shell命令
no version
I am tmp add new words
parent pid=19895
2. 变量的作用域
变量的作用域分为环境变量、全局变量、局部变量。
- 环境变量是系统中已经定义好的变量,输入
env
即可:
SHELL=/bin/zsh
TMPDIR=/var/folders/1x/gcpxck2s0jxbfs6qll8p0jlh0000gn/T/
Apple_PubSub_Socket_Render=/private/tmp/com.apple.launchd.X4uBMH5DE9/Render
TERM_PROGRAM_VERSION=1.20.0
ZSH=/Users/saka/.oh-my-zsh
USER=saka
COMMAND_MODE=unix2003
PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
PWD=/Users/saka/Downloads/Markdown/shell命令
LANG=zh_CN.UTF-8
XPC_FLAGS=0x0
XPC_SERVICE_NAME=0
var=parent process var
VSCODE_NODE_CACHED_DATA_DIR_18562=/Users/saka/Library/Application Support/Code/CachedData/c63189deaa8e620f650cc28792b8f5f3363f2c5b
SHLVL=30
HOME=/Users/saka
VSCODE_NLS_CONFIG={"locale":"zh-cn","availableLanguages":{"*":"zh-cn"}}
LESS=-R
这些变量都可以直接在shell脚本中获取。
- 全局变量
shell脚本,包括shell脚本中的函数中定义的变量是global的,其作用域从被定义的地方开始,到shell结束或被显示删除的地方为止。 - 局部变量
函数定义的变量可以被显示定义成local的,其作用域局限于函数内。但请注意,函数的参数是local的。如果变量同名,Shell函数定义的local变量会屏蔽脚本定义的global变量。
一个简单的例子说明:
echo "env variable SHELL=${SHELL}" #*输出环境变量SEHLL的默认值
function showshell(){ #*定义一个函数
SHELL="custom shell" #*将SHELL设置为自己需要的变量
local var="local var" #*定义函数内的局部变量
echo "function SHELL=$SHELL" #*输出SHELL,已变为自定义变量
echo "local var=${var}" #*输出局部变量,有效
}
showshell #*执行函数showshell
echo "after showshell SHELL=${SHELL}" #*输出SHELL,函数外有效
echo "local var=${var}" #*输出函数内的局部变量,无效
unset SHELL
echo "after unset SHELL=${SHELL}" #*执行unset后,变量已无值,包括环境变量
查看输出结果:
env variable SHELL=/bin/zsh
function SHELL=custom shell
local var=local var
after showshell SHELL=custom shell
local var=
after unset SHELL=
3. 对变量的操作
首先来看一张总的表:
- 变量的替换与删除
变量设置方式 | 说明 |
---|---|
${变量#关键字} | 若变量内容从头开始的数据符合“关键字”,则将符合的最短数据删除 |
$(变量##关键字) | 若变量内容从头开始的数据符合“关键字”,则将符合的最长数据删除 |
${变量%关键字} | 若变量内容从末端向前的数据符合“关键字”,则将符合的最短数据删除 |
${变量%%关键字} | 若变量内容从末端向前的数据符合“关键字”,则将符合的最长数据删除 |
${变量/旧字符串/新字符串} | 若变量内容符合“旧字符串”,则第一个旧字符串会被新字符串替换 |
${变量//旧字符串/新字符串} | 若变量内容符合“旧字符串”,则全部的旧字符串会被新字符串替换 |
path="abcdeaAbcedeA"
echo "字符*匹配任意个字符,下边是原有的值"
echo $path
echo "从开始位置匹配第一个'a',然后一直删除到第一个碰到的'de'"
echo ${path#a*de}
echo "从开始位置匹配到第一个'a',然后一直删除到最后一个碰到的'de'"
echo ${path##a*de}
echo "从末尾开始匹配到第一个'A',然后一直删除到向前寻找到的第一个'c'"
echo ${path%A*c}
echo "从末尾开始匹配到第一个'A',然后一直删除到向前寻找到的最后一个'c'"
echo ${path%%A*c}
echo "替换一个a为Z"
echo ${path/a/Z}
echo "替换所有的a为Z"
echo ${path//a/Z}
输出结果:
字符*匹配任意个字符,下边是原有的值
abcdeaAbcedeA
从开始位置匹配第一个'a',然后一直删除到第一个碰到的'de'
aAbcedeA
从开始位置匹配到第一个'a',然后一直删除到最后一个碰到的'de'
A
从末尾开始匹配到第一个'A',然后一直删除到向前寻找到的第一个'c'
abcdeaAbcedeA
从末尾开始匹配到第一个'A',然后一直删除到向前寻找到的最后一个'c'
abcdeaAbcedeA
替换一个a为Z
ZbcdeaAbcedeA
替换所有的a为Z
ZbcdeZAbcedeA
- 变量的设置
设置方式 | str没有设置 | str=”” | str有值 |
---|---|---|---|
var=${str-expr} | var=expr | var= | 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=expr var=expr |
str不变 var= |
str不变 var=$str |
var=${str:=expr} | str=expr var=expr |
str=expr var=expr |
str不变 var=$str |
var=${str?expr} | expr输出到stderr | var= | var=str |
var=${str:?expr} | expr输出到stderr | expr输出到stderr | var=str |
这个比较简单,不写测试用例。主要说明一下’-‘和’:’:
假如-前边的变量未设置值,则取后边的变量假如前边的变量已经设置值,则输出前边的变量。
假如:-一同使用,则前边的变量未设置或者值为””,则用后边的值替换前边的值,否则不替换
4. 变量的声明
- 通过用户输入设置变量的值
声明形式
read [-pt] <variable>
参数:
-p : 后面接提示的内容
-t : 后面接等待的时间,单位为秒
编写一个简单的脚本测试:
#/bin/zsh
echo "请根据下面的提示输入你想要设置的值"
read -p "var1= " var1
read -p "var2= " var2
read -p "你已经输入了所有的变量值,是否立即打印?y/n:" print
if [ ${print}x == yx ];then
echo "var1= $var1"
echo "var2= $var2"
elif [ ${print}x == nx ];then
echo "complete"
else
echo unknow command
fi
执行即可:
请根据下面的提示输入你想要设置的值
var1= 9
var2= 8
你已经输入了所有的变量值,是否立即打印?y/n:y
var1= 9
var2= 8
- declare/typeset
定义形式
declare [-aixrp] variable
参数:
-a : 将变量定义为数组类型
-i : 将变量定义为整型
-x : 将变量输出为环变量
-r : 将变量设置为只读类型(readonly),相当于java中的常量
declare -x <variable>
能将变量提升为环境变量,declare +x <varibale>
能将变量取消为环境变量。
bash中的变量假如不是用声明方式,默认都是字符串。声明后可以进行简单的操作。一个简单的例子说明:
#bin/bash
sum_one=100+10 #*直接声明,是字符串格式
echo $sum_one #*输出100+10
declare -i sum #*声明为整型
sum=100+10 #*计算结果
echo $sum #*输出为110
declare -a array #*定义数组
array[1]="a" #*定义元素1
array[2]="b" #*定义元素2
echo ${array[*]} #*输出数组
100+10
110
a b