[转帖]shell编程:变量知识进阶(三)
https://www.cnblogs.com/luoahong/articles/9154309.html
1 Shell特殊位置变量

范例1:$n的实践例子
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
[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.shecho $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语句节选如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
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案例
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
tail -6 /etc/init.d/rpcbindecho $"Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart|try-restart}" #如果$0基本生产场景就是,当用户的输入不符合脚本的要求时,就打印脚本的名字及使用帮助 RETVAL=2 ;;esac exit $RETVAL[root@luoahong ~]#/etc/init.d/rpcbindUsage: /etc/init.d/rpcbind {start|stop|status|restart|reload|force-reload|condrestart|try-restart} |
#上文/etc/init.d/rpcbind就是$0从脚本命令行获取的值,当用户输入不符合脚本设定的要求时,就打印脚本的名字及使用帮助
例子:$#
|
1
2
3
4
5
6
|
[root@luoahong ~]# cat q.shecho $1 $2 $3 $4 $5 $6 $7 $8 $9echo $#[root@luoahong ~]# sh q.sh {a..z}a b c d e f g h i #只接收了9个变量,所以打印9个字符26 #传入26个字符作为26个参数,因此这里的数字为26,说明传入了26个参数 |
范例:根据用户在命令行的传参个数判断用户的输入,不合要求的给予提示并退出
|
1
2
3
4
5
6
7
8
9
10
|
[root@luoahong ~]# cat t1.sh[ $# -ne 2 ] && { echo "muse two args" exit 1 } echo luoahong[root@luoahong ~]# sh t1.shmuse two args[root@luoahong ~]# sh t1.sh arg1 arg2luoahong |
然后是if判断语句的写法,如下:
|
1
2
3
4
5
6
7
8
9
10
11
|
[root@luoahong ~]# cat t2.shif [ $# -ne 2 ] then echo " USAGE:/bin/sh $0 arg1 arg2" exit 1fiecho $1 $2[root@luoahong ~]# sh t2.sh USAGE:/bin/sh t2.sh arg1 arg2[root@luoahong ~]# sh t2.sh luoahong tyxluoahong tyx |
$*和$@区别
范例:利用set设置位置参数(同命令行脚本的传参)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
[root@luoahong ~]# set -- "luoahong hong" wo bushi luoahong#设置三个字符串参数"--" 表示清除所有的参数变量,重新设置后面的参数变量[root@luoahong ~]# echo $#4[root@luoahong ~]# echo $1luoahong hong[root@luoahong ~]# echo $2wo[root@luoahong ~]# echo $3bushi[root@luoahong ~]# echo $4luoahong |
测试$*和$@,注意此时不带双引号:
|
1
2
3
4
|
[root@luoahong ~]# echo $*luoahong hong wo bushi luoahong[root@luoahong ~]# echo $@luoahong hong wo bushi luoahong |
测试$*和$@,注意此时带双引号:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
[root@luoahong ~]# echo "$@"luoahong hong wo bushi luoahong[root@luoahong ~]# echo "$*"luoahong hong wo bushi luoahong这才真正符合我们传入的参数需求[root@luoahong ~]# for i in "$*";do echo $i;doneluoahong hong wo bushi luoahong#在有双引号的情况,参数里引号中的内容当作一个参数输出了![root@luoahong ~]# for i in "$@";do echo $i;done#有双引号的时候,每个参数均以独立的内容输出luoahong hong #有双引号算一个参数wobushiluoahong |
#在有双引号的情况,参数里引号中的内容当作一个参数输出了!

Shell进程状态变量

提示:查找知道方法:man bash,然后搜索Special Parameters.
$?实例
范例:执行命令后获取返回值(切换到oldboy永固下进行测试)
|
1
2
3
4
5
6
7
8
9
10
|
[root@luoahong ~]# echo $?0[root@luoahong ~]# sl #执行一个不存在的命令-bash: sl: command not found[root@luoahong ~]# echo $?127[root@luoahong ~]# ls /home/luoahongls: cannot access /home/luoahong: No such file or directory[root@luoahong ~]# echo $?2 |
范例:通过脚本控制命令及脚本执行后的返回值
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
[root@luoahong ~]# cat test4.sh[ $# -ne 2 ] && {echo "must be two args."echo 119}echo luoahong[root@luoahong ~]# sh test4.shmust be two args.119luoahong[root@luoahong ~]# echo $?0[root@luoahong ~]# sh test4.sh a bluoahong[root@luoahong ~]# cat testtest4.sh test.txt |
范例:查看系统脚本的应用情况,脚本名为/etc/init.d/rpcbind
|
1
2
3
4
5
6
7
8
9
10
11
|
sed -n '63,73p' /etc/init.d/rpcbindstop() { 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 |
生产应用:
这是一个生产案的简单模拟,脚本用于执行启动或定时任务时,相同的脚本中只能有一个运行,当新脚本运行时,必须关闭未运行完或未退出的上一次的同名脚本进程
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
[root@luoahong ~]# cat pid.sh#!/bin/shpidpath=/tmp/a.pidif [ -f "$pidpath" ] then kill `cat $pidpath` >/dev/null 2>&1 rm -f $pidpathfiecho $$ >$pidpathsleep 300<br>[root@luoahong ~]# ps -ef|grep pid.sh|grep -v greproot 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 greproot 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内置命令(没有路径(二进制文件))
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
aliasbreakcdcontinuedeclareechoevalexecexitexporthelphistoryjobskillletlocallogoutprintfpwdreadreadonlyreturnsetshifttimestraptypesetulimitumaskunaliasunset |
1、echo

echo的参数应用示例
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
[root@luoahong ~]# echo luoahong; wo shi;luoahong-bash: wo: command not found[root@luoahong ~]# echo luoahong;echo shi;luoahongshi[root@luoahong ~]# echo luoahong; echo shi;luoahongshi[root@luoahong ~]# echo -n luoahong; echo shi;luoahongshi[root@luoahong ~]# echo -e luoahong; echo shi;luoahongshi[root@luoahong ~]# echo woshi\luoahong\wo\bushi\tanyapengwoshiluoahongwobushitanyapeng[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\luoahongwushi anyapeng[root@luoahong ~]# echo -e "woshi\tluoahong\nwo\bushi\tanyapeng"woshi luoahongwushi 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命令的使用(含特殊位置变量用法)方法
|
1
2
3
4
5
6
7
8
9
|
[root@luoahong ~]# cat noeval.shecho \$$#[root@luoahong ~]# sh noeval.sh arg1 agg2$2[root@luoahong ~]# cat eval.shecho "echo \$$# "[root@luoahong ~]# sh eval.sh arg1 agg2echo $2 |
3、exec
命令格式:eval 命令参数
功能:exec命令能够在不创建新的子进程的前提下,转去执行指定的命令,当制定的命令执行完毕后
该进程(也就是最初的shell)就终止了
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
[root@luoahong ~]# exec dateFri Jun 8 12:31:38 EDT 2018Vim: Caught deadly signal TERMVim: 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功能实例
|
1
2
3
4
5
6
7
|
[root@luoahong ~]# seq 5 > /tmp/tmp.log[root@luoahong ~]# cat exec.shexec </tmp/tmp.logwhile read linedoecho $linedone |
执行结果如下:
|
1
2
3
4
5
6
7
|
[root@luoahong ~]# sh exec.sh12345ok |
5、shift
命令格式:shift-Shift positional parameters
功能:shift语句会按如下方式重新命名所有的位置参数变量,即$2成为$1、$3成为$2等
以此类推,在程序中每使用一次shift语句,都会使所有的位置参数依次向左移动一个位置,并使位置
参数$#减1,知道0为止
范例:shift的功能介绍
|
1
2
3
4
5
6
7
8
9
|
[root@luoahong ~]# help shiftshift: shift [n]Shift positional parameters.Rename the positional parameters $N+1,$N+2 ... to $1,$2 ... If N isnot given, it is assumed to be 1.Exit Status:Returns success unless N is negative or greater than $#. |
shift的使用示例
|
1
2
3
4
5
6
|
[root@luoahong ~]# cat shift.shecho $1 $2if [ $# -eq 2 ];then shift echo $1fi |
[root@luoahong ~]# sh shift.sh 1 2
1 2
2
应用场景:
当我们写shell希望像命令行的命令通过参数控制不同的功能时,就类似传一个类似-c
的参数,然后再接内容
|
1
2
3
4
|
[root@luoahong ~]#[root@luoahong ~]# sh shift.sh -c luoahong-c luoahongluoahong |
系统案例

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"。操作代码如下:
|
1
2
3
|
[root@luoahong ~]# LUO="wo shi yi ge it administrator"[root@luoahong ~]# echo ${LUO}wo shi yi ge it administrator |
范例:返回变量LUO值的长度
|
1
2
3
4
5
6
7
8
9
|
[root@luoahong ~]# echo $LUOwo shi yi ge it administrator方法一:[root@luoahong ~]# echo $LUO| wc -L29方法二:[root@luoahong ~]# expr length "$LUO" 29<br><br>方法三:[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循环对几种获取字符串长度的方法进行性能比较
|
1
2
3
4
5
6
7
8
9
10
11
12
|
[root@luoahong ~]# time for n in {1..10000};do char=`seq -s "luoahong" 100`;echo ${#char} &>/dev/null;donereal 0m12.111suser 0m5.557ssys 0m5.636s<br>[root@luoahong ~]# time for n in {1..10000};do char=`seq -s "luoahong" 100`;echo ${char}|wc -L &>/dev/null;donereal 0m33.874suser 0m13.642ssys 0m17.467s<br>[root@luoahong ~]# time for n in {1..10000};do char=`seq -s "luoahong" 100`;echo $char|awk '{print length($0)}' &>/dev/null;donereal 0m35.538suser 0m14.868ssys 0m17.925s |
有关获取字符串长度的集中统计方法的性能比较如下:
- 变量自带的计算长度的方法的效率最高,在要求效率的场景中尽量多用
- 使用管道统计的方法的效率比较差,在要求效率的场景中尽量不用
- 对于日常简单的脚本计算,读者可以根据自己擅长的或易用的程度去选择
范例:截取LUO变量的内容,从第2个字符之后开始截取,默认截取后面字符的全部,第2个字符不包含在内,也可以理解为删除前面的多个字符
|
1
2
3
4
|
[root@luoahong ~]# echo ${LUO}wo shi yi ge it administrator[root@luoahong ~]# echo ${LUO:2}shi yi ge it administrator |
范例:截取LUO变量的内容,从第2个字符之后开始截取,截取2个字符
|
1
2
3
4
|
[root@luoahong ~]# echo ${LUO:2:2}s[root@luoahong ~]# echo ${LUO}|cut -c 3-4s |
范例:从变量$LUO内容的开始删除最短匹配"a*c"及"a*C"的子串
|
1
2
3
4
5
6
|
[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"的子串
|
1
2
3
4
5
6
|
[root@luoahong ~]# LUO=abcABC123ABCabc[root@luoahong ~]# echo $LUOabcABC123ABCabc[root@luoahong ~]# echo ${LUO##a*C}abc[root@luoahong ~]# echo ${LUO##a*c} |
范例:从变量$LUO内容的结尾删除最短匹配"a*c"及"a*C"的子串
|
1
2
3
4
|
[root@luoahong ~]# echo $LUOabcABC123ABCabc[root@luoahong ~]# echo ${LUO%a*C}abcABC123ABCabc |
范例:从变量$LUO内容的结尾删除最长匹配"a*c"及"a*C"的子串
|
1
2
3
|
[root@luoahong ~]# echo ${LUO%%a*C}abcABC123ABCabc[root@luoahong ~]# echo ${LUO%%a*c} |
范例:使用a字符串代替变量$LUO匹配的hong字符串
|
1
2
3
4
5
6
7
8
|
[root@luoahong ~]# LUO="wo shi,luo,hong"[root@luoahong ~]# echo $LUOwo shi,luo,hong[root@luoahong ~]# LUO="wo hong shi,luo,hong"[root@luoahong ~]# echo ${LUO/hong/a}wo a shi,luo,hong<br>[root@luoahong ~]# echo ${LUO//hong/a}wo a shi,luo,a |
有关替换的小结:
/ 表示替换匹配的第一个字符串
// 表示替换匹配的所有字符串
匹配删除小结
- # 开头删除匹配最短
- ## 从头开始匹配最长
- % 结尾开始匹配最短
- %% 结尾开始匹配最长
- a*c 表示匹配的字符串,*表示匹配所有,a*c匹配开头为a、中间为任意多个字符、结尾为c的字符串
- a*C 表示匹配的字符串,*表示匹配所有,a*C匹配开头为a、中间为任意多个字符、结尾为C的字符串
生产案例:
|
1
2
3
4
5
6
|
httpd=${HTTPD-/usr/sbin/httpd}prog=httpdpidfile=${PIDFILE-/var/run/httpd/httpd.pid}lockfile=${LOCKFILE-/var/lock/subsys/httpd}RETVAL=0STOP_TIMEOUT=${STOP_TIMEOUT-10} |
企业场景例子:尽量不要使用rm
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
[root@MySQL test]# cat del.shpath=/server/backupfind ${path:=/tmp/} -name "*.tar.gz" -type f |xargs rm -f===================path=/server/backupfind ${path:=/tmp/} -name "*.tar.gz" -type f |xargs rm -f[root@MySQL test]# cat del.shpath=/server/backupfind ${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.shfind ${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的算术运算实例如下:
|
1
2
3
4
5
6
7
8
|
[root@db01 ~]# ((a=1+2**3-4%3))[root@db01 ~]# echo $a8[root@db01 ~]# ((a=1+2**3-4%3))[root@db01 ~]# echo $a8[root@db01 ~]# echo $((1+2**3-4%3))8 |
记忆方法:++,--
变量a在前,表达式的值为a,然后a自增或自减,变量a在符号后,表达式值自增或自减,然后a值自增或自减
|
1
2
3
|
[root@db01 ~]# a=$((100*(100+1)/2))[root@db01 ~]# echo $a5050 |
范例6:这是一个实践考试题,内容如下:
把a,b两个变量通过命令行脚本传参的方式实现上面混合运算脚本的功能
第一种方法:
|
1
2
3
4
5
6
7
8
9
|
#!/bin/basha=6b=2echo "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 ))" |
第二种方法:
|
1
2
3
4
5
6
7
8
9
10
|
[root@web02 ~]# cat abc.sh#!/bin/basha=$1b=$2echo "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
|
1
2
3
4
|
[root@db01 scripts]# i=2[root@db01 scripts]# let i=i+8[root@db01 scripts]# echo $i10 |
3)expr (evaluate(求值)expressions(表达式))命令的用法:
expr命令一般用于整数值,但也可用于字符串,用来求表达式变量的值,同时expr也是一个手工命令计算器
1.计算
语法:expr Expression
|
1
2
3
4
5
6
7
8
9
10
11
12
|
[root@web02 /]# expr 2 + 24[root@web02 /]# expr 2 - 20[root@web02 /]# expr 2 * 2expr: syntax error 语法错误[root@web02 /]# expr 2 \* 24[root@web02 /]# expr 3 / 21[root@web02 /]# expr 3 % 21 |
另一种玩法
|
1
2
3
4
|
[root@db01 scripts]# i=0[root@db01 scripts]# i=`expr $i + 1`[root@db01 scripts]# echo $i1 |
expr $[$a+$b]表达式形式,其中$a $b 可为整数值
|
1
2
3
4
5
6
7
8
9
10
|
[root@web02 /]# expr $[2+3]5[root@web02 /]# expr $[2*3]6[root@web02 /]# expr $[2**3] 2的2次方*38[root@web02 /]# expr $[2/3]0[root@web02 /]# expr $[2%3]2 |
四种运算方法:
1.(())
2.let
3.expr
4.[]
整数
判断一个文件的扩展名是不是pub(发送公钥的命令就是使用此参数)
|
1
2
3
4
5
6
7
8
9
10
11
|
#!/bin/shif expr "$1" : ".*\.pub" &>/dev/nullthenecho "you are using $1"elseecho "pls use *.pub file"fi[root@web02 ~]# sh aaa.sh oldboypls use *.pub file[root@web02 ~]# sh aaa.sh oldboy.pubyou are using oldboy.pub |
判断一个输入是不是数字
|
1
2
3
4
5
6
7
|
#!/bin/shwhile truedoread -p "Pls input:" aexpr $a + 0 >/dev/null 2>&1[ $? -eq 0 ] &&echo int||echo charsdone |
如果判断是不是数字,就执行错误shars
|
1
2
3
4
5
6
7
8
9
10
11
12
|
[root@db01 scripts]# cat b.sh#!/bin/shexpr $1 + 1 >/dev/null 2>&1[ $? -eq 0 ] &&echo int||echo chars[root@db01 scripts]# sh b.sh 1int[root@db01 scripts]# sh b.sh 1achars[root@db01 scripts]# sh b.sh 100int[root@db01 scripts]# sh b.sh 100abcchars |
expr match 整数判断
|
1
2
3
4
|
[[ `expr match "$a" "[0-9][0-9]*$"` == 0 ]] && {echo "the first is not a num"exit 3} |
计算变量长度
|
1
2
3
|
[root@db01 scripts]# a="oldboy"[root@db01 scripts]# expr length "$a"6 |
expr功能
1.整数计算
2.判断扩展名
3.判断输入是否为整数
4.计算变量的长度
bc命令用法
|
1
2
3
4
5
6
7
8
9
10
11
|
[root@db01 scripts]# bcbc 1.06.95Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.This is free software with ABSOLUTELY NO WARRANTY.For details type `warranty'.1+121+346*848 |
另一种使用bc的方式
|
1
2
3
4
|
[root@db01 scripts]# echo 1+2|bc3[root@db01 scripts]# echo 8-2|bc6 |
inux下的bc命令可以设置结果的位数,通过scale.
|
1
2
3
4
5
6
7
|
[root@db01 scripts]# echo "scale=3;5.23 / 3.13"|bc1.670[root@db01 scripts]# echo "scale=2;5.23 / 3.13"|bc1.67比如:$ echo "scale=4; 1.2323293128 / 1.1" | bc -l1.1202 |
bc命令简单的计算
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
[root@web02 ~]# i=2[root@web02 ~]# i=`echo $i+1|bc`[root@web02 ~]# echo $i3可以做加法计算[root@web02 ~]# echo 3.5+53.5+5[root@web02 ~]# echo 3.5+5|bc8.5减法计算[root@web02 ~]# echo 3.5-5|bc-1.5乘法计算[root@web02 ~]# echo 3.5*5|bc17.5保留位数(bc的用处不大)[root@web02 ~]# echo "scale=2; 3.5*5.1"|bc17.85[root@web02 ~]# echo "scale=2; 3*5"|bc15[root@web02 ~]# echo "scale=1; 3*5"|bc15提示: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配合变量运算
|
1
2
3
4
|
[root@adminset 05]# i=5[root@adminset 05]# i=`echo $i+6|bc` #利用echo输出表达式,通过管道交给bc计算,此方法效率较低[root@adminset 05]# echo $i11 |
提示:根据bc所具有的特殊性来看:
- 如果小数,则选择bc运算没有问题(老男孩推荐awk)
- 若是整数场景,可用(())、let、expr等
范例:通过一条命令计算输出1+2+3+...+10的表达式,并计算出结果,使用bc计算
输出内容如:1+2+3+4+5+6+7+8+9+10=55
第一种方法:
|
1
2
3
4
|
[root@web02 ~]# seq -s "+" " "101+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 |
第二种方法:
|
1
2
3
4
|
[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 |
更多方法:因计算不是重点,所以我们不重点研究。
|
1
2
3
4
5
6
7
8
9
10
11
12
|
[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的独有特点是支持小数运算,当然也可以整数运算。
[转帖]shell编程:变量知识进阶(三)的更多相关文章
- SHELL (3) —— 变量知识进阶和实践
摘自:Oldboy Linux运维——SHELL编程实战 SHELL中特殊切重要的变量 位置变量 作用说明 $0 获取当前执行的Shell脚本的文件名,如果执行脚本包含了路径,那么就包括脚本路径 $n ...
- shell编程变量赋值
[shell编程变量赋值] 1.等号两边均不能有空格存在.例, a="hello world" 2.变量和其它文字以{}或空格格开,否则会混淆.例, 有时候变量名可能会和其它文 ...
- shell编程—变量(三)
在shell脚本中,变量分两种,系统变量和自定义变量. 系统默认变量是系统自带的一些变量,如path为路径变量 用户自定义变量为在编写吧脚本的时候自己定义的一些变量 变量名命名规则 首个字符必须为字母 ...
- shell编程-变量
Shell支持自定义变量. 定义变量 定义变量时,变量名不加美元符号($),如: VALUE=“tmp” 注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样.同时,变量名的命名须遵 ...
- Linux_10------Linux之shell编程------变量
.-9 vim num.sh #! /bin/bash num1=$1 num2=$2 sum=$(($num1+$num2)) #变量sum是num1和num2的综合 echo $sum 执行 ./ ...
- Linux Shell编程变量赋值和引用
我们可以使用任意一种文字编辑器,比如gedit.kedit.emacs.vi等来编写shell脚本,它必须以如下行开始(必须放在文件的第一行): #!/bin/sh ... 注意:最好使用“! ...
- Shell编程基础知识(一)
一.基本的运行Linux程序的3种方法: (1) 使文件具有可执行权限,直接运行文件.eg: chmod a+x testfile.sh ./testfile.sh (2) 直接调用命令解释器来 ...
- shell 编程 变量
转自:http://blog.csdn.net/qq504196282/article/details/52994249 shell之变量和引用 分类:SHELL编程基础 (470) (0) 举报 ...
- shell编程基础知识
什么是shell shell是一个命令解释器,它在操作系统的最外层,负责直接与用户对话,把用户的输入解释给操作系统,并处理各种各样的操作系统的输出结果,输出屏幕返回给用户 shell对话方式 交互的方 ...
- 第三章:shell变量知识进阶
特殊变量:位置变量大于9的时候,需要加上(),例如$(10)$*获取脚本的所有参数,如果不加""和$@是一样的效果,如果加上"",则表示所有参数组成一个字符串$ ...
随机推荐
- Python中的协程、线程和进程
一.协程与多线程和多进程一起使用有什么不同 协程.多线程和多进程都是实现程序并发执行的方法,不过它们在工作方式和适合的应用场景上存在一些区别. 1.协程(Coroutine) 协程是在单一线程 ...
- 虚拟化M搭建及基本操作
虚拟化MH搭建 虚拟化概念: 虚拟机安装分为2块:RHEVM .RHEVH RHEVM:负责管理角色 RHEVH:负责运算角色 2016-09-23_0-52-54.png hypervisor: 提 ...
- 一文读懂Spring框架中依赖注入流程
想读懂Spring的依赖注入流程,我们先简单了解一下Ioc和DI是什么? IoC和DI Ioc-Inversion of Control,即"控制反转",不是什么技术,而是一种设计 ...
- 5分钟搞定vue3函数式弹窗
前言 最近接到一个需求,需要在一些敏感操作进行前要求输入账号和密码,然后将输入的账号和密码加到接口请求的header里面.如果每个页面都去手动导入弹窗组件,在点击按钮后弹出弹窗.再拿到弹窗返回的账号密 ...
- 微信小程序数组
常用函数 concat(): 连接两个或多个数组,返回连接后的新数组. 示例:const arr1 = [1, 2, 3]; const arr2 = [4, 5, 6]; const arr3 = ...
- CANN 6.0来了,硬核技术抢先看
摘要:在华为全联接大会2022期间,华为正式官宣昇腾AI异构计算架构CANN 6.0版本将在年底正式发布. 本文分享自华为云社区<昇腾AI异构计算架构CANN 6.0全新开放升级,全面释放AI生 ...
- Kafka 源码解析:Server 端的运行过程
摘要:Kafka网络模块之Server端,介绍Server端启动.接收请求和处理请求的过程. 本文分享自华为云社区<Kafka网络模块-Server端>,原文作者:中间件小哥 . Sock ...
- 带你认识三种kafka消息发送模式
摘要:在kafka-0.8.2之后,producer不再区分同步(sync)和异步方式(async),所有的请求以异步方式发送,这样提升了客户端效率. 本文分享自华为云社区<kafka消息发送模 ...
- 火山引擎DataLeap联合DataFun发布《数据治理知识地图》
近期,火山引擎DataLeap和技术社区DataFun联合发布<数据治理知识地图专业版V1>(以下简称"地图"),地图将数据治理的领域.流程.技术.工具等内容进行系统化 ...
- 【HZERO】消息发送
消息发送 https://open.hand-china.com/community/detail/625843016338378752 新建模板 @Override public String sh ...