bash 如何将变量的值传递给命令的标准输入?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4775548/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 20:06:36  来源:igfitidea点击:

How to pass the value of a variable to the stdin of a command?

securitybashstdin

提问by Martin

I'm writing a shell script that should be somewhat secure i.e. does not pass secure data through parameters of commands and preferably does not use temporary files. How can I pass a variable to the stdin of a command? Or, if it's not possible, how to correctly use temporary files for such task?

我正在编写一个应该有点安全的 shell 脚本,即不通过命令参数传递安全数据,最好不使用临时文件。如何将变量传递给命令的标准输入?或者,如果不可能,如何正确使用临时文件来完成此类任务?

采纳答案by Oliver Charlesworth

Something as simple as:

像这样简单的事情:

echo "$blah" | my_cmd

回答by Martin

Passing a value to stdinin bashis as simple as:

stdinbash 中传递一个值非常简单:

your-command <<< "$your_variable"

Always make sure you put quotes around variable expressions!

始终确保在变量表达式周围加上引号!

Be cautious, that this will probably work only in bashand will not work in sh.

请注意,这可能仅bash适用于sh.

回答by Jonathan Leffler

Note that the 'echo "$var" | commandoperations mean that standard input is limited to the line(s) echoed. If you also want the terminal to be connected, then you'll need to be fancier:

请注意, 'echo "$var" | command操作意味着标准输入仅限于回显的行。如果您还希望连接终端,那么您需要更高级:

{ echo "$var"; cat - ; } | command

( echo "$var"; cat -   ) | command

This means that the first line(s) will be the contents of $varbut the rest will come from catreading its standard input. If the command does not do anything too fancy (try to turn on command line editing, or run like vimdoes) then it will be fine. Otherwise, you need to get really fancy - I think expector one of its derivatives is likely to be appropriate.

这意味着第一行将是内容,$var但其余的将来自cat读取其标准输入。如果命令没有做任何太花哨的事情(尝试打开命令行编辑,或者像vim这样运行),那么它会很好。否则,你需要变得非常花哨——我认为expect或者它的一种衍生物可能是合适的。

The command line notations are practically identical - but the second semi-colon is necessary with the braces whereas it is not with parentheses.

命令行符号实际上是相同的 - 但第二个分号与大括号是必需的,而没有括号。

回答by PoltoS

(cat <<END
$passwd
END
) | command

The catis not really needed, but it helps to structure the code better and allows you to use more commands in parentheses as input to your command.

cat是不是真的需要,但它有助于更好地结构中的代码,并允许您在括号中使用更多的指令输入到你的命令。

回答by Robert Jacobs

I liked Martin's answer, but it has some problems depending on what is in the variable. This

我喜欢马丁的回答,但根据变量中的内容,它有一些问题。这个

your-command <<< """$your_variable"""

is better if you variable contains " or !

如果变量包含 " 或 !

回答by cnst

As per Martin's answer, there is a bash feature called Here Strings(which itself is a variant of the more widely supported Here Documentsfeature).

根据 Martin 的回答,有一个名为Here Strings的 bash 功能(它本身是更广泛支持的Here Documents功能的变体)。

http://www.gnu.org/software/bash/manual/bashref.html#Here-Strings

http://www.gnu.org/software/bash/manual/bashref.html#Here-Strings

3.6.7 Here Strings

A variant of here documents, the format is:

<<< word

The word is expanded and supplied to the command on its standard input.

3.6.7 这里的字符串

此处文档的一个变体,格式为:

<<< word

这个词被扩展并提供给它标准输入上的命令。

Note that Here Strings would appear to be bash-only, so, for improved portability, you'd probably be better off with the original Here Documents feature, as per PoltoS's answer:

请注意,根据 PoltoS 的回答,Here Strings 似乎仅适用于 bash,因此,为了提高可移植性,您最好使用原始的 Here Documents 功能:

( cat <<EOF
$variable
EOF
) | cmd

Or, a simpler variant of the above:

或者,上述更简单的变体:

(cmd <<EOF
$variable
EOF
)

You can omit (and ), unless you want to have this redirected further into other commands.

您可以省略(and ),除非您希望将其进一步重定向到其他命令中。

回答by unbeli

Try this:

尝试这个:

echo "$variable" | command

回答by Kamil Maciorowski

This robust and portable way has already appeared in comments. It should be a standalone answer.

这种健壮和便携的方式已经出现在评论中。它应该是一个独立的答案。

printf '%s' "$var" | my_cmd

or

或者

printf '%s\n' "$var" | my_cmd

Notes:

笔记:

  • It's better than echo, reasons are here: Why is printfbetter than echo?
  • printf "$var"is wrong. The first argument is format where various sequences like %sor \nare interpreted. To pass the variable right, it must not be interpreted as format.
  • Usually variables don't contain trailing newlines. The former command (with %s) passes the variable as it is. However tools that work with text may ignore or complain about an incomplete line (see Why should text files end with a newline?). So you may want the latter command (with %s\n) which appends a newline character to the content of the variable. Non-obvious facts:

    • Here string in Bash (<<<"$var" my_cmd) does append a newline.
    • Any method that appends a newline results in non-empty stdin of my_cmd, even if the variable is empty or undefined.
  • 它比 好echo,原因在这里:为什么printf比 好echo
  • printf "$var"是错的。第一个参数是格式,其中各种序列喜欢%s\n解释。要正确传递变量,不得将其解释为格式。
  • 通常变量不包含尾随换行符。前一个命令 (with %s) 按原样传递变量。然而,处理文本的工具可能会忽略或抱怨不完整的行(请参阅为什么文本文件应以换行符结尾?)。因此,您可能需要后一个命令 (with %s\n),它将换行符附加到变量的内容中。不明显的事实:

    • 这里 Bash ( <<<"$var" my_cmd) 中的string确实附加了一个换行符。
    • 任何附加换行符的方法都会导致 的非空标准输入my_cmd,即使变量为空或未定义。

回答by Clox

Just do:

做就是了:

printf "$my_var" | my_cmd

If the var doesn't contain spaces then the quotes may be omitted.
If using bash then you may also do:

如果 var 不包含空格,则可以省略引号。
如果使用 bash 那么你也可以这样做:

echo -n "$my_var" | my_cmd

Avoid using echo without -n because it will pipe the vraiable with an added linebreak at the end.

避免在没有 -n 的情况下使用 echo,因为它会在末尾添加换行符来管理 vraiable。