ファイルが必要なプログラムにテキストを渡す


30

Stack Overflow:wsadmin.shに複数行のコードを渡すという質問に関連して

文字列として、コマンドに入力する必要がある数行の入力があります。ただし、コマンドは入力がいっぱいのファイルのみを受け入れます。

実際にディスクに書き込まれることのない一時ファイルまたはパイプに行を保存し、それをプログラムに直接フィードする方法はありますか?

パイプを取得し、入力をパイプに送り、そのパイプをコマンドに渡し、パイプを削除するにはどうすればよいですか?


2
使用しているコマンドの例と、どのように呼び出されるべきかを追加できますか?
ブレークスルー

2
それはプログラムが標準入力を受け入れないということですか?
レオラム

上記の両方のコメント者に同意します。プログラムの仕様を知らずに機能するものを提案することは不可能です。
ラーセンド

回答:


27

別の解決策は、Bashでプロセス置換を使用することです。システムに名前付きパイプがある場合、この機能を使用できます。

次のように使用されます。

program_expecting_a_file <(list)

where listは、一連のシェルコマンドです(実際にはパイプライン。詳細については、こちらを参照してください)。listが実行され、その出力がパイプに接続されます。その後、パイプの名前がプログラムに渡されます。

注:<との間にスペースは使用できません(

(他の置換>(list)も期待どおりに機能します。)

あなたの特定のケースでは、使用できます

program_expecting_a_file <(echo "$your_strings")

@meuhのソリューションがよりエレガントであることがわかるかもしれません。

更新:Advanced Bash Scripting Guideで非常に多くの使用例が見つかります。


他の2つは、最も些細な場合でも機能しませんでした。あなたのものは、私がこれまでに投げたテストに合格します。私は今のところあなたのものを支持しています。必要なことをすべて実行できる場合は、戻ってこれを承認済みとしてマークします。
-ArtOfWarfare

あなたのものは完璧に動作します。必要に応じて、StackOverflowの関連する質問に追加することができます。また、そこからも受け入れます。stackoverflow.com/questions/31374202/...
ArtOfWarfare

こんにちは@ArtOfWarfare、助けてくれて嬉しいです。提案された同じ解決策に関するコメントが既にそこにあるので、そこに答えを投稿するのは正しくありません。
エドワード

彼がする前にソリューションを投稿しました。とにかく、私はそれを受け入れることができるように彼のコメントを答えに変更するよう彼に頼みました。どちらも24時間以内にその質問に回答を投稿しない場合は、自分で回答を投稿するので、それを受け入れます(回答が何であるかを見つけたら、質問を未回答のままにしておくのは嫌です。将来の読者/質問の潜在的な回答者のためのちょうど悪いマナー。)
ArtOfWarfare

こんにちは@ArtOfWarfare、あなたが提案するものには絶対に大丈夫です!
エドワード

15

bash here-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が明確になることを願っています。
デビッドZ

1
:(-これは非常に有望に思えましたが、試してみるとエラーメッセージが表示されました"-f" option must be followed by a file name.
-ArtOfWarfare

here-docは標準入力用です。コマンドに絶対に-fファイル名が必要な場合は、ファイル名を指定します/dev/stdin。編集をご覧ください。
-meuh

編集後は絶対に実行可能なオプションだと思います!
エドワード

1
/dev/stdin提案のために+1 。呼び出そうとしているプログラムはファイル名のみを受け入れるため/dev/stdin、heredoc と組み合わせました。
Huw Walters

7

スクリプトの内容によっては、stdinを表す特別なファイル名-(マイナス)を使用できる場合があります

$ mycmd -
Line 1
Line 2
^D

あなたのために働くかもしれない別の方法は、/dev/fd/0再びstdinを表すファイルを開くことです。

3番目のオプションは、FIFO先入れ先出し)を作成することです。これはファイルに似ていますが、2つの目的があります。一方の端に書き込み、もう一方の端から読み取ります。

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

3
-この方法を解釈するには、プログラムを作成する必要があることに注意してください。これは、シェルまたはオペレーティングシステムの機能ではありません。もちろん、私の知る限り、ほとんどの標準Linuxユーティリティはこの規則に従います。
デビッドZ

1
いや。これはプログラムでは機能しません。対話モードがありますが、別のプログラムからこのプログラムに実行するコマンドを渡したいのですが、うさぎの穴に入りたくありませんexpect
ArtOfWarfare

@ArtOfWarfare動作する可能性のある3番目のオプションを追加しました。
マジェンコ

いい答えだ!2番目と3番目のオプションは基本的に<()ソリューションに似ていますが、より明示的です-これは非常に便利です!
エドワード

4

mycmd -ソリューションに似た別のオプションがありますが、-特に処理しないプログラムでも:

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

/dev/stdin OS関連であると思われ、Debian GNU / Linuxで動作しますが、他にどこで動作するのかわかりません。


1
これはうまくいくかもしれませんが、何^Dですか?
ArtOfWarfare

^DCtrl-Dを押すための一般的な表記法です。^ Dのセマンティクスは、ここでは「入力ストリームの終わり」です。それはおそらく、Ctrl-Zを押すか、Ctrl-Cを押すことを表す、^Cまたは^ZCtrl-Cを押すことを意味します。
アクセルベッカート

1
それはうまくいくように見えますが、どのようにしてプログラム/dev/stdinで何かを入れてから閉じるのでしょうか?
ArtOfWarfare

1
何かをそのコマンドにパイプするだけで機能しcat content | mycmd /dev/stdinます。catこことは異なるコマンドを想像してください。
アクセルベッカート
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.