我正在编写一个 shell 脚本,它应该比较安全,也就是说,不通过命令的参数传递安全数据,最好不使用临时文件。如何将变量传递给命令的标准输入?
或者,如果不可能,我如何正确地使用临时文件执行这样的任务?
试试这个:
echo "$variable" | command
echo
像这样简单的东西就能解决问题:
echo "$blah" | my_cmd
请注意,如果 $blah包含 -n、 -e、 -E等等,这可能不会正常工作; 或者如果它包含反斜杠(在缺省情况下,echo的 bash 副本保留字面反斜杠,但是将它们视为转义序列,并用相应的字符替换它们,即使没有 -e,如果可选的 XSI 扩展被启用)。
$blah
-n
-e
-E
printf
printf '%s\n' "$blah" | my_cmd
这样做没有上面列出的缺点: 所有可能的 C 字符串(不包含 NULs 的字符串)都保持不变地打印出来。
(cat <<END $passwd END ) | command
实际上并不需要 cat,但它有助于更好地构造代码,并允许您使用括号中的更多命令作为命令的输入。
cat
在 Bash 中向标准输入传递一个值非常简单:
your-command <<< "$your_variable"
始终确保在变量表达式周围加引号!
请注意,这可能只在 bash中起作用,在 sh中不起作用。
bash
sh
注意,‘ echo "$var" | command操作意味着标准输入仅限于回显的行。如果你也想要终端连接,那么你需要更花哨一些:
echo "$var" | command
{ echo "$var"; cat - ; } | command ( echo "$var"; cat - ) | command
这意味着第一行(s)将是 $var的内容,但其余的将来自 cat读取其标准输入。如果命令没有做什么太花哨的事情(试着打开命令行编辑,或者像 vim那样运行) ,那么就没问题。否则,你需要变得非常花哨-我认为 expect或其衍生物之一可能是合适的。
$var
vim
expect
命令行符号实际上是相同的——但是第二个分号对于大括号是必需的,而对于括号则不必。
根据 马丁的回答,有一个名为 Here-Strings”rel = “ nofollow noReferrer”> Here Strings 的 Bash 特性(它本身是支持更广泛的 此处文件特性的一个变体) :
3.6.7这里字符串 本文档的一个变体格式如下: <<< word 该单词在其标准上展开并提供给命令 输入。
3.6.7这里字符串
本文档的一个变体格式如下:
<<< word
该单词在其标准上展开并提供给命令 输入。
请注意,Here String 似乎是仅 Bash 的,因此,为了提高可移植性,您可能最好使用原始的 Here Document 特性,如 PoltoS 的回答所示:
( cat <<EOF $variable EOF ) | cmd
或者,上面提到的一个更简单的变体:
(cmd <<EOF $variable EOF )
您可以省略 (和 ),除非您希望将它们进一步重定向到其他命令。
(
)
我喜欢 马丁的回答,但它有一些问题取决于什么是在变量
your-command <<< """$your_variable"""
如果你的变量包含 "或者 !就更好了。
"
!
这种健壮和可移植的方式已经出现在评论中,它应该是一个独立的答案。
printf '%s' "$var" | my_cmd
或者
printf '%s\n' "$var" | my_cmd
Notes:
printf "$var"
%s
\n
通常变量不包含尾随换行符。前一个命令(使用 %s)按原样传递变量。然而,处理文本的工具可能会忽略或抱怨一个不完整的行(参见 为什么文本文件以换行结束)。因此,您可能需要后一个命令(使用 %s\n) ,它将一个换行符附加到变量的内容中。不明显的事实:
%s\n
<<<"$var" my_cmd
my_cmd
如果你来自一个复制品,你可能是一个初学者谁尝试做一些像
"$variable" >file
"$variable" | wc -l
你明显是想说什么
echo "$variable" >file echo "$variable" | wc -l
(真正的初学者也会忘记引号; 除非你有特定的理由去省略它们,至少在你理解引号之前。)