shell-不定参数
这两天在写shell脚本,因为接到了王老板的安排。先是让我写了个触发器,然后就是将之前别人的脚本优化一下。其实我来这里没多久就把那个脚本重写了,因为之前的那个输出真的很乱,看的我眼睛疼。虽然已经有现成的了,但是距离王老板的要求(简洁、输出重要信息、屏蔽没有的信息),我自认为还差点意思。
刚开始让我写个触发器的时候,我一脸懵,触发器是啥?然后王老板给我找了个别人写的模板,让我对着学一下。哈哈,怕给我压力,然后叫我随便玩一下,说也不重要。这么长时间了,觉得王老板这个人挺好的,等我以后离开这个地方后,我觉得真的还挺舍不得的。学了之后发现和存储过程一样简单,然后一会就写完了,因为之前学了存储过程,里面涉及取变量的操作,做起来就觉得挺简单的。不过用到了一个新的函数sys.guid()
用来生成唯一的标识符,为了避免重复操作导致不能辨别嘛。
然后就是改这个shell脚本了,之前我改了一下,主要是改格式,之前输出没对齐,看着特别乱。然后加了一些上限值的警告,如果正常的话,会在后面输出bingo!
哈哈。但是还是会在屏幕上输出很多信息,也就是刷屏了。然后就是这个上限警告值是写死在里面的,所以这次优化,主要是加入这些功能:
- help信息
- -s 数字 来设置size的上限
- -m 数字 来设置数量上限
- -q 来设置quiet/silent模式,即不刷屏,只显示最后结果。当然想看这些信息的话,就不加这个参数咯
两个点:
- 所有这些都需要通过参数传递进去
- 但是如果没传参数也要有默认值
不用if判断的赋值
:-
or-
如果值为空则赋值
:+
or+
如果值非空就赋值
也可以理解为赋默认值,其实本意是先判断再赋值。按照原意理解的话,就可以省去一个if判断变量是否为空的写法
1 | {variable:-值} |
三目运算
程序写多了,才会发现这些语法的重要性。就好比python的lambda函数,对于一些简单的函数来说简直是好用。这里要说的是shell中的三目运算,其实好多if判断很简单,仅仅是做一个判断加一个赋值,有时候就觉得真的没必要写一个if...then....fi
出来。但是可惜的shell的三目运算仅仅支持数字。
1 | a是否为20,是返回1,否则返回2 |
shell中传参
我之前想的是把所有传递进去的参数作为一个列表或者字符串。因为一个参数后面要跟一个数字,为了取到这个数字,我用的是字符串截取。因为我用shift
老是取不到想要的值。
1 | list=$* |
上面这么写没问题,本来我之前想用shift取参数的,毕竟学过perl嘛,perl就是这么做的,但是我没成功。
是我太愚蠢了:),我每次都是shift一个参数,结果第二个参数就要shift两个,第三个参数又只要shift一个参数。如果传入参数的顺序不变,那没问题。但是。。。。。。谁能保证参数顺序不变,而且程序也不能设计的这个样子吧,我自己都看不下去了。所以傻傻的我google到了正确写法:一次shift两个参数 shift 2
虽然我不知道可以一次可以shift两个参数,但是我想都不敢想,说明我傻。
1 | for i in $* |
这么写多帅啊,不需要字符串截取,不需要awk,不需要子进程,速度也快多了。
shift
说了这么多,还没写它的作用,它就好比从栈中(pop)取数据。不过是从左边取,不带参数的话就是一次取一个参数,取出来的参数是不会放回去的。不过pop
有push
可以放回去,但是shell中shift
为什么没有unshift
呢?perl中就有啊。
不可例外的,还是要写一下这几天的总结:也算是过失吧
第一个:在写shell脚本的时候,因为要重复调用两次相同的代码,所以我就想着用一个函数写吧,这样简单不少。但是我却没考虑到写成了函数之后,它中间的变量问题。如果在函数外已经定义了变量,那好,一点问题都没有。但问题来了,他那个代码中竟然需要接受一个程序外部传进来的参数$1
,所以始终是运行不正常的。后来才发现了这个问题,对于shell函数来说,$1
代表的是传给函数的第一个参数:例如
1 | function getvar(){ |
最终这个$1
接受到的就是666。所以它接受的并不是函数外部传进来的参数。所以这个教训的总结就是变量如果是从程序外部传进来的,二话不说先把这些变量保存下来,所有的都保存也好$*
或者$@
,一个一个的保存也好$1
,$2
。这样就不会出现这个问题了,这也算是一个良好的编程习惯吧。
第二个:如果是改写别人之前写的脚本,不仅要把自己的那部分功能实现,还要弄清楚别人之前写的意图,因为你改了之后就不能保证别人的还一样正确啊,比如说shell环境问题,变量问题,如果是函数的话还要考虑函数位置问题,各个模块的逻辑问题等等。总之不要只看自己写的那部分,就可以提高正确率,减少不必要的纠错时间。