微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

bash脚本的奇怪行为

这是一个片段:
var=`ls | shuf | head -2 | xargs cat | sed -e 's/\(.\)/\1\n/g' | shuf | tr -d '\n'`

这将从当前目录中选择两个随机文件,组合它们的内容,将它们进行混洗,并将结果分配给var.这大部分时间工作正常,但是在一千次的情况下,只有ls的输出被绑定到var(这不仅仅是输出,参见EDIT II).什么可以解释?

一些更有潜力的相关事实:

>该目录至少包含两个文件
>目录中只有文本文件
>文件名不包含空格
>文件的长度为5到约1000个字符
>该片段是较大脚本的一部分,它并行运行两个实例
> bash版本:GNU bash,版本4.1.5(1)-release(i686-pc-linux-gnu)
> uname:Linux 2.6.35-28-generic-pae#50-Ubuntu

编辑:我自己运行了这个代码段,几千次,没有错误.然后我尝试运行它与整个脚本的各种其他部分.这是一个产生错误的配置:

cd dir_with_text_files
var=`ls | shuf | head -2 | xargs cat | sed -e 's/\(.\)/\1\n/g' | shuf | tr -d '\n'`
cd ..

cds之间有数百行脚本,但这是重现错误的最小配置.请注意,异常输出绑定到var当前目录的输出,而不是dir_with_text_files.

编辑二:我一直在看更多的输出. ls输出不会单独出现,它连同两个洗牌文件(在其内容之间,或之前或之前,完整).但它变得更好了让我设置舞台来谈谈特定的目录.

[~/projects/upload] ls -1
checked // dir
lines   // dir,the files to shuffle are here
pages   // also dir
proxycheck
singlepost
uploader
indexrefresh
t
tester

到目前为止,我已经看到ls的输出是从上传的,但是现在我看到了ls * / *的输出(也从上传运行).它的形式是“someMangledText ls moreMangledText ls * / * finalBatchOfText”.是否有可能无序地产生的序列ls被执行?

这里也没有问题.
我也会重写上面这个:
sed 's:\(.\):\1\n:g' < <(shuf -e * | head -2 | xargs cat) | shuf | tr -d '\n'

不要使用ls来列出目录内容,请使用*.
此外,做一些调试.使用shebang,然后:

set -e
set -o pipefail

并运行这样的脚本:

/bin/bash -x /path/to/script

并检查输出.
而不是调试整个脚本,您可以围绕似乎与-x有问题的部分

set -x
...code that may have problems...
set +x

所以输出集中在代码的那部分.
另外,使用pipefail选项.

Some deFinitions:

  • -e : Exit immediately if a simple command exits with a non-zero status,unless the command that fails is part of the command list immediately following a while or until keyword,part of the test in an if statement,part of a && or || list,or if the command’s return status is being inverted using !. A trap on ERR,if set,is executed before the shell exits
  • -x : Print a trace of simple commands,for commands,case commands,select commands,and arithmetic for commands and their arguments or associated word lists after they are expanded and before they are executed. The value of the PS4 variable is expanded and the resultant value is printed before the command and its expanded arguments
  • pipefail : If set,the return value of a pipeline is the value of the last (rightmost) command to exit with a non-zero status,or zero if all commands in the pipeline exit successfully

原文地址:https://www.jb51.cc/bash/386471.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