这是一个片段:
var=`ls | shuf | head -2 | xargs cat | sed -e 's/\(.\)/\1\n/g' | shuf | tr -d '\n'`
这将从当前目录中选择两个随机文件,组合它们的内容,将它们混洗,并将结果分配给var。这在大多数情况下都可以正常工作,但是在大约一千个案例中,只有ls
的输出被绑定到var(它不仅仅是输出,请参阅编辑II)。可能是什么解释?
一些可能相关的事实:
GNU bash, version 4.1.5(1)-release (i686-pc-linux-gnu)
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 ..
cd
之间有几百行脚本,但这是重现错误的最小配置。请注意,异常输出绑定到var当前目录的输出,而不是dir_with_text_files
。
编辑II:我一直在更详细地查看输出。 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
的输出来自upload
,但现在我看到ls */*
的输出(也来自upload
)。它的形式为“someMangledText ls
moreMangledText ls */*
finalBatchOfText”。毫无疑问,生成的序列ls
是否可能以某种方式执行?
答案 0 :(得分:2)
这里也没有问题。 我还要重写上面的内容:
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
选项。
一些定义:
-e
:如果一个简单的命令以非零状态退出,则立即退出,除非失败的命令是紧跟在while或until关键字之后的命令列表的一部分,if语句中的部分测试,&amp;&amp;和或||列表,或者如果使用!反转命令的返回状态。 ERR上的陷阱(如果已设置)在shell退出之前执行- 之前打印结果值
-x
:打印一系列简单命令,用于命令,大小写命令,选择命令,以及命令及其参数或相关单词列表在扩展后和执行之前的算术运算。扩展PS4变量的值,并在命令及其扩展参数pipefail
:如果设置,管道的返回值是以非零状态退出的最后一个(最右边)命令的值,如果管道中的所有命令都成功退出则为零
答案 1 :(得分:1)
出于调试目的,您还可以使用env -i
清除环境并过滤掉不可打印的字符:
#!/usr/bin/env -i /bin/bash --
set -ef
set -o pipefail
unset IFS PATH LC_ALL
IFS=$' \t\n'
PATH="$(PATH=/bin:/usr/bin getconf PATH)"
LC_ALL=C
export IFS PATH LC_ALL
#var="$((find . -type f -maxdepth 1 -print0 | shuf -z -n 2 | xargs -0 cat) | sed -e 's/\(.\)/\1\n/g' | shuf | tr -d '\n')"
var="$((find . -type f -maxdepth 1 -print0 | shuf -z -n 2 | xargs -0 cat) | tr -cd '[[:print:]]' | grep -o '.' | shuf | tr -d '\n')"
在运行脚本之前,您还可以禁用GNU readline库和!风格历史扩展:
bash --noediting
set +H
答案 2 :(得分:0)
根据你对你的失败率所说的话,并且考虑到上述海报所执行的其他测试的成功,这听起来像偶尔的目录更改失败可能导致的问题。您在此脚本中访问的目录是否偶然从远程计算机挂载?如果是这样,它可能只是一个小的和临时的网络相关的故障,没有得到妥善处理。 (只是一个猜测。)