Bash file命令中的进程替换出现问题

Bash file命令中的进程替换出现问题,bash,shell,pipe,Bash,Shell,Pipe,更容易表现为试图用文字描述 find-名称jo\*-打印>列表 猫名单 #/工作1 #/工作2 #/工作3 #通过从文件“列表”中读取文件列表来创建“文件” 文件-f列表 #./jo1:ASCII文本 #/jo2:ASCII文本 #./jo3:ASCII文本 #现在是进程替换 file-f你做得对。这是您实现的文件中的一个bug,我可以在我的文件(Debian jessie上的文件5.22)中复制它。它希望参数-f是可查找的文件,并且在文件不可查找时不会检测到错误。这就是为什么它可以使用常规文件

更容易表现为试图用文字描述

find-名称jo\*-打印>列表
猫名单
#/工作1
#/工作2
#/工作3
#通过从文件“列表”中读取文件列表来创建“文件”
文件-f列表
#./jo1:ASCII文本
#/jo2:ASCII文本
#./jo3:ASCII文本
#现在是进程替换

file-f你做得对。这是您实现的
文件
中的一个bug,我可以在我的文件(Debian jessie上的文件5.22)中复制它。它希望参数
-f
是可查找的文件,并且在文件不可查找时不会检测到错误。这就是为什么它可以使用常规文件,但不能使用管道(流程替换使用管道在两个流程之间传递数据)

您可以观察strace的运行情况:

$ strace file -f <(echo foo)
…
open("/proc/self/fd/13", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
…
read(3, "foo\n", 4096)                 = 5
…
read(3, "", 4096)                       = 0
lseek(3, 0, SEEK_SET)                   = -1 ESPIPE (Illegal seek)
read(3, "", 4096)                       = 0
close(3)                                = 0

如果文件名不是
-
(指示从标准输入读取),则代码将读取文件两次,一次用于确定文件名的最大宽度,一次用于处理文件。对
回放的调用缺少错误处理。使用
-
作为文件名,代码不会尝试对齐列。

如果不使用
之间的差异,文件名中的空格是否正确,将导致解决方案出现问题,例如文件$(find.-name jo*-printf%f“”)(虽然示例中没有空格,因此假设没有空格可处理)考虑空格的替代解决方案是find.-name jo*-exec file'{}\;我知道如何解决问题(一种方法是您的建议,另一种方法是
find…| file-f-
,这里至少有两种其他方法。)但是这个问题的优点是为什么流程替换不起作用?(我得到了公认的答案:))无论如何,谢谢你的关注。
diff <(some command) <(another command)
diff /dev/fd/... /dev/fd/...
grep -f <(command_for_produce_the_patterns) files..
grep -f /dev/fd/63 files....
file -f <(command)
$ strace file -f <(echo foo)
…
open("/proc/self/fd/13", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
…
read(3, "foo\n", 4096)                 = 5
…
read(3, "", 4096)                       = 0
lseek(3, 0, SEEK_SET)                   = -1 ESPIPE (Illegal seek)
read(3, "", 4096)                       = 0
close(3)                                = 0
private int
unwrap(struct magic_set *ms, const char *fn)
{
    // …
    if (strcmp("-", fn) == 0) {
            f = stdin;
            wid = 1;
    } else {
        if ((f = fopen(fn, "r")) == NULL) {
                (void)fprintf(stderr, "%s: Cannot open `%s' (%s).\n",
                    progname, fn, strerror(errno));
                return 1;
        }
        while ((len = getline(&line, &llen, f)) > 0) {
            // … code to determine column widths
        }
        rewind(f);
    }
    // Code to read the file names from f follows
}