将文本传递给需要文件的程序


30

与我在堆栈溢出问题上提出的一个问题有关:将多行代码传递给wsadmin.sh?

作为字符串,我需要输入几行输入到命令中。但是,该命令仅接受充满输入的文件。

有什么方法可以将行存储在从未真正写入磁盘的临时文件或管道中,然后直接将其输入程序中?

我该如何获取管道,将输入馈入管道,将该管道传递给命令,然后摆脱该管道?


2
您可以添加一个示例,说明正在使用的命令以及如何调用该命令吗?
突破

2
这是否意味着该程序不接受标准输入?
Lao Lam 2015年

我同意以上两位评论者的意见。如果不了解程序的规格,就不可能提出任何可行的建议。
拉尔森德(Larssend)

Answers:


27

另一种解决方案是在Bash中使用Process Substitution。如果系统已命名管道,则可以使用此功能。

它的用法如下:

program_expecting_a_file <(list)

其中list是壳的命令序列(实际上管道;完整细节这里)。list将被执行,并且其输出将连接到管道。管道的名称然后传递到您的程序。

注意:<和之间不允许有空格(

(另一个替代项>(list)也可以按照您的预期工作。)

在您的特定情况下,您可以使用

program_expecting_a_file <(echo "$your_strings")

尽管您可能会发现@meuh的解决方案更优雅。

更新:Advanced Bash脚本指南中可以找到很多用法示例。


即使在最琐碎的情况下,其他两个也不起作用。到目前为止,您已经通过了我所进行的测试。我现在投票赞成你的。我会回来并将其标记为“接受”(如果它可以完成我需要的一切)。
ArtOfWarfare 2015年

您的作品完美无缺。如果您愿意,可以将其添加到StackOverflow上的相关问题中,我也可以在那里接受。stackoverflow.com/questions/31374202/...
ArtOfWarfare

嗨@ArtOfWarfare,很高兴能为您提供帮助。那里已经有使用相同提议解决方案的评论,因此在此处发布答案对我来说是不合适的。
爱德华

您在他之前发布了解决方案。无论如何,我已经请他将他的评论更改为答案,以便我接受。如果你们俩都没有在约24小时内发布关于该问题的答案,我会自己发布答案,这样我才能接受(我不希望自己的问题在找到答案后不再显示。)对于未来的读者/潜在的问题
回答者来说

嗨,@ ArtOfWarfare,我对您的建议绝对满意!
爱德华

15

您可以在此处使用bash -doc。例如,

$ cat -n <<<'a
> b'
 1  a
 2  b

如果bash变量中包含某些内容,也可以对其进行插值:例如<<<"path is $PATH"


如果您的命令坚持使用文件名,则可以给它/dev/stdin。例如:

$ sed -f /dev/stdin <<<'s/a/b/'

产生输出:s/b/b/


从这个问题尚不清楚,该命令是否接受上的输入stdin,如果不接受,将无法正常工作。我希望OP能够澄清。
David Z

1
:(-这似乎很有前途,但是当我尝试时,出现错误信息 "-f" option must be followed by a file name.
ArtOfWarfare 2015年

此处文档适用于stdin。如果您的命令绝对需要-f一个文件名,请提供filename /dev/stdin。看到我的编辑。
u

我认为编辑后绝对是一个可行的选择!
爱德华

1
+1的/dev/stdin建议。我尝试调用的程序仅接受文件名,因此我将其/dev/stdin与heredoc 结合使用。
Huw Walters

7

根据脚本中的内容,您也许可以使用特殊的文件名-(减号),代表标准输入

$ mycmd -
Line 1
Line 2
^D

另一种对您有用的方法是打开/dev/fd/0再次代表stdin的文件。

第三种选择可能是创建一个FIFO(先进先出)。这就像一个文件,但它有两个目的-您要写入一个末端,然后从另一末端读取。

-- Process 1 --                  -- Process 2 --
$ mkfifo foo
$ cat foo
<waits>                          $ echo hello > foo
hello                            $
$ rm foo

3
可能值得注意的是,必须以-这种方式编写程序才能解释-它不是Shell或操作系统的功能。据我所知,当然大多数标准Linux实用程序都遵循此约定。
David Z

1
不。这不适用于该程序。有一个交互模式,但是我想将命令从另一个程序传递给该程序,并且我不想进入expect
ArtOfWarfare 2015年

@ArtOfWarfare我刚刚添加了第三个可能有效的选项。
Majenko

好答案!第二个和第三个选项基本上类似于<()解决方案,但更明确-可能非常有用!
爱德华

4

还有另一个类似于 mycmd -解决方案,但即使对于不-专门处理的程序,也是如此:

$ mycmd /dev/stdin
Line 1
Line 2
^D

/dev/stdin 似乎与OS有关,并且它在Debian GNU / Linux上对我有效,但是我不确定它还能在其他地方工作。


1
这似乎可能有用,但是什么^D呢?
ArtOfWarfare 2015年

^D是按Ctrl-D的常用符号。^ D在这里具有“输入流结束”的语义。分别在按Ctrl-C ^C^Z按Ctrl-Z所代表的位置中可能更常见。
Axel Beckert

1
看来确实可行,但是如何以编程方式将内容放入/dev/stdin然后关闭?
ArtOfWarfare 2015年

1
只需将某些内容传送到该命令中,它就可以正常工作,即cat content | mycmd /dev/stdin。试想一下与cat此处不同的命令。
阿克塞尔·贝克特
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.