Shell变量

系统变量

在命令行提示符直接执行 env、set 查看系统或环境变量。env 显示用户环境变量,set 显示 Shell预先定义好的变量以及用户变量。可以通过 export 导出成用户变量。

一些写Shell脚本时常用的系统变量

$SHELL  默认 Shell
$HOME 当前用户家目录
$IFS 内部字段分隔符
$LANG 默认语言
$PATH 默认可执行程序路径
$PWD 当前目录
$UID 当前用户 ID
$USER 当前用户
$HISTSIZE 历史命令大小,可通过 HISTTIMEFORMAT 变量设置命令执行时间
$RANDOM 随机生成一个 0 至 32767 的整数
$HOSTNAME 主机名
普通变量与临时环境变量

普通变量定义:VAR=value

临时环境变量定义:export VAR=value

变量引用:$VAR

下面看下他们之间区别:

Shell 进程的环境变量作用域是 Shell 进程,当 export 导入到系统变量时,则作用域是 Shell 进程及其 Shell 子进程。

Shell 进程的环境变量作用域是 Shell 进程,当 export 导入到系统变量时,则作用域是 Shell 进程及其 Shell 子进程。

ps axjf 输出的第一列是 PPID(父进程 ID),第二列是 PID(子进程 ID)当SSH 连接 Shell 时,当前终端 PPID(-bash)是 sshd 守护程序的 PID(root@pts/0),因此在当前终端下的所有进程的 PPID 都是-bash 的 PID,比如执行命令、运行脚本。

所以当在-bash 下设置的变量,只在-bash 进程下有效,而-bash 下的子进程 bash 是无效的,当export 后才有效。

进一步说明:再重新连接 SSH,去除上面定义的变量测试下所以在当前 shell 定义的变量一定要 export,否则在写脚本时,会引用不到。

还需要注意的是退出终端后,所有用户定义的变量都会清除。

在/etc/profile 下定义的变量就是这个原理.

位置变量

位置变量指的是函数或脚本后跟的第 n 个参数。

1−1−n,需要注意的是从第 10 个开始要用花括号调用,例如${10}

shift 可对位置变量控制,例如:

#!/bin/bash
echo "1: $1"
shift
echo "2: $2"
shift
echo "3: $3" sh test.sh 1 2 3
1: 1
2: 3
3:
# 每执行一次 shift 命令,位置变量个数就会减一,而变量值则提前一位。shift n,可设置向前移动n位。
特殊变量
$0  # 脚本自身名字
$? # 返回上一条命令是否执行成功,0 为执行成功,非 0 则为执行失败
$# # 位置参数总数
$* # 所有的位置参数被看做一个字符串
$@ # 每个位置参数被看做独立的字符串
$$ # 当前进程 PID
$! # 上一条运行后台进程的 PID
变量引用
赋值运算符 示例
= 变量赋值
+= 两个变量相加
自定义变量与引用
a=123
echo $a
123 a+=456
echo $a
123456 # Shell 中所有变量引用使用$符,后跟变量名 # 有时个别特殊字符会影响正常使用,就需要使用${a},例如
[root@redis ~]# b=123
[root@redis ~]# echo $b
123
[root@redis ~]# echo ${b}
123
# 有时个别特殊字符会影响正常引用,那么需要使用${VAR}
[root@redis ~]# echo $b123 [root@redis ~]# echo ${b}123
123123 # 将命令结果作为变量值
[root@redis ~]# c=`echo 123`
[root@redis ~]# echo $c
123
[root@redis ~]# c=$(echo 123)
[root@redis ~]# echo $c
123 # 这里的反撇号等效于$(),都是用于执行 Shell 命令。 # 单引号和双引号
[root@redis ~]# d=1
[root@redis ~]# d="1 2 $d"
[root@redis ~]# echo $d
1 2 1
[root@redis ~]# c=1
[root@redis ~]# c='1 2 $c'
[root@redis ~]# echo $c
1 2 $c
# 单引号是告诉 Shell 忽略特殊字符,而双引号则解释特殊符号原有的意义,比如$ 、 !。
Shell变量的输入

Shell变量除了可以直接赋值或脚本传参外,还可以使用read命令从标准输入获得,read为bash内置命令,可以通过help read查看帮助

语法格式

# read [参数] [变量名]

常用参数

# -p prompt: 设置提示信息
# -t timeout: 设置输入等待的事件,单位默认为秒

read的基本读入

如果不加-t read就会一直等待

