为什么我想在打印到标准输出时避免使用“printf”这种类似于回显的方式?

为什么我想在打印到标准输出时避免使用“printf”这种类似于回显的方式?

printf当我试图了解如何工作时,我编写了以下脚本:

#!/usr/bin/bash

printf "Give me your three preferences.?
"
read p1
read p2
read p3
printf "%s\n" "${p1}" "${p2}" "${p3}"
printf "Just the same as this, \n"
printf "%s\n%s\n%s\n" "${p1}" "${p2}" "${p3}"
printf "I've found this way to be the easiest, ${p1}\n ${p2}\n ${p3}\n"

通过反复试验,我发现第三种方法有效 - 尽管它未指定此学习资源。我printf最常使用这种方式,因为它类似于echo-。是否存在这种打印值的方式stdout不起作用的变量情况或值?为什么我想避免这种使用方式printf

答案1

为什么我想避免这种使用 printf 的方式?

正如 FelixJN 提到的,您的最后printf一个格式仅包含用户提供的数据。尝试您的脚本并输入类似“我的第一选择是 %s”之类的内容。在你的最后一种情况下,它不会打印%s而是将其解释为缺少参数的格式说明符(因此%s替换为任何内容):

$ p1="%s"
$ printf "I've found this way to be the easiest, ${p1}\n"
I've found this way to be the easiest, 

在其他语言中,例如 C,这甚至可以被视为安全漏洞,因为它处理错误格式字符串的方式不像 Bash 那样宽松。称为“格式字符串漏洞”或“不受控制的格式字符串”。

答案2

printf命令的构建方式类似于

printf format [argument]...

即,您的最后一个选项是仅正式打印格式,并且不应用该格式的参数。这很好。优点是printf参数可以被专门格式化,例如用零填充或定义最大字符串长度。

您不需要这些,但说实话,echo对于该用例来说就足够了。

相关内容