SHUF产生“错误的文件描述符”错误在NFS上,但只有当作为后台进程

问题描述:

这是一个有趣的谜...
此代码运行...SHUF产生“错误的文件描述符”错误在NFS上,但只有当作为后台进程

shuf $TRAINING_UNSHUFFLED > $TRAINING_SHUFFLED 
wc -l $TRAINING_UNSHUFFLED 
wc -l $TRAINING_SHUFFLED 

shuf $VALIDATION_UNSHUFFLED > $VALIDATION_SHUFFLED 
wc -l $VALIDATION_UNSHUFFLED 
wc -l $VALIDATION_SHUFFLED 

产生这个错误...

shuf: read error: Bad file descriptor 
8122 /nfs/digits/datasets/com-aosvapps-distracted-driving3/databases/TrainImagePathsAndLabels_AlpineTest1.csv 
0 /nfs/digits/datasets/com-aosvapps-distracted-driving3/databases/TrainImagePathsAndLabels_AlpineTest1_Shuffled.csv 

shuf: read error: Bad file descriptor 
882 /nfs/digits/datasets/com-aosvapps-distracted-driving3/databases/ValImagePathsAndLabels_AlpineTest1.csv 
0 /nfs/digits/datasets/com-aosvapps-distracted-driving3/databases/ValImagePathsAndLabels_AlpineTest1_Shuffled.csv 

,但只有当我运行它像这样后台作业...

​​

当我在交互式shell中直接运行它时,它似乎工作正常。

tf2$./shuffle.sh > /tmp/shuffle.log 

我猜,这事做的事实,输入和输出文件驻留在NFS共享上的不同AWS EC2实例。

stdin,stderr和stdin在后台进程示例中的切断是可疑的。这样做是为了在终端会话关闭的情况下进程不会死亡。我有许多其他的命令可以从这个共享中读取和写入,没有任何问题。只有shuf命令很困难。

我很好奇这可能是什么原因造成的,如果可以修复而不寻求shuf的替代方案?

我在Ubuntu 14.04.5 LTS上使用shuf(GNU coreutils)8.21。

tf2$which shuf 
/usr/bin/shuf 

tf2$shuf --version 
shuf (GNU coreutils) 8.21 
Copyright (C) 2013 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 Paul Eggert. 

tf2$lsb_release -a 
No LSB modules are available. 
Distributor ID: Ubuntu 
Description: Ubuntu 14.04.5 LTS 
Release: 14.04 
Codename: trusty 

UPDATE:消除STDIN的切断,使问题消失

即。如果不是这样......

$nohup ./shuffle.sh > /tmp/shuffle.log 2>&1 0>&- & 

我做到这一点...

$nohup ./shuffle.sh > /tmp/shuffle.log 2>&1 & 

“坏描述符” 错误消失。

但是,stdin/stdout/stderr的切断是为了确保杀死终端会话不会终止进程,所以这个解决方案并不完全令人满意。

此外,它似乎只需要为shuf做到这一点。从该文件系统读取文件的其他命令都不会导致任何错误。

原来是glibc中的一个bug。
的细节在这里:
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=25029

的解决办法是简单:
代替

shuf $TRAINING_UNSHUFFLED > $TRAINING_SHUFFLED 

shuf < $TRAINING_UNSHUFFLED > $TRAINING_SHUFFLED 

感谢哈灵顿布雷迪上的coreutils队。