我有一个虚拟问题要问你,我正在尝试从文件中提取以特殊字符串开头的一些行并将它们复制到文件中。我试过 :
cat /dev/ttyACM0 | grep "something" > essai
该文件已创建,但它不包含任何内容!
答案1
为了提高效率,grep 和许多其他命令使用缓冲输入/输出,也就是说,它们一次读取大块数据(而不是一次一个字符),并且在积累到一定数量之前不输出数据(而不是一次写入一行或一次一个字符)
但是,当程序的输入来自终端(例如串行端口)时,操作系统会帮助程序并一次返回一行(程序可以通过将终端放入生的或者非规范模式;大多数人没有)。
当程序使用标准输入输出库中,到终端(文档称其为“交互式设备”)的标准输出默认情况下是行缓冲的,但到文件或管道的输出是完全缓冲的。
使用 stdio 库的程序可以通过调用选择全缓冲、行缓冲或无缓冲setvbuf
。也可以调用fflush
随时强制写入。
GNU grep 需要一个--line-buffered
选项,这将运行以下代码在输出匹配行的函数中:
if (line_buffered)
fflush (stdout);
将所有部分放在一起:
使用此命令:
cat /dev/ttyACM0 | grep "something" > essai
cat
每次从 读取一行/dev/ttyACM0
。积累了几千字节的输出后,它将写入管道。它将重复此操作,直到读取返回计数为零或失败(这可能在串行端口脱机之前不会发生)。
grep
将从管道一次读取几千字节,并在积累了几千字节的输出后,它将写入文件essai
。它将重复此操作,直到读取返回计数为零或失败,如果进程cat
退出,就会发生这种情况。
因此,在找到几千字节的匹配行之前,您不会看到essai
文件中出现任何内容。grep
为了更迅速地将输出写入文件,您可以为 GNU grep 提供该选项:
grep --line-buffered < /dev/ttyACM0 > essai
由于它是从串行端口读取,因此它将被行缓冲,并且该--line-buffered
选项也会使输出行缓冲。