由于Linux shell中默认定义的变量都是全局的,所以导致在递归函数中定义的变量,在下一层调用中修改了值后,返回上一层,改变量已被修改,导致运行结果不对。
解决办法就是,给相应的变量加上local前缀,表示是局部变量,即可。
问题原因:参数太多
比如,使用
if [ -d $item_full_path ]; then
去判断item_full_path是否为文件夹,但是如果传入的参数是
arm_vs_mips.xml - Copy_bak
,则会出现too many arguments的错误。因为对于shell中的-d去判断一个参数是否为文件夹的时候,此参数,只能是一个字符串,而不能是多个字符串,而此处的
arm_vs_mips.xml - Copy_bak
虽然物理上表示对应的某个文件,但是作为此处的参数传递进来的话,的确就是三个字符串了:
arm_vs_mips.xml - Copy_bak
。
解决办法:自己去找错误的位置,是不是也是由于类似的,使用某个功能的时候,传递的参数,超过该功能所期望的参数的个数了。如果超过了,估计多数情况下,也都是你自己使用不当,或者没有进行合适的处理而导致的。
在用shell过程中,经常会遇到处理文件名中包含空格的问题
对此,参考Linux shell脚本 遍历带空格的文件名,尝试了用tr将ls输出结果替换为问号,的确是可以的:
CLi@PC-CLI-1 ~/develop/docbook/books/arm_vs_mips/src $ ls arm_vs_mips.xml arm_vs_mips_____xml - Copy_bak glossary.xml Makefile remove_bak.sh arm_vs_mips.xml.bak ch01_reduced_instruction_set.xml images reference.xml remove_bak.sh.bak CLi@PC-CLI-1 ~/develop/docbook/books/arm_vs_mips/src $ ls | tr " " "\?" arm_vs_mips.xml arm_vs_mips.xml.bak arm_vs_mips_____xml?-?Copy_bak ch01_reduced_instruction_set.xml glossary.xml images Makefile reference.xml remove_bak.sh remove_bak.sh.bak
cygwin中的tr在shell中工作不正常? -> 实际上是cygwin中的显示有问题 | |
---|---|
不过,另外提及一下,目前遇到一个问题,就是上述的代码: ls | tr " " "\?" 放到shell中执行: local sub_folders=`ls $input_folder | tr "\32" "\?"`; echo '444 sub_folders='$sub_folders; 当时结果是tr无效,输出的效果中文件名中的空格没有被替换为问号。 其中当前环境是用的Cygwin,tr版本为: CLi@PC-CLI-1 ~/develop/docbook/books/arm_vs_mips/src $ tr --version tr (GNU coreutils) 8.15 Packaged by Cygwin (8.15-1) Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Written by Jim Meyering.
后来终于经过一番折腾,而搞清楚了: 把问号换成其他的,比如<,>等: local sub_folders=`ls $input_folder | tr "\32" "\<"`; local sub_folders=`ls $input_folder | tr "\32" "\>"`; 也都是可以看到替换的结果的。 并且也可以用: each_item=`echo $each_item | tr "\<" " "`; each_item=`echo $each_item | tr "\>" " "`; 再替换回来的。 而对于上述的问号替换空格,虽然没有显示出来,但是如果没有此操作的话,后面 for each_item in $sub_folders; do 所得到的每个item中, arm_vs_mips.xml - Copy_bak 就会变成三个字符串: arm_vs_mips.xml - Copy_bak 而有此操作,后面得到的就是一个独立的字符串: arm_vs_mips.xml - Copy_bak 所以明白了根本原因是,Cygwin中,没有正确的显示出来,实际上,是已经替换成功的了。 不过很悲催的是,单独echo问号字符,却又是可以正常显示的。。。 说实话,这样的bug,真的很让人崩溃。。。太浪费时间了。。。 |
用经典的那句中文介绍此书就是,对于Linux Shell的"从入门到精通",^_^
专门提及一下常用的供参考的章节: