Bash:回显还是 < 更好

Bash:回显还是 < 更好

传递输入时,哪种方法更好?

 > echo 'test' | base64
dGVzdAo=

 > base64 <<< 'test'
dGVzdAo=

同样对于变量,应该使用哪种方法?

 > t='test'

 > echo "$t" | base64
dGVzdAo=

 > base64 <<< "$t"
dGVzdAo=

答案1

<<<zsh是here-string,是here-document (以及 Unix 端口)在 90 年代初引入的缩写形式rc,此后被复制(带有变体)到许多其他 shell。

它的实现方式与此处文档相同。在包括zsh和在内的大多数 shell 中bash,这是通过删除临时文件来实现的,Bourne shell(在 70 年代末引入了此处文档的 shell)就是这样做的。

当你这样做时:

cmd <<< 'something'

shell 做了类似的事情:

file=$(mktemp)
printf 'something\n' > "$file"
{
  rm -f -- "$file" && cmd
} < "$file"

(当然,所有mktemp, printf,rm都是在内部完成的,而不执行这些命令)。

一些 shell 使用管道和单独的进程(可以是分叉命令或小此处文档/字符串的主 shell 进程)来提供数据。某些 shell 可能会恢复使用/dev/null空的此处文档(此处字符串不能为空,除非rc不添加换行符)。

使用临时文件的实现有几个优点。

  • 没有分叉进程。
  • 输入是可查找的(该命令可以在其输入中来回读取数据,以在不同的位置再次读取数据,而当其输入是管道时则无法执行此操作)。不过,您不能在可移植sh脚本中依赖它。

一些缺点:

  • 除了 in 之外zsh,内容不能包含 NUL 字节
  • 除了 in 之外rc,不可能提供不以换行符结尾的输入
  • 临时文件创建可能会失败(例如当没有剩余空间$TMPDIRumask某些实现限制太多时)。
  • 数据存储在永久存储器中。即使文件在被删除之前被删除read,数据也可能最终被提交到磁盘,这意味着如果有人能够获得磁盘,则可以将其恢复。

在:

printf '%s\n' "$something" | cmd

(这里使用printf而不是echoasecho不能用于任意数据)。

我们有两个进程同时运行,一个进程通过管道将输出提供给另一个进程。当cmd是内置命令或复合命令或函数时,使用zsh或 AT&Tkshbash -o lastpipe,该命令在当前 shell 中运行,但否则在子进程中运行,因此类似的操作echo x | read var不起作用。

这样做的一些优点:

  • 是便携式的(与<<<,<<是便携式相反)
  • 没有<<<上面提到的缺点
  • 要在 shell 之外的 shell 中提供 NUL 字节zshzsh是唯一可以将 NUL 字节传递给内置命令的 shell),您可以执行以下操作printf '\0' | cmd

缺点:

  • 额外的进程以及在某些 shell 中的子进程中运行的事实cmd,如上所述
  • 输入不可查找。

请注意,如果您想要 的 base64 编码test,那就是:

printf test | base64

或者

printf %s "$data" | base64

对于任意数据。

您的为您提供了 的 base64 编码test<newline>

相关内容