操作符与相关主题

操作符

赋值

变量赋值,初始化或者修改变量的值

=

通用赋值操作符,可用于算术和字符串赋值。

var=12
car=bmw # 在=号后面不能出现空白字符的

不要混淆=赋值操作符与=测试操作符

# = 在这里是测试操作符
if [ "$string1" = "$string2" ]
# if [ "X$string1" = "X$string2" ] 是一种更安全的做法,
# 这样可以防止两个变量中的一个为空所产生的错误.
# (字符"X"作为前缀在等式两边是可以相互抵消的.)
thencommand
fi

算术操作符
+
加法计算

-
减法计算

*
乘法计算

/
除法计算

**

幂运算

 # 在Bash, 版本2.02, 中开始引入了"**" 幂运算符.let "z=5**3"
echo "z = $z"
# z = 125

%

模运算,或者说是求余运算

求最大公约数

#!/bin/bash
# gcd.sh: 最大公约数
#使用Euclid的算法# 两个整数的"最大公约数" (gcd),
#+ 就是两个整数所能够同时整除的最大的数.# Euclid算法采用连续除法.
# 在每一次循环中,
#+ 被除数 <--- 除数
#+ 除数 <--- 余数
#+ 直到 余数 = 0.
#+ 在最后一次循环中, gcd = 被除数.
#
# 关于Euclid算法的更精彩的讨论, 可以到
#+ Jim Loy的站点, http://www.jimloy.com/number/euclids.htm.# ------------------------------------------------------
# 参数检查
ARGS=2
E_BADARGS=65if [ $# -ne "$ARGS" ]
thenecho "Usage: `basename $0` first-number second-number"exit $E_BADARGS
fi
# ------------------------------------------------------gcd ()
{dividend=$1
# 随意赋值.divisor=$2
#+ 在这里, 哪个值给的大都没关系.
# 为什么没关系?remainder=1
# 如果在循环中使用了未初始化的变量,
#+ 那么在第一次循环中,
#+ 它将会产生一个错误消息.until [ "$remainder" -eq 0 ]do
let "remainder = $dividend % $divisor"
dividend=$divisor
# 现在使用两个最小的数来重复.
divisor=$remainderdone
# Euclid的算法
}
# Last $dividend is the gcd.
gcd $1 $2
echo; echo "GCD of $1 and $2 = $dividend"; echo
# Exercise :
# --------
# 检查传递进来的命令行参数来确保它们都是整数.
#+ 如果不是整数, 那就给出一个适当的错误消息并退出脚本.
exit 0

执行结果

andrew@andrew:/work/bash/src$ bash gcd.sh  2345 56GCD of 2345 and 56 = 7

+=
“加-等于” (把变量的值增加一个常量然后再把结果赋给变量)let "var += 5" var 变量的值会在原来的基础上加 5 .

-=

“减-等于” (把变量的值减去一个常量然后再把结果赋给变量)

*=
“乘-等于” (先把变量的值乘以一个常量的值, 然后再把结果赋给变量)
let "var *= 4" var 变量的结果将会在原来的基础上乘以 4 .

/=
“除-等于” (先把变量的值除以一个常量的值, 然后再把结果赋给变量)

%=
“取模-等于” (先对变量进行模运算, 即除以一个常量取模, 然后把结果赋给变量)
算术操作符经常会出现在 exprlet表达式中.

使用算术操作符

#!/bin/bash
# 使用10种不同的方法计数到11.
n=1; echo -n "$n "let "n = $n + 1"
# let "n = n + 1" 也可以.
echo -n "$n ": $((n = $n + 1))
# ":" 是必需的, 因为如果没有":"的话,
#+ Bash将会尝试把"$((n = $n + 1))"解释为一个命令.
echo -n "$n "(( n = n + 1 ))
# 上边这句是一种更简单方法.
# 感谢, David Lombard, 指出这点.
echo -n "$n "n=$(($n + 1))
echo -n "$n ": $[ n = $n + 1 ]
# ":" 是必需的, 因为如果没有":"的话,
#+ Bash将会尝试把"$[ n = $n + 1 ]"解释为一个命令.
# 即使"n"被初始化为字符串, 这句也能够正常运行.
echo -n "$n "n=$[ $n + 1 ]
# 即使"n"被初始化为字符串, 这句也能够正常运行.
#* 应该尽量避免使用这种类型的结构, 因为它已经被废弃了, 而且不具可移植性.
echo -n "$n "  # echo输出时不输出最后的回车
# 现在来一个C风格的增量操作.let "n++"
# let "++n" 也可以.
echo -n "$n "(( n++ ))
# (( ++n ) 也可以.
echo -n "$n ": $(( n++ ))
# : $(( ++n )) 也可以.
echo -n "$n ": $[ n++ ]
# : $[ ++n ]] 也可以.
echo -n "$n "
echo
exit 0

执行结果

andrew@andrew:/work/bash/src$ bash algroth.sh
1 2 3 4 5 6 7 8 9 10 11

在bash中的整型变量事实上是一个有符号的long(32-bit)整型值,所表示的范围是-2147483648到2147483647。如果超过这个范围进行算术操作的话,那么将不会得到你期望的结果。

bash中不能直接进行浮点型计算,要是需要进行浮点型计算,需要在脚本中使用bc,这个命令可以进行浮点型运算,或者调用数学库函数

位操作符

<<

左移一位

<<=

“左移-赋值”
let "var <<= 2"
这句的结果就是变量 var 左移 2 位(就是乘以 4 )

>>

右移一位

>>=

右移-赋值

&
按位与

&=
“按位与-赋值”

|
按位或

|=
“按位或-赋值”

~
按位反

!

按位非

^
按位异或XOR

^=
“按位异或-赋值”

逻辑操作符

&&
与(逻辑)

if [ $condition1 ] && [ $condition2 ]
# 与 if [ $condition1 -a $condition2 ] 相同
# 如果condition1和condition2都为true, 那结果就为true.if [[ $condition1 && $condition2 ]] #也可以
## 注意 && 符号不允许出现在[...]中

||
或(逻辑)

if [ $condition1 ] || [ $condition2 ]
# 与 if [ $condition1 -o $condition2 ] 相同
# 如果condition1或condition2中的一个为true, 那么结果就为true.if [[ $condition1 || $condition2 ]]
# 也可以.
# 注意||操作符是不能够出现在[ ... ]结构中的.

使用&& 和 || 进行混合条件测试

#!/bin/basha=24
b=47# 如果a==24 并且b==47 则条件成立
if [ "$a" -eq 24 ] && [ "$b" -eq 47 ]
thenecho "Test #1 succeeds."
elseecho "Test #1 fails."
fi# ERROR: 在单括号中不能使用 && 但是在双括号中能使用
if [ "$a" -eq 24 && "$b" -eq 47 ]
#+尝试运行' [ "$a" -eq 24 '
#+因为没找到匹配的']'所以失败了.
#
# 注意: if [[ $a -eq 24 && $b -eq 24 ]] 也能正常运行.
# 双中括号的if-test结构要比
#+ 单中括号的if-test结构更加灵活.
#(在第17行"&&"与第6行的"&&"具有不同的含义.)if [ "$a" -eq 98 ] || [ "$b" -eq 47 ]
thenecho "Test #2 succeeds."
elseecho "Test #2 fails."
fi# -a和-o选项提供了
#+ 一种可选的混合条件测试的方法.if [ "$a" -eq 24 -a "$b" -eq 47 ]
thenecho "Test #3 succeeds."
elseecho "Test #3 fails."
fiif [ "$a" -eq 98 -o "$b" -eq 47 ]
thenecho "Test #4 succeeds."
elseecho "Test #4 fails."
fia=rhino
b=crocodile
if [ "$a" = rhino ] && [ "$b" = crocodile ]
thenecho "Test #5 succeeds."
elseecho "Test #5 fails."
fiexit 0

使用shellcheck工具对该脚本进行检测

andrew@andrew:/work/bash/src$ shellcheck if_else.sh In if_else.sh line 15:
if [ "$a" -eq 24 && "$b" -eq 47 ]
^-- SC1073: Couldn't parse this if expression.In if_else.sh line 57:
exit 0^-- SC1050: Expected 'then'.^-- SC1072: Expected 'then'.. Fix any mentioned problems and try again.

提示脚本的第15行出现问题,看脚本的第15行会发现

if [ "$a" -eq 24 && "$b" -eq 47 ]脚本在单括号中使用了&&

&&和||操作符也可以用在算术上下文中.

andrew@andrew:~$ echo $(( 1 && 2 )) $((3 && 0)) $((4 || 0)) $((0 || 0))
1 0 1 0

,

,号操作符,逗号操作符可以链接两个或多个算术运算,所有的操作都会被运行,但是只会返回最后的操作的结果

let "t1 = ((5 + 3, 7 - 1, 15 - 4))"
echo "t1 = $t1"   # t1 = 11
let "t2 = ((a = 9, 15 / 3))" # 设置"a"并且计算"t2".
echo "t2 = $t2 a = $a"# t2 = 5 a = 9

数字常量

shell脚本在默认情况下,都是把数字作为10进制来处理,除非这个数字采用了特殊的标记或者前缀。如果数字以0开头的话那么就是8进制,如果数字以0x开头的话那么就是16进制数,如果数字中间嵌入了#的话,那么就被认为是BASE#NUMBER形式的标记法。

数字常量表示法

#!/bin/bash
# numbers.sh: 几种不同数制的数字表示法.# 10进制: 默认情况
let "dec = 32"
echo "decimal number = $dec"
# 32
# 这没什么特别的.# 8进制: 以'0'(零)开头
# 八进制的  32 刚好是 3*8 + 2 = 26
let "oct = 032"
echo "octal number = $oct"
# 26
# 表达式结果是用10进制表示的.
# ---------------------------# 16进制: 以'0x'或者'0X'开头的数字
# 十六进制的 0x32就是60
let "hex = 0x32"
echo "hexadecimal number = $hex"
# 50
# 表达式结果是用10进制表示的.# 其他进制: BASE#NUMBER
# BASE的范围在2到64之间.
# NUMBER的值必须使用BASE范围内的符号来表示, 具体看下边的示例.# 二进制的
let "bin = 2#111100111001101"
echo "binary number = $bin"
# 31181let "b32 = 32#77"
echo "base-32 number = $b32"
# 231let "b64 = 64#@_"
echo "base-64 number = $b64"
# 4031
# 这个表示法只能工作于受限的ASCII字符范围(2 - 64).
# 10个数字 + 26个小写字母 + 26个大写字符 + @ + _echoecho $((36#zz)) $((2#10101010)) $((16#AF16)) $((53#1aA))# 1295 170 44822 3375# 重要的注意事项:
# ---------------
# 使用一个超出给定进制的数字的话,
#+ 将会引起一个错误.let "bad_oct = 081"
# (部分的) 错误消息输出:
# bad_oct = 081: value too great for base (error token is "081")
#Octal numbers use only digits in the range 0 - 7.exit 0
andrew@andrew:/work/bash/src$
andrew@andrew:/work/bash/src$ shellcheck numbers.sh
andrew@andrew:/work/bash/src$ bash numbers.sh
decimal number = 32
octal number = 26
hexadecimal number = 50
binary number = 31181
base-32 number = 231
base-64 number = 40311295 170 44822 3375
numbers.sh: 行 56: let: bad_oct = 081: 数值太大不可为算数进制的基 (错误符号是 "081")

bash-shell高级编程--操作符与相关主题相关推荐

  1. linux shell 高级编程,shell高级编程

    条件选择if语句 选择执行: 注意:if语句可嵌套 单分支 if 判断条件;then 条件为真的分支代码 fi 双分支 if 判断条件; then 条件为真的分支代码 else条件为假的分支代码 fi ...

  2. linux脚本怎么获取参数,在Bash shell脚本编程中,如何正确无误获取到“脚本选项参数”和“脚本参数”呢?...

    Linnux 中有些命令的功能非常强大,主要是因为它支持的命令选项比较多.如:[ip]命令可以配置IP地址.路由条目的配置管理操作非常完善,该命令就可以完成[ifconfig]和[route]命令实现 ...

  3. shell高级编程笔记(第九章 变量重游)

    第三部分 超越基本 第九章 变量重游 如果变量使用恰当,将会增加脚本的能量和灵活性.但前提是这需要仔细学习变量的细节知识. 9.1 内部变量 $BASH 这个变量将指向Bash的二进制执行文件的位置 ...

  4. Bash Shell脚本编程-变量知识

    Shell:GUI  CLI 提供交互式接口:提高效率 命令行展开:~ ,{} 命令别名:alias 命令历史:history Globbing:*,?,[],[^] 命令补全:$PATH指定的目录下 ...

  5. shell高级编程笔记(第十章 循环和分支)

    第十章 循环和分支 对代码块进行操作是有组织的结构化的shell脚本的关键.为了达到这个目的,循环和分支提供帮助. 10.1 循环 循环就是重复一些命令的代码块,如果条件不满足就退出循环. for 循 ...

  6. 第二部分 Linux Shell高级编程技巧——第三章 运行级别脚本介绍

    笔记 #运行级别脚本介绍 #准备工作 #进入目录 cd /home/wgb/shell #建立文件夹 mkdir 0421 #进入目录 cd 0421#运行级别 #运行级别目录 #进入etc目录 [r ...

  7. linux bash sh,linux bash shell.sh编程实例

    1.输出 #!/bin/bash echo "Please type your number:" read a for ((i=1;i<=a;i++)) do for ((p ...

  8. shell高级编程--引用

    引用 在shell中,引用的意思就是时讲字符串使用双拥好括起来,他的作用就是保护字符串中的特殊字符.不被shell或者shell脚本重新解释,或者扩展. andrew@andrew:~$ ls -l ...

  9. 博客文件第二部分 Linux Shell高级编程技巧——第一章 深入讨论

    最近研究博客文件,稍微总结一下,以后继续补充: 道歉 由于频视出了点问题,所以临时只有这点内容,期后再补上. 条记 #录记和域 #入深探讨awk #编辑 #vi awkif.sh #转变权限 [roo ...

最新文章

  1. 什么是智能仓储?一文带你彻底搞懂!
  2. 2_vuex状态管理器
  3. java hbase创建_hadoop组件介绍及python 连接Hbase
  4. win10 uwp DataContext
  5. 【快乐水题】997. 找到小镇的法官
  6. linux下模仿用户左键,linux 鼠标左右键互换实现代码
  7. 关于Linux路由表的route命令
  8. Java NIO————NIO 简介
  9. 基于人人网的Android开发流程介绍
  10. discuz x2.5 mysql_Discuz2.5的MYSQL数据库的备份与恢复
  11. c语言主函数如何获得子函数的值,子函数中的数组值怎么带回主函数中?
  12. asp Upload
  13. USB:收录比较好的USB协议讲解
  14. tf.train.slice_input_producer(转)
  15. 《一个操作系统的实现》 ubuntu系统环境配置
  16. paypal支付开发接口(转)
  17. python查两个微博共同粉丝_Python:获取新浪微博用户的收听列表和粉丝列表
  18. 数据分析基础-假设检验原理详解
  19. 利用文心大模型制作多功能机器人
  20. 第一序列任小粟的能力_《第一序列》陈无敌刚烈正义,自封大圣,可任小粟做不得慈悲唐僧...

热门文章

  1. 为什么log4j的概念模型是错的--zlog的模型简介
  2. hdu 5617 Jam's maze(双线程dp)
  3. hdu 2686(多线程dp)
  4. Java Web中数据从前端输入到插入数据库,哪些地方需要考虑字符编码?
  5. NYOJ 752 又见回文串
  6. NYOJ 49 开心的小明
  7. NYOJ 36 最长公共子序列 dp
  8. {%csrf_token%}的作用
  9. Navicat(连接) -1之SSL 设置
  10. 编程方法学15:指针要点回顾