[转帖]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)$*获取脚本的所有参数,如果不加""和$@是一样的效果,如果加上"",则表示所有参数组成一个字符串$ ...
随机推荐
- 欢迎 Mixtral - 当前 Hugging Face 上最先进的 MoE 模型
最近,Mistral 发布了一个激动人心的大语言模型: Mixtral 8x7b,该模型把开放模型的性能带到了一个新高度,并在许多基准测试上表现优于 GPT-3.5.我们很高兴能够在 Hugging ...
- Pikachu漏洞靶场 ../../(目录遍历)
目录遍历 概述 在web功能设计中,很多时候我们会要将需要访问的文件定义成变量,从而让前端的功能便的更加灵活.当用户发起一个前端的请求时,便会将请求的这个文件的值(比如文件名称)传递到后台,后台再执行 ...
- JavaScript apply、call、bind 函数详解
apply和call apply和call非常类似,都是用于改变函数中this的指向,只是传入的参数不同,等于间接调用一个函数,也等于将这个函数绑定到一个指定的对象上: let name = 'win ...
- 记一次uboot编译/经验/教训
记一次uboot编译/经验/教训 - 最近学习uboot移植有关的知识,在了解原理后自己编译uboot,但是出现了好多各式各样的错误,最后换了几次系统环境之后才找到错误来源 1.准备源码与交叉编译工具 ...
- 前端js常用的60余种工具方法【强烈建议收藏】
"工欲善其事,必先利其器!"本文为大家带来前端js开发常用的60种工具方法,有了这些开发工具你就可以高效的处理任务和信息了. 1.邮箱 export const isEmail = ...
- 昇腾实战丨DVPP媒体数据处理视频解码问题案例
摘要:本期就分享几个关于DVPP视频解码问题的典型案例,并给出原因分析及解决方法 本文分享自华为云社区<DVPP媒体数据处理视频解码问题案例>,作者:昇腾CANN . DVPP(Digit ...
- 为AR&VR黑科技:以“自由视角”360度尽展舞台唯美
摘要:看华为的黑科技,如何用"自由视角"让观众感受舞台"风暴"的魅力所在. "风暴"降临 2021年1月9日晚上,我坐在电视机前,等待湖南卫 ...
- 基于KubeEdge的边缘节点分组管理设计与实现
摘要:KubeEdge 1.11版本提供了"边缘节点分组管理"新特性,抽象出了跨地域的应用部署模型. 本文分享自华为云社区<基于KubeEdge的边缘节点分组管理设计与实现& ...
- 云图说|华为云自研云数据库GaussDB NoSQL,兼容多款NoSQL接口的数据库服务
摘要:云数据库GaussDB NoSQL是一款基于计算存储分离架构的分布式多模NoSQL数据库服务,兼容多款nosql接口,在灵活弹性.快速扩展方面做到了极致. 本文分享自华为云社区<云图说|华 ...
- 企业新道路怎么走?火山引擎AB测试助力决策选择
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 乐刻是一家创立8年的企业,除了消费者熟悉的乐刻健身房可办月卡.24小时营业等,其还有比外界了解更多元的业务.目 ...