Bash 是否可以在不关闭输入流的情况下将输入流的前导字节复制到另一个文件?

Bash 是否可以在不关闭输入流的情况下将输入流的前导字节复制到另一个文件?,bash,stdin,head,Bash,Stdin,Head,我基本上是在问为什么: head -c 2 > /tmp/first-two-bytes cat /tmp/first-two-bytes - 不将stdin的前两个字节复制到/tmp/前两个字节,然后将stdin的全部内容转储到stout [编辑]为了清楚起见,以下是我的机器上发生的情况: $ uname -a Darwin Myles-Byrnes-iMac.local 11.3.0 Darwin Kernel Version 11.3.0: Thu Jan 12 18:47:41

我基本上是在问为什么:

head -c 2 > /tmp/first-two-bytes
cat /tmp/first-two-bytes -
不将stdin的前两个字节复制到
/tmp/前两个字节
,然后将stdin的全部内容转储到stout

[编辑]为了清楚起见,以下是我的机器上发生的情况:

$ uname -a
Darwin Myles-Byrnes-iMac.local 11.3.0 Darwin Kernel Version 11.3.0: Thu Jan 12 18:47:41 PST 2012; root:xnu-1699.24.23~1/RELEASE_X86_64 x86_64
$ echo "hello, world" | (head -c 2 > /tmp/first-two-bytes; cat /tmp/first-two-bytes -)
he$ cat /tmp/first-two-bytes 
he$

流中的每个字节只能读取一次。完全有可能实现head以使其仅读取2个字节,但也有可能实现head以读取整个流并仅输出前2个字节。如果使用后一种实现,则标准输出将在cat看到任何数据之前耗尽


如果您希望head的功能能够保证从输入流中准确读取2个字节的数据,并且最大限度地可移植,那么您可能需要使用dd。只需将
head-C2
替换为
dd bs=2 count=1

您的命令就可以完全执行它们应该执行的操作。请记住,流不是文件。从流中读取的内容将从流中删除。没有倒带(除非您自己在应用程序中使用缓冲区实现它-但它将在应用程序中,而不是流的属性)。第一个命令从stdin读取2个字节。另一个从/tmp和“stdin的全部内容”输出文件,但在调用时,stdin的“全部内容”已经比上一个命令执行前少了两个字节。

从以下命令可以看出,行为与您描述的一样:

$ echo "hello, world" | (head -c 2 > /tmp/first-two-bytes; cat /tmp/first-two-bytes -)
hello, world
$ cat /tmp/first-two-bytes
he$

请注意,最后一个
$
是提示

如果我理解正确,您希望只将标准输入的前两个字节写入特殊文件,然后将整个输入(包括前两个字节)打印到标准输出

我是这样做的:

while read -r -n2 c2; do
    if [ ! -f tmp.txt ]; then
        echo $c2 > tmp.txt
    fi
    echo $c2
done < input.txt
读取时-r-n2 c2;做
如果[!-f tmp.txt];然后
echo$c2>tmp.txt
fi
echo$c2
完成

基本上,您首先将输入读入一个变量,一次读入两个字节,然后只写入前两个字节。

它实现了您在我的示例中所期望的功能。你要发送给stdin的是什么?对我也很有用,但请看下面我的回答。出于好奇,如果输入超过8K,你会得到多少输出?我猜head读取4K或8K的数据,如果你有足够的输入,猫会得到其中的一部分。只是在一个更大的文件上尝试了一下,这就是正在发生的事情。谢谢你的回答,曼尼什。在这种情况下,我正在寻找一种解决方案,它不会将所有标准输入读入内存。@Quackduck现在更新了它,以便逐行读取输入。嗨,Manish,再次感谢您的关注。我曾考虑过使用read,但我担心它不会是二进制安全的。我确实想读取前两个字节,而不是前两个字符。程序将接收二进制文件作为输入。@quackduck好的,我不知道它是二进制文件。我已经更新了我的答案。您可以使用
read-r-n2
一次最多读取两个字节。对。这正是我所期望的,但它对我不起作用:(不幸的是,我无法在我的机器上重现这种行为。可能是达尔文的脑袋(双关语)有点不同吗?我不知道他们是使用GNU coreutils还是有自己的。头--version说什么?我看到了后者的行为case@quackingduck这意味着您的head实现正在从输入流读取所有数据,这对于head来说是完全有效的行为在从流中读取正好两个字符时,请尝试:perl-e'sysread STDIN,$v,2;print$v'Thank william。我试图避免对脚本语言的任何依赖,因为我打算打包一个脚本来分发脚本。@quackduck您可以使用dd:'dd bs=2 count=1'将从输入流中读取正好两个字节,并且无处不在。