小编rua*_*akh的帖子

如何在 Bash 中使用空字节?

我读过,因为 Bash 中的文件路径可以包含除空字节(零值字节$'\0')之外的任何字符,所以最好使用空字节作为分隔符。例如,如果将 的输出find发送到另一个程序,则建议使用该-print0选项(对于find具有它的版本)。

但是,虽然这样的事情工作正常(打印由换行符分隔的文件路径 - 别担心,这只是一个演示,我实际上并没有在实际脚本中这样做):

find -print0 \
  | while IFS= read -r -d $'\0' ; do echo "$REPLY" ; done
Run Code Online (Sandbox Code Playgroud)

这样的事情就不会工作:

for file in * ; do echo -n "$file"$'\0' ; done \
  | while IFS= read -r -d $'\0' ; do echo "$REPLY" ; done
Run Code Online (Sandbox Code Playgroud)

当我只尝试for-loop 部分时,我发现它只是将所有文件名打印在一起,中间没有空字节。

为什么是这样?这是怎么回事?

bash null

39
推荐指数
1
解决办法
3万
查看次数

管道,数据如何在管道中流动?

我不明白管道中的数据是如何流动的,希望有人能澄清那里发生了什么。

我认为命令管道以逐行方式处理文件(文本、字符串数组)。(如果每个命令本身逐行工作。)每行文本都通过管道,命令不会等待前一个完成处理整个输入。

但似乎并非如此。

这是一个测试示例。有几行文字。我将它们大写并重复每行两次。我这样做cat text | tr '[:lower:]' '[:upper:]' | sed 'p'

为了遵循这个过程,我们可以“交互地”运行它——跳过cat. 管道的每个部分逐行运行:

$ cat | tr '[:lower:]' '[:upper:]'
alkjsd
ALKJSD
sdkj
SDKJ
$ cat | sed 'p'
line1
line1
line1
line 2
line 2
line 2
Run Code Online (Sandbox Code Playgroud)

但是完整的管道确实等待我完成输入,EOF然后才打印结果:

$ cat | tr '[:lower:]' '[:upper:]' | sed 'p'
I am writing...
keep writing...
now ctrl-D
I AM WRITING...
I AM WRITING...
KEEP WRITING...
KEEP WRITING...
NOW CTRL-D
NOW CTRL-D
Run Code Online (Sandbox Code Playgroud)

应该是这样吗?为什么不是一行一行的?

shell pipe text-processing buffer stdout

22
推荐指数
2
解决办法
3134
查看次数

标签 统计

bash ×1

buffer ×1

null ×1

pipe ×1

shell ×1

stdout ×1

text-processing ×1