# read后面的参数是一个变量
[root@youmen ~]# read -p 'please input you num:' num
please input you num:234
[root@youmen ~]# echo $num
234 # 设置超时事件为3秒
read -t 3 -p "please input you num:" num
please input you num:
# 过3秒钟会脚本会自己执行结束

read在脚本中常用例子

[root@youmen ~]# sh test.sh
please input you num: 1 2
1-2 =-1
1+2 =3
1*2 =2
1/2 =0
1**2 =1
1%2 =1
[root@youmen ~]# cat abc.sh
#!/bin/bash
read -t 18 -p "please input you num:" a b
echo "$a-$b =$(( $a - $b ))"
echo "$a+$b =$(( $a + $b ))"
echo "$a*$b =$(( $a * $b ))"
echo "$a/$b =$(( $a / $b ))"
echo "$a**$b =$(( $a ** $b ))"
echo "$a%$b =$(( $a % $b ))" # 利用echo 命令替代和read -p的功能
[root@youmen ~]# cat test.sh
#!/bin/bash
echo -n "请输入两个数字:"
read a b
echo "$a+$b =$(( $a + $b ))"
echo "$a*$b =$(( $a * $b ))"
echo "$a/$b =$(( $a / $b ))"
echo "$a**$b =$(( $a ** $b ))"
echo "$a%$b =$(( $a % $b ))" [root@youmen ~]# bash test.sh
请输入两个数字:2 3
2+3 =5
2*3 =6
2/3 =0
2**3 =8
2%3 =2

条件测试与比较

介绍

在bash的各种流程控制结构中通常要进行各种测试,然后根据测试结果执行不同的操作,有时也会通过与if等条件语句相结合,更方便的完成判断

条件测试通常由如下3种语法形式

# 语法1:test<测试表达式>
# 语法2:[<测试表达式>]
# 语法3:[[<测试表达式>]] # 说明
# 1.上述语法格式1和语法格式2的写法是相等的。语法格式3为扩展的test命令。推荐使用语法格式2. # 2.在[[]]中可以使用通配符进行模式匹配。&&、||、>、<等操作可以应用于[[]]中,但不能应用于[]中. # 3.对于整数的关系运算,也可以使用Shell的算术运算符(())
test测试表达式
# 判断是不是文件
[root@youmen ~]# test -f /etc/hosts
[root@youmen ~]# echo $?
0
[root@youmen ~]# test -f /etc/hostss
[root@youmen ~]# echo $?
1 # 判断文件是否可以执行
[root@youmen ~]# test -x /usr/bin/ssh
[root@youmen ~]# echo $?
0
[root@youmen ~]# test -x /etc/hosts
[root@youmen ~]# echo $?
1 # 判断是不是目录
[root@youmen ~]# test -d /etc/
[root@youmen ~]# echo $?
0
[root@youmen ~]# test -d /etc/hosts
[root@youmen ~]# echo $?
1
[]中括号表达式
# 判断是不是普通文件
[root@youmen ~]# [ -f /etc/hosts ]
[root@youmen ~]# echo $?
0
[root@youmen ~]# [ -f /etc/hostss ]
[root@youmen ~]# echo $?
1 # 判断是否是目录
[root@youmen ~]# [ -d /etc/hosts ]
[root@youmen ~]# echo $?
1
[root@youmen ~]# [ -d /etc/ ]
[root@youmen ~]# echo $?
0 # 判断是否可被执行
[root@youmen ~]# [ -x /etc/hosts ]
[root@youmen ~]# echo $?
1
[root@youmen ~]# [ -x /usr/bin/ssh ]
[root@youmen ~]# echo $?
0
[[双括号表达式]]
[root@youmen ~]# [[ -x /etc/hosts ]]
[root@youmen ~]# echo $?
1
[root@youmen ~]# [[ -x /usr/bin/ssh ]]
[root@youmen ~]# echo $?
0 # [[]] 和[]一样
# 区别是可以在多括号里面添加多个判断
# 例如判断是不是目录,并判断下一个文件是不是可执行
[root@youmen ~]# [[ -d /etc/ && -x /usr/bin/ssh ]]
[root@youmen ~]# echo $?
0
[root@youmen ~]# [[ -d /etc/ && -x /usr/bin/sshdd ]]
[root@youmen ~]# echo $?
1 # &&只在双括号里面有效,如果单括号里面需要使用-a,-o
文件测试表达式
操作符 说明 举例

# -b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。

# -c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ] 返回 false。

# -d file 检测文件是否是目录,如果是,则返回 true。 [ -d $file ] 返回 false。

# -f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 [ -f $file ] 返回 true。 

# -g file 检测文件是否设置了 SGID 位,如果是,则返回 true。 [ -g $file ] 返回 false。 

# -k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 [ -k $file ] 返回 false。 

# -p file 检测文件是否是具名管道,如果是,则返回 true。 [ -p $file ] 返回 false。

# -u file 检测文件是否设置了 SUID 位,如果是,则返回 true。 [ -u $file ] 返回 false。

# -r file 检测文件是否可读,如果是,则返回 true。 [ -r $file ] 返回 true。

# -w file 检测文件是否可写,如果是,则返回 true。 [ -w $file ] 返回 true。

# -x file 检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true。

# -s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true。

# -e file 检测文件(包括目录)是否存在,如果是,则返回 true。 [ -e $file ] 返回 true。

# 特别说明:这些操作符号对于[[]]、[]、test几乎都是通用的,

字符串表达式

字符串测试操作符的作用有:比较两个字符串是否相同、字符串的长度是否为零,字符串是否为NULL(注:bash区分零长度字符串和空字符串)等

常用字符串测试操作符 说明 -z “字符串” 若串长度为0则真,-z可以理解为zero -n ”字符串“ 若昂度不为0则真,-n 可以理解为no zero ”串1“ = ”串2“

若串1等于串2则真,可以使用”==“代替”=“

“串2” != “串2”

若串1不等于串2则真,不能用“!==“ 代替”!=“ 特别注意:

# 1. 以上表格中的字符串测试操作符号务必要用”“引起来。
# 2.比较符号两端有空格

字符串测试操作符提示

# 1)-n 比较字符串长度是否不为零,如果不为零则为真,如:[ -n “$myvar” ]

# 2)-z 比较字符串长度是否等于零,如果等于零则为真,如:[ -z “$myvar” ]

# 特别注意
# 对于以上表格中的字符串测试操作符号,如[ -n “$myvar” ],要把字符串用“”引起来。 # 1、字符串或字符串变量比较都要加双引号之后再比较。 # 2、字符串或字符串变量比较,比较符号两端最好都有空格,可以参考系统脚本 # “=”比较两个字符串是否相同,与“==”等价,如[ “$a” = “$b” ]其中$a这样的变量最好用“”括起来,因为如果中间由空格,*等符号就可能出错,更好的办法就是[ “${a}” = “${b}” ] # “!=” 比较两个字符串是否相同,不同则为“是”

逻辑操作符

在[]和test中使用 在[[]]中使用 说明 -a && and与,两端都为真,则真 -o || or或,两端有一个为真则真 ! ! not非,相反则为真

# !中文意思是反:与一个逻辑值相关的逻辑值

# -a 中文意思是(and|&&):两个逻辑值都为“真”,返回值才为“真”,反之为“假”

# -o 中文意思是或(or| ||):两个逻辑值只要有一个为“真”,返回值就为“真”

# 逻辑操作运算规则
# -a和&& 的运算规则:只有两端都是1才为真
# 要想使用&&注意双括号

Shell流程控制

If

if 语句语法格式

if condition
then
command1
command2
...
commandN
fi # 写成一行
if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi
If else

if else语法格式

if condition
then
command1
command2
...
commandN
else
command
fi
if else-if else

if else-if else语法格式

if condition1
then
command1
elif condition2
then
command2
else
commandN
fi

实例

a=10
b=20
if [ $a == $b ]
then
echo "a 等于 b"
elif [ $a -gt $b ]
then
echo "a 大于 b"
elif [ $a -lt $b ]
then
echo "a 小于 b"
else
echo "没有符合的条件"
fi # a 小于 b

if else语句经常与test命令结合使用,如下所示

num1=$[2*3]
num2=$[1+5]
if test $[num1] -eq $[num2]
then
echo '两个数字相等!'
else
echo '两个数字不相等!'
fi # 输出结果
# 两个数字相等!

循环

for

语法格式

for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done # 写成一行
for var in item1 item2 ... itemN; do command1; command2… done; # 当变量值在列表里,for循环即执行一次所有命令,使用变量名获取列表中的当前取值。
# 命令可为任何有效的shell命令和语句。in列表可以包含替换、字符串和文件名。
# in列表是可选的,如果不用它,for循环使用命令行的位置参数。
# 顺序输出当前列表中的数字 for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done # 输出
The value is: 1
The value is: 2
The value is: 3
The value is: 4
The value is: 5 # 顺序输出字符串中的字符
for str in 'This is a string'
do
echo $str
done
# 输出结果
This is a string
While

while循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。其格式为:

while condition
do
command
done

一下是一个基本的while循环,测试条件是,如果int小于等于5,那么条件返回真。int从0开始,每次循环处理时,int加1。运行上述脚本,返回数字1到5,然后终止。

#!/bin/bash
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done # 输出
1
2
3
4
5 # 以上实例使用了 Bash let 命令,它用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量
# while循环可用于读取键盘信息。下面的例子中,输入信息被设置为变量FILM,按<Ctrl-D>结束循环 echo '按下 <CTRL-D> 退出'
echo -n '输入你最喜欢的网站名: '
while read FILM
do
echo "是的!$FILM 是一个好网站"
done # 运行脚本,输出类似下面
按下 <CTRL-D> 退出
输入你最喜欢的网站名: youmeblog
是的!youmenblog 是一个好博客
无限循环

无限循环语法格式

while :
do
command
done # or
while true
do
command
done # or
for (( ; ;))
until循环

until 循环执行一系列命令直至条件为 true 时停止。

until 循环与 while 循环在处理方式上刚好相反。

一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。

until 语法格式

until condition
do
command
done

condition 一般为条件表达式,如果返回值为 false,则继续执行循环体内的语句,否则跳出循环。

以下实例我们使用 until 命令来输出 0 ~ 9 的数字:

#!/bin/bash

a=0

until [ ! $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done # 运行结果
0
1
2
3
4
5
6
7
8
9
case

Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。case语句格式如下:

case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac

case工作方式如上所示。取值后面必须为单词in,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。

取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。

下面的脚本提示输入1到4,与每一种模式进行匹配:

echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
1) echo '你选择了 1'
;;
2) echo '你选择了 2'
;;
3) echo '你选择了 3'
;;
4) echo '你选择了 4'
;;
*) echo '你没有输入 1 到 4 之间的数字'
;;
esac # 输入不同的内容,会有不同的结果,例如:
输入 1 到 4 之间的数字:
你输入的数字为:
3
你选择了 3
break

break命令允许跳出所有循环(终止执行后面的所有循环)

下面的例子中,脚本进入死循环直至用户输入数字大于5。要跳出这个循环,返回到shell提示符下,需要使用break命令

#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字:"
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
break
;;
esac
done # 执行以上代码,输出结果为
输入 1 到 5 之间的数字:3
你输入的数字为 3!
输入 1 到 5 之间的数字:7
你输入的数字不是 1 到 5 之间的! 游戏结束
continue

continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。对上面的例子进行修改:

#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字: "
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的!"
continue
echo "游戏结束"
;;
esac
done
Case..esac

case ... esac 与其他语言中的 switch ... case 语句类似,是一种多分枝选择结构,每个 case 分支用右圆括号开始,用两个分号 ;; 表示 break,即执行结束,跳出整个 case ... esac 语句,esac(就是 case 反过来)作为结束标记。

case ... esac 语法格式如下

case 值 in
模式1)
command1
command2
command3
;;
模式2)
command1
command2
command3
;;
*)
command1
command2
command3
;;
esac # case后为取值,值可以为变量或常数
# 值后为关键字 in,接下来是匹配的各种模式,每一模式最后必须以右括号结束,模式支持正则表达式。 #!/bin/sh site="runoob" case "$site" in
"runoob") echo "youmen博客"
;;
"google") echo "Google 搜索"
;;
"taobao") echo "淘宝网"
;;
esac

02 . Shell变量和逻辑判断及循环使用的更多相关文章

  1. LINUX SHELL 笔记 02: 变量初识

    https://www.shellscript.sh/variables1.html 变量是一个可操作(读.写)的内存块的名字. 尝试-1 创建一个变量: root@iZwz:~/labs# sh m ...

  2. shell变量详解

    1 shell变量基础 shell变量是一种很"弱"的变量,默认情况下,一个变量保存一个串,shell不关心这个串是什么含义.所以若要进行数学运算,必须使用一些命令例如let.de ...

  3. Shell入门教程:Shell变量

    变量 是一种很“弱”的变量,默认情况下,一个变量保存一个串,Shell不关心这个串是什么含义.所以若要进行数学运算,必须使用一些命令例如 let.declare.expr.双括号等. Shell变量可 ...

  4. shell变量的替换

    1 shell变量基础shell变量是一种很“弱”的变量,默认情况下,一个变量保存一个串,shell不关心这个串是什么含义.所以若要进行数学运算,必须使用一些命令例如let.declare.expr. ...

  5. centos shell脚本编程1 正则 shell脚本结构 read命令 date命令的用法 shell中的逻辑判断 if 判断文件、目录属性 shell数组简单用法 $( ) 和${ } 和$(( )) 与 sh -n sh -x sh -v 第三十五节课

    centos   shell脚本编程1 正则  shell脚本结构  read命令  date命令的用法  shell中的逻辑判断  if 判断文件.目录属性  shell数组简单用法 $( ) 和$ ...

  6. [Z]shell变量详解

    原文:http://www.cnblogs.com/barrychiao/archive/2012/10/22/2733210.html 1 shell变量基础shell变量是一种很“弱”的变量,默认 ...

  7. Shell变量概述

    目录 1. Shell变量概述 1.定义变量,变量名=变量值.不能出现"-横杠"命令 2.引用变量,$变量名 3.查看变量,set显示所有变量,包括自定义变量和环境变量 4.取消变 ...

  8. shell 编程 && bash 简介(shell 变量、shell操作环境、数据流重导向、管线命令、shell script)

    如何学习一门编程语言 数据类型 运算符 关键字 1 认识BASH 这个shell linux是操作系统核心,用户通过shell与核心进行沟通,达到我们想要的目的.硬件.核心.用户之间的关系: 原理:所 ...

  9. shell(shell变量、条件表达式、流程控制)

    本章内容: 变量 运算 if语句 for语句 while语句 break.continue 实例 shell变量 1.shell变量简介 变量是任何一种编程语言都必不可少的组成部分,变量用来存放各种数 ...

随机推荐

  1. Linux (三) 基础命令 上

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一 . 背景知识 1. Linux系统中一切皆文件 在Linux系统中任何东西都是以文件形式来存储的.这 ...

  2. 初学者对Git的使用安装教程,以及对unknown key type -rsa的解决办法

    第一次使用Git,诚惶诚恐. Git在每个电脑上第一次使用必须要配置环境,才能通过SSH秘钥的方式安全稳定的拉取代码! 此文适合对Git一无所知的小白观看,大神勿扰.下面我将讲解一个傻瓜式的Git安装 ...

  3. Java实现蓝桥杯第八届决赛 对局匹配

    标题:对局匹配 小明喜欢在一个围棋网站上找别人在线对弈.这个网站上所有注册用户都有一个积分,代表他的围棋水平. 小明发现网站的自动对局系统在匹配对手时,只会将积分差恰好是K的两名用户匹配在一起.如果两 ...

  4. Java实现 LeetCode 386 字典序排数

    386. 字典序排数 给定一个整数 n, 返回从 1 到 n 的字典顺序. 例如, 给定 n =1 3,返回 [1,10,11,12,13,2,3,4,5,6,7,8,9] . 请尽可能的优化算法的时 ...

  5. Java实现 蓝桥杯VIP 算法提高 阶乘差

    问题描述 给定n和m以及p,保证n>=m,求(n!-m!)对p取余的结果. 输入格式 一行三个正整数n,m,p. 输出格式 一行一个非负整数表示结果. 样例输入 3 2 10 样例输出 4 数据 ...

  6. Java实现信用卡校验

    当你输入信用卡号码的时候,有没有担心输错了而造成损失呢?其实可以不必这么担心,因为并不是一个随便的信用卡号码都是合法的,它必须通过Luhn算法来验证通过. 该校验的过程: 1.从卡号最后一位数字开始, ...

  7. java实现填写算式

    ** 填写算式** 看这个算式: ☆☆☆ + ☆☆☆ = ☆☆☆ 如果每个五角星代表 1 ~ 9 的不同的数字. 这个算式有多少种可能的正确填写方法? 173 + 286 = 459 295 + 17 ...

  8. 01-Python初体验

    本节内容 Python介绍 发展史 Python 2 or 3? 安装 Hello World程序 变量 用户输入 模块初识 .pyc是个什么鬼? 数据类型初识 数据运算 表达式if ...else语 ...

  9. ODEINT 求解常微分方程(1)

    An example of using ODEINT is with the following differential equation with parameter k=0.3, the ini ...

  10. filter()函数过滤序列

    ''' Python内建的filter()函数用于过滤序列. 和map()类似,filter()也接收一个函数和一个序列.和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据 ...