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
有关获取字符串长度的集中统计方法的性能比较如下:
  1. 变量自带的计算长度的方法的效率最高,在要求效率的场景中尽量多用
  2. 使用管道统计的方法的效率比较差,在要求效率的场景中尽量不用
  3. 对于日常简单的脚本计算,读者可以根据自己擅长的或易用的程度去选择

范例:截取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 
有关替换的小结:

/ 表示替换匹配的第一个字符串
// 表示替换匹配的所有字符串

匹配删除小结

  1. # 开头删除匹配最短
  2. ## 从头开始匹配最长
  3. % 结尾开始匹配最短
  4. %% 结尾开始匹配最长
  5. a*c 表示匹配的字符串,*表示匹配所有,a*c匹配开头为a、中间为任意多个字符、结尾为c的字符串
  6. 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 
image_1b16rb59912t71vbn1nvq9cl8d549.png-237.9kB
image_1b16rbe73147s102t1feo34er9u4m.png-34.7kB
image_1b16rbmn97nq1gbk9mbojj1igm53.png-74.7kB

变量的数值(整数)计算

  变量的数值计算常见的有如下几个命令: 
(())、let、expr、bc(小数)、$[],其他都是整数

如果要执行简单的整数运算,只需将特定的算术表达式用"$(("和"))" 括起来即可。
shell的算术运算符号常置于"$(("......"))"的语法中。这一语法如同双引号的功能

image_1b16reaf114d22b0rqh1vb11ilq5g.png-211.1kB

 

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所具有的特殊性来看:

  1. 如果小数,则选择bc运算没有问题(老男孩推荐awk)
  2. 若是整数场景,可用(())、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的独有特点是支持小数运算,当然也可以整数运算。

 

转载于:https://www.cnblogs.com/luoahong/articles/9154309.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值