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

相关文章

用的openwrt路由器,家里宽带申请了动态公网ip,为了方便把2...
#!/bin/bashcommand1&command2&wait从Shell脚本并行...
1.先查出MAMP下面集成的PHP版本cd/Applications/MAMP/bin/ph...
1、先输入locale-a,查看一下现在已安装的语言2、若不存在如...
BashPerlTclsyntaxdiff1.进制数表示Languagebinaryoctalhexa...
正常安装了k8s后,使用kubect工具后接的命令不能直接tab补全...