shell编程:变量知识进阶(三)
1 Shell特殊位置变量
范例1:$n的实践例子
[root@luoahong ~]# echo \${1..15} $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 [root@luoahong ~]# echo \${1..15} >n.sh [root@luoahong ~]# cat n.sh $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 [root@luoahong ~]# echo {a..z} a b c d e f g h i j k l m n o p q r s t u v w x y z [root@luoahong ~]# cat n.sh $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 [root@luoahong ~]# sh n.sh {a..z} n.sh: line 1: a: command not found [root@luoahong ~]# cat n.sh echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15} [root@luoahong ~]# sh n.sh {a..z} a b c d e f g h i j k l m n o
数字大于9,必须给数字加大括号才能输出正确内容
位置参数的系统生产场景案例
在生产场景中,执行/etc/init.d/rpcbind start之后,rpcbind脚本后携带的start参数会传给脚本里的"$1"
进行判断,脚本中传递参数的关键case语句节选如下:
case "$1" in #这里的用于$1接收执行此脚本命令的第一个参数,规范用法是用双引号引起来 start) #如果$1接收的值匹配start,则执行下文的start函数及内容的指令 start #调用脚本中的start函数 RETVAL=$? #这里是记录函数执行的返回值,$?也是重要的变量,暂时可以忽略,后面有介绍 ;; stop) #如果$1接收的值匹配stop,则执行下文的stop函数及内容的指令 stop RETVAL=$? ;; status) #如果$1接收的值匹配status,则执行下文的status函数及内容的指令 status $prog RETVAL=$? ;; restart | reload| force-reload) stop start RETVAL=$? ;; .....省略部分内容
$0案例
tail -6 /etc/init.d/rpcbind echo $"Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart|try-restart}" #如果$0基本生产场景就是,当用户的输入不符合脚本的要求时,就打印脚本的名字及使用帮助 RETVAL=2 ;; esac exit $RETVAL [root@luoahong ~]#/etc/init.d/rpcbind Usage: /etc/init.d/rpcbind {start|stop|status|restart|reload|force-reload|condrestart|try-restart}
#上文/etc/init.d/rpcbind就是$0从脚本命令行获取的值,当用户输入不符合脚本设定的要求时,就打印脚本的名字及使用帮助
例子:$#
[root@luoahong ~]# cat q.sh echo $1 $2 $3 $4 $5 $6 $7 $8 $9 echo $# [root@luoahong ~]# sh q.sh {a..z} a b c d e f g h i #只接收了9个变量,所以打印9个字符 26 #传入26个字符作为26个参数,因此这里的数字为26,说明传入了26个参数
范例:根据用户在命令行的传参个数判断用户的输入,不合要求的给予提示并退出
[root@luoahong ~]# cat t1.sh [ $# -ne 2 ] && { echo "muse two args" exit 1 } echo luoahong [root@luoahong ~]# sh t1.sh muse two args [root@luoahong ~]# sh t1.sh arg1 arg2 luoahong
然后是if判断语句的写法,如下:
[root@luoahong ~]# cat t2.sh if [ $# -ne 2 ] then echo " USAGE:/bin/sh $0 arg1 arg2" exit 1 fi echo $1 $2 [root@luoahong ~]# sh t2.sh USAGE:/bin/sh t2.sh arg1 arg2 [root@luoahong ~]# sh t2.sh luoahong tyx luoahong tyx
$*和$@区别
范例:利用set设置位置参数(同命令行脚本的传参)
[root@luoahong ~]# set -- "luoahong hong" wo bushi luoahong #设置三个字符串参数"--" 表示清除所有的参数变量,重新设置后面的参数变量 [root@luoahong ~]# echo $# 4 [root@luoahong ~]# echo $1 luoahong hong [root@luoahong ~]# echo $2 wo [root@luoahong ~]# echo $3 bushi [root@luoahong ~]# echo $4 luoahong
测试$*和$@,注意此时不带双引号:
[root@luoahong ~]# echo $* luoahong hong wo bushi luoahong [root@luoahong ~]# echo $@ luoahong hong wo bushi luoahong
测试$*和$@,注意此时带双引号:
[root@luoahong ~]# echo "$@" luoahong hong wo bushi luoahong [root@luoahong ~]# echo "$*" luoahong hong wo bushi luoahong 这才真正符合我们传入的参数需求 [root@luoahong ~]# for i in "$*";do echo $i;done luoahong hong wo bushi luoahong #在有双引号的情况,参数里引号中的内容当作一个参数输出了! [root@luoahong ~]# for i in "$@";do echo $i;done #有双引号的时候,每个参数均以独立的内容输出 luoahong hong #有双引号算一个参数 wo bushi luoahong
#在有双引号的情况,参数里引号中的内容当作一个参数输出了!
Shell进程状态变量
提示:查找知道方法:man bash
,然后搜索Special Parameters.
$?实例
范例:执行命令后获取返回值(切换到oldboy永固下进行测试)
[root@luoahong ~]# echo $? 0 [root@luoahong ~]# sl #执行一个不存在的命令 -bash: sl: command not found [root@luoahong ~]# echo $? 127 [root@luoahong ~]# ls /home/luoahong ls: cannot access /home/luoahong: No such file or directory [root@luoahong ~]# echo $? 2
范例:通过脚本控制命令及脚本执行后的返回值
[root@luoahong ~]# cat test4.sh [ $# -ne 2 ] && { echo "must be two args." echo 119 } echo luoahong [root@luoahong ~]# sh test4.sh must be two args. 119 luoahong [root@luoahong ~]# echo $? 0 [root@luoahong ~]# sh test4.sh a b luoahong [root@luoahong ~]# cat test test4.sh test.txt
范例:查看系统脚本的应用情况,脚本名为/etc/init.d/rpcbind
sed -n '63,73p' /etc/init.d/rpcbind stop() { echo -n $"Stopping $prog: " killproc $prog #这是停止rpcbind的命令 RETVAL=$? #将上述命令的返回值"$?"赋值给RETVAL变量,用于后面的判断 echo [ $RETVAL -eq 0 ] && { #如果返回值不等于0,则跳过条件表达式判断,在这里直接作为返回值传给执行stop函数的脚本 rm -f /var/lock/subsys/$prog rm -f /var/run/rpcbind* } return $RETVAL
生产应用:
这是一个生产案的简单模拟,脚本用于执行启动或定时任务时,相同的脚本中只能有一个运行,当新脚本运行时,必须关闭未运行完或未退出的上一次的同名脚本进程
[root@luoahong ~]# cat pid.sh #!/bin/sh pidpath=/tmp/a.pid if [ -f "$pidpath" ] then kill `cat $pidpath` >/dev/null 2>&1 rm -f $pidpath fi echo $$ >$pidpath sleep 300
[root@luoahong ~]# ps -ef|grep pid.sh|grep -v grep root 4846 2685 0 11:58 pts/0 00:00:00 sh pid.sh [root@luoahong ~]# sh pid.sh & [3] 4871 [root@luoahong ~]# sh pid.sh & [4] 4875 [2] Terminated sh pid.sh [root@luoahong ~]# sh pid.sh & [5] 4879 [3] Terminated sh pid.sh [root@luoahong ~]# sh pid.sh & [6] 4883 [4] Terminated sh pid.sh [root@luoahong ~]# sh pid.sh & [7] 4887 [5] Terminated sh pid.sh [root@luoahong ~]# ps -ef|grep pid.sh|grep -v grep root 4887 2685 0 11:59 pts/0 00:00:00 sh pid.sh [6] Terminated sh pid.sh
$?应用小结:
1、根据返回值判断如软件的安装步骤是否成功
2、判断命令、脚本或函数等程序是否执行成功
3、通过获取的返回值确定网站备份是否正确
当服务器的数据进行备份时,我们会在执行完关键命令,例如tar或cp后
通过获取返回值来判断命令是否成功,备份数据是否完整
4、通过脚本控制命令及脚本执行后的返回值
5、若在脚本中调用"exit数字",则会返回这个数字给"$?"变量
6、若在函数里,则通"return数字"把这个数字以数字函数返回值的形式传给"$?"
bash内置命令(没有路径(二进制文件))
alias break cd continue declare echo eval exec exit export help history jobs kill let local logout printf pwd read readonly return set shift times trap typeset ulimit umask unalias unset
1、echo
echo的参数应用示例
[root@luoahong ~]# echo luoahong; wo shi; luoahong -bash: wo: command not found [root@luoahong ~]# echo luoahong;echo shi; luoahong shi [root@luoahong ~]# echo luoahong; echo shi; luoahong shi [root@luoahong ~]# echo -n luoahong; echo shi; luoahongshi [root@luoahong ~]# echo -e luoahong; echo shi; luoahong shi [root@luoahong ~]# echo woshi\luoahong\wo\bushi\tanyapeng woshiluoahongwobushitanyapeng [root@luoahong ~]# echo "woshi\luoahong\wo\bushi\tanyapeng" woshi\luoahong\wo\bushi\tanyapeng [root@luoahong ~]# echo -e "woshi\luoahong\wo\bushi\tanyapeng" woshi\luoahong\wushi anyapeng [root@luoahong ~]# echo -e "woshi\luoahong\nwo\bushi\tanyapeng" woshi\luoahong wushi anyapeng [root@luoahong ~]# echo -e "woshi\tluoahong\nwo\bushi\tanyapeng" woshi luoahong wushi anyapeng [root@luoahong ~]# echo -e "1\b23" 23 [root@luoahong ~]# echo -e "1\b2n" 2n [root@luoahong ~]# echo -e "1\b23\n"
2、eval
命令格式:eval args
功能:当shell程序执行到eval语句时,shell读入参数args,并将它们组合成一个新的命令
然后执行
范例:set和eval命令的使用(含特殊位置变量用法)方法
[root@luoahong ~]# cat noeval.sh echo \$$# [root@luoahong ~]# sh noeval.sh arg1 agg2 $2 [root@luoahong ~]# cat eval.sh echo "echo \$$# " [root@luoahong ~]# sh eval.sh arg1 agg2 echo $2
3、exec
命令格式:eval 命令参数
功能:exec命令能够在不创建新的子进程的前提下,转去执行指定的命令,当制定的命令执行完毕后
该进程(也就是最初的shell)就终止了
[root@luoahong ~]# exec date Fri Jun 8 12:31:38 EDT 2018 Vim: Caught deadly signal TERM Vim: Finished. Connection closed by foreign host. Disconnected from remote host(59) at 15:31:38. Type `help' to learn how to use Xshell prompt. [f:\~]$ #退到普通用户模式下 Connecting to 192.168.118.59:22... Connection established. To escape to local shell, press 'Ctrl+Alt+]'. Last login: Fri Jun 8 06:21:24 2018 from 192.168.118.30
当使用exec打开文件后,read命令每次都会将文件指针移动到文件的下一行进行读取
,直到文件末尾,利用这个可以实现处理文件的内容
范例:exec功能实例
[root@luoahong ~]# seq 5 > /tmp/tmp.log [root@luoahong ~]# cat exec.sh exec </tmp/tmp.log while read line do echo $line done
执行结果如下:
[root@luoahong ~]# sh exec.sh 1 2 3 4 5 ok
5、shift
命令格式:shift-Shift positional parameters
功能:shift语句会按如下方式重新命名所有的位置参数变量,即$2成为$1、$3成为$2等
以此类推,在程序中每使用一次shift语句,都会使所有的位置参数依次向左移动一个位置,并使位置
参数$#减1,知道0为止
范例:shift的功能介绍
[root@luoahong ~]# help shift shift: shift [n] Shift positional parameters. Rename the positional parameters $N+1,$N+2 ... to $1,$2 ... If N is not given, it is assumed to be 1. Exit Status: Returns success unless N is negative or greater than $#.
shift的使用示例
[root@luoahong ~]# cat shift.sh echo $1 $2 if [ $# -eq 2 ];then shift echo $1 fi
[root@luoahong ~]# sh shift.sh 1 2
1 2
2
应用场景:
当我们写shell希望像命令行的命令通过参数控制不同的功能时,就类似传一个类似-c
的参数,然后再接内容
[root@luoahong ~]# [root@luoahong ~]# sh shift.sh -c luoahong -c luoahong luoahong
系统案例
6、exit
命令格式:exit-Exit the shell
功能:退出shell程序,在exit之后可以有选择地制定一个数位作为返回状态
shell变量子串介绍与实战
常用操作如下表:man bash找本节资料“Parameter Expansion
”
${#string} 返回$string的长度
${string:position} 在$string中,从位置$position之后开始提取子串
${string:position:length} 在$string中,从位置$position之后开始提取长度为$length的子串
${string#substring} 从变量$string开头开始删除最短匹配$substring子串
${string##substring } 从变量$string开头开始删除最长匹配$substring子串
${string%substring} 从变量$string结尾开始删除最短匹配$substring子串
${string%%substring} 从变量$string结尾开始删除最长匹配$substring子串
${parameter/pattern/string} 使用string,来代替第一个匹配的pattern
${parameter/#pattern/string} 从开头匹配string变量中的pattern,使用string来替换匹配的pettern
${parameter/%patter/string} 从结尾开始匹配string变量中的pattern,就用string来替换匹配pattern
${parameter//pattern/string} 使用string,来代替所有匹配的pattern
更多资料man bansh 查找“Parameter Expansion”
准备:
定义LUO变量,赋值内容为"wo shi yi ge it administrator"。操作代码如下:
[root@luoahong ~]# LUO="wo shi yi ge it administrator" [root@luoahong ~]# echo ${LUO} wo shi yi ge it administrator
范例:返回变量LUO值的长度
[root@luoahong ~]# echo $LUO wo shi yi ge it administrator 方法一: [root@luoahong ~]# echo $LUO| wc -L 29
方法二:
[root@luoahong ~]# expr length "$LUO" 29
方法三: [root@luoahong ~]# expr "$LUO"|awk '{print lengt($0)}' awk: cmd. line:1: (FILENAME=- FNR=1) fatal: function `lengt' not defined [root@luoahong ~]# expr "$LUO"|awk '{print length($0)}' 29
范例:利用time命令及for循环对几种获取字符串长度的方法进行性能比较
[root@luoahong ~]# time for n in {1..10000};do char=`seq -s "luoahong" 100`;echo ${#char} &>/dev/null;done real 0m12.111s user 0m5.557s sys 0m5.636s
[root@luoahong ~]# time for n in {1..10000};do char=`seq -s "luoahong" 100`;echo ${char}|wc -L &>/dev/null;done real 0m33.874s user 0m13.642s sys 0m17.467s
[root@luoahong ~]# time for n in {1..10000};do char=`seq -s "luoahong" 100`;echo $char|awk '{print length($0)}' &>/dev/null;done real 0m35.538s user 0m14.868s sys 0m17.925s
有关获取字符串长度的集中统计方法的性能比较如下:
- 变量自带的计算长度的方法的效率最高,在要求效率的场景中尽量多用
- 使用管道统计的方法的效率比较差,在要求效率的场景中尽量不用
- 对于日常简单的脚本计算,读者可以根据自己擅长的或易用的程度去选择
范例:截取LUO变量的内容,从第2个字符之后开始截取,默认截取后面字符的全部,第2个字符不包含在内,也可以理解为删除前面的多个字符
[root@luoahong ~]# echo ${LUO} wo shi yi ge it administrator [root@luoahong ~]# echo ${LUO:2} shi yi ge it administrator
范例:截取LUO变量的内容,从第2个字符之后开始截取,截取2个字符
[root@luoahong ~]# echo ${LUO:2:2} s [root@luoahong ~]# echo ${LUO}|cut -c 3-4 s
范例:从变量$LUO内容的开始删除最短匹配"a*c"及"a*C"的子串
[root@luoahong ~]# LUO=abcABC123ABCabc [root@luoahong ~]# [root@luoahong ~]# echo ${LUO#a*c} ABC123ABCabc [root@luoahong ~]# echo ${LUO#a*C} 123ABCabc
范例:从变量$LUO内容的开始删除最长匹配"a*c"及"a*C"的子串
[root@luoahong ~]# LUO=abcABC123ABCabc [root@luoahong ~]# echo $LUO abcABC123ABCabc [root@luoahong ~]# echo ${LUO##a*C} abc [root@luoahong ~]# echo ${LUO##a*c}
范例:从变量$LUO内容的结尾删除最短匹配"a*c"及"a*C"的子串
[root@luoahong ~]# echo $LUO abcABC123ABCabc [root@luoahong ~]# echo ${LUO%a*C} abcABC123ABCabc
范例:从变量$LUO内容的结尾删除最长匹配"a*c"及"a*C"的子串
[root@luoahong ~]# echo ${LUO%%a*C} abcABC123ABCabc [root@luoahong ~]# echo ${LUO%%a*c}
范例:使用a字符串代替变量$LUO匹配的hong字符串
[root@luoahong ~]# LUO="wo shi,luo,hong" [root@luoahong ~]# echo $LUO wo shi,luo,hong [root@luoahong ~]# LUO="wo hong shi,luo,hong" [root@luoahong ~]# echo ${LUO/hong/a} wo a shi,luo,hong
[root@luoahong ~]# echo ${LUO//hong/a} wo a shi,luo,a
有关替换的小结:
/ 表示替换匹配的第一个字符串
// 表示替换匹配的所有字符串
匹配删除小结
- # 开头删除匹配最短
- ## 从头开始匹配最长
- % 结尾开始匹配最短
- %% 结尾开始匹配最长
- a*c 表示匹配的字符串,*表示匹配所有,a*c匹配开头为a、中间为任意多个字符、结尾为c的字符串
- a*C 表示匹配的字符串,*表示匹配所有,a*C匹配开头为a、中间为任意多个字符、结尾为C的字符串
生产案例:
httpd=${HTTPD-/usr/sbin/httpd} prog=httpd pidfile=${PIDFILE-/var/run/httpd/httpd.pid} lockfile=${LOCKFILE-/var/lock/subsys/httpd} RETVAL=0 STOP_TIMEOUT=${STOP_TIMEOUT-10}
企业场景例子:尽量不要使用rm
[root@MySQL test]# cat del.sh path=/server/backup find ${path:=/tmp/} -name "*.tar.gz" -type f |xargs rm -f =================== path=/server/backup find ${path:=/tmp/} -name "*.tar.gz" -type f |xargs rm -f [root@MySQL test]# cat del.sh path=/server/backup find ${path:=/tmp/} -name "*.tar.gz" -type f |xargs rm -f [root@MySQL test]# sh -x del.sh + path=/server/backup + find /server/backup -name '*.tar.gz' -type f + xargs rm -f [root@MySQL test]# sed -i '1d' del.sh [root@MySQL test]# cat del.sh find ${path:=/tmp/} -name "*.tar.gz" -type f |xargs rm -f [root@MySQL test]# sh -x del.sh + find /tmp -name '*.tar.gz' -type f + xargs rm -f #rm -fr ${path:=/tmp/}
扩展:其他变量的替换
变量替换表:了解,man bash查到资料Parameter Expansion
变量的数值(整数)计算
变量的数值计算常见的有如下几个命令: (())、let、expr、bc(小数)、$[],其他都是整数
如果要执行简单的整数运算,只需将特定的算术表达式用"$(("和"))" 括起来即可。
shell的算术运算符号常置于"$(("......"))"的语法中。这一语法如同双引号的功能
1)(())用法:(此方法很常用)**
范例:shell的算术运算实例如下:
[root@db01 ~]# ((a=1+2**3-4%3)) [root@db01 ~]# echo $a 8 [root@db01 ~]# ((a=1+2**3-4%3)) [root@db01 ~]# echo $a 8 [root@db01 ~]# echo $((1+2**3-4%3)) 8
记忆方法:++,--
变量a
在前,表达式的值为a
,然后a自增或自减,变量a在符号后,表达式值自增或自减,然后a值自增或自减
[root@db01 ~]# a=$((100*(100+1)/2)) [root@db01 ~]# echo $a 5050
范例6:这是一个实践考试题,内容如下:
把a,b两个变量通过命令行脚本传参的方式实现上面混合运算脚本的功能
第一种方法:
#!/bin/bash a=6 b=2 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 ))"
第二种方法:
[root@web02 ~]# cat abc.sh #!/bin/bash a=$1 b=$2 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 ))"
2)let命令的用法(整数)
格式: let
赋值表达式
【注】let赋值表达式功能等同于:((赋值表达式))
范例1:给自变量i加8
[root@db01 scripts]# i=2 [root@db01 scripts]# let i=i+8 [root@db01 scripts]# echo $i 10
3)expr (evaluate(求值)expressions(表达式))命令的用法:
expr命令一般用于整数值,但也可用于字符串,用来求表达式变量的值,同时expr也是一个手工命令计算器
1.计算
语法:expr Expression
[root@web02 /]# expr 2 + 2 4 [root@web02 /]# expr 2 - 2 0 [root@web02 /]# expr 2 * 2 expr: syntax error 语法错误 [root@web02 /]# expr 2 \* 2 4 [root@web02 /]# expr 3 / 2 1 [root@web02 /]# expr 3 % 2 1
另一种玩法
[root@db01 scripts]# i=0 [root@db01 scripts]# i=`expr $i + 1` [root@db01 scripts]# echo $i 1
expr $[$a+$b]
表达式形式,其中$a $b
可为整数值
[root@web02 /]# expr $[2+3] 5 [root@web02 /]# expr $[2*3] 6 [root@web02 /]# expr $[2**3] 2的2次方*3 8 [root@web02 /]# expr $[2/3] 0 [root@web02 /]# expr $[2%3] 2
四种运算方法:
1.(())
2.let
3.expr
4.[]
整数
判断一个文件的扩展名是不是pub
(发送公钥的命令就是使用此参数)
#!/bin/sh if expr "$1" : ".*\.pub" &>/dev/null then echo "you are using $1" else echo "pls use *.pub file" fi [root@web02 ~]# sh aaa.sh oldboy pls use *.pub file [root@web02 ~]# sh aaa.sh oldboy.pub you are using oldboy.pub
判断一个输入是不是数字
#!/bin/sh while true do read -p "Pls input:" a expr $a + 0 >/dev/null 2>&1 [ $? -eq 0 ] &&echo int||echo chars done
如果判断是不是数字,就执行错误shars
[root@db01 scripts]# cat b.sh #!/bin/sh expr $1 + 1 >/dev/null 2>&1 [ $? -eq 0 ] &&echo int||echo chars [root@db01 scripts]# sh b.sh 1 int [root@db01 scripts]# sh b.sh 1a chars [root@db01 scripts]# sh b.sh 100 int [root@db01 scripts]# sh b.sh 100abc chars
expr match 整数判断
[[ `expr match "$a" "[0-9][0-9]*$"` == 0 ]] && { echo "the first is not a num" exit 3 }
计算变量长度
[root@db01 scripts]# a="oldboy" [root@db01 scripts]# expr length "$a" 6
expr功能
1.整数计算
2.判断扩展名
3.判断输入是否为整数
4.计算变量的长度
bc命令用法
[root@db01 scripts]# bc bc 1.06.95 Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty'. 1+1 2 1+3 4 6*8 48
另一种使用bc的方式
[root@db01 scripts]# echo 1+2|bc 3 [root@db01 scripts]# echo 8-2|bc 6
inux下的bc
命令可以设置结果的位数,通过scale
.
[root@db01 scripts]# echo "scale=3;5.23 / 3.13"|bc 1.670 [root@db01 scripts]# echo "scale=2;5.23 / 3.13"|bc 1.67 比如: $ echo "scale=4; 1.2323293128 / 1.1" | bc -l 1.1202
bc命令简单的计算
[root@web02 ~]# i=2 [root@web02 ~]# i=`echo $i+1|bc` [root@web02 ~]# echo $i 3 可以做加法计算 [root@web02 ~]# echo 3.5+5 3.5+5 [root@web02 ~]# echo 3.5+5|bc 8.5 减法计算 [root@web02 ~]# echo 3.5-5|bc -1.5 乘法计算 [root@web02 ~]# echo 3.5*5|bc 17.5 保留位数(bc的用处不大) [root@web02 ~]# echo "scale=2; 3.5*5.1"|bc 17.85 [root@web02 ~]# echo "scale=2; 3*5"|bc 15 [root@web02 ~]# echo "scale=1; 3*5"|bc 15 提示:bc是特有的小数计算 awk也可以进行小数计算 [root@web02 ~]# echo "5.5 5.6" |awk '{print ($2-$1)}' 0.1 [root@web02 ~]# echo "5.5 5.5" |awk '{print ($2+$1)}' 11
利用bc配合变量运算
[root@adminset 05]# i=5 [root@adminset 05]# i=`echo $i+6|bc` #利用echo输出表达式,通过管道交给bc计算,此方法效率较低 [root@adminset 05]# echo $i 11
提示:根据bc所具有的特殊性来看:
- 如果小数,则选择bc运算没有问题(老男孩推荐awk)
- 若是整数场景,可用(())、let、expr等
范例:通过一条命令计算输出1+2+3+...+10
的表达式,并计算出结果,使用bc计算
输出内容如:1+2+3+4+5+6+7+8+9+10=55
第一种方法:
[root@web02 ~]# seq -s "+" " "10 1+2+3+4+5+6+7+8+9+10 [root@web02 ~]# echo `seq -s "+" " "10`=`seq -s "+" " "10|bc` 1+2+3+4+5+6+7+8+9+10=55
第二种方法:
[root@web02 ~]# echo {1..10}|tr " " "+" 1+2+3+4+5+6+7+8+9+10 [root@web02 ~]# echo `echo {1..10}|tr " " "+"`=`echo {1..10}|tr " " "+"|bc` 1+2+3+4+5+6+7+8+9+10=55
更多方法:因计算不是重点,所以我们不重点研究。
[root@adminset 05]# echo `seq -s "+" 10`="$((`seq -s "+" 10`))" 1+2+3+4+5+6+7+8+9+10=55 #使用(())计算 [root@adminset 05]# echo `seq -s "+" 10`=`seq -s "+" 10|bc` 1+2+3+4+5+6+7+8+9+10=55 #使用bc计算 [root@adminset 05]# echo `seq -s "+" 10`=`seq -s " + " 10|xargs expr` 1+2+3+4+5+6+7+8+9+10=55 #使用expr计算 [root@adminset 05]# echo `seq -s "+" 10`=$(echo $[`seq -s " + " 10`]) 1+2+3+4+5+6+7+8+9+10=55 #使用$[]计算
特点:bc的独有特点是支持小数运算,当然也可以整数运算。