標準入力から一時ファイルを作成する

標準入力から一時ファイルを作成する

次のような標準入力ストリームがあるとします。ファイルの内容そして、ファイル名を引数として指定し、標準入力ストリームのファイル内容で構成されたファイルに対してそのコマンドを実行したいと考えています。

例えば、コマンド

imageviewer mouse.jpg

magicこれを同等にする魔法の線が欲しい

cat mouse.jpg | magic

これはまたはmagicではどのように見えるでしょうか?zshbash

できれば、こんな感じにしたいです

cat mouse.jpg | submagic | xargs imageviewer

つまり、submagic標準入力ストリームから一時ファイルを作成し、作成されたファイルのファイル名を出力したいと思います。

magicまたは の行はsubmagic、bash または zsh コマンド、それらの組み込みコマンド、GNU coreutils などのみを使用するシェル パイプラインである必要があります。


これが質問のすべてです。以下は、私が言いたいことを人々が誤解し続けたため、単に説明と背景を述べたものです。


分かりました、私は明確に伝えたつもりでしたが、そうではなかったようです。本当に同等の機能を持つパイプラインが欲しい

imageviewer mouse.jpg

それ正確に始まるつまりcat mouse.jpg | …、私は本当に欲しいその通りmagicまたはsubmagicそのようなものその通り上記のパイプラインは機能します。私の質問は文字通りの意味です。

これは特に、次の提案された解決策は機能しないことを意味します。

  • パイプラインの開始tmpfile = $(mktemp); cat mouse.jpg | …
  • それを次のように書き直すとimageviewer =(cat mouse.jpg)
  • それを次のように書き直すとecho mouse.jpg | xargs imageviewer
  • 関数やバイナリを使用して解決する。例えば、定義する。function magic () { … }

私が興味を持っているのは、上記のパイプラインの 1 つが機能し、これらのエイリアスの定義に bash または zsh コマンド、GNU coreutils などのみが含まれる (自分で記述したalias magic='…'ものalias submagic='…'は何も含まれない) ようなエイリアスなどを作成できるかどうかだと言えます。

別のコメント。または、または、何かでimageviewerあると考えます。fehsxiv

背景この質問は、メール クライアントを使用してメールに添付された複数の画像ファイルを開こうとしたときに思いつきましたneomutt。Neomutt は、添付ファイルにタグを付け、そのファイルの内容を入力可能なコマンド ラインにパイプする機能を提供します。したがって、ここでは、指定された標準入力ストリームで何かを実行するコマンド ラインのみを提供できます。これが質問の出所です。しかし、私は元の問題には興味がなく、この質問にのみ興味があります。

答え1

少なくともbashプロセス置換:

utility <( some_other_utility )

これはutilityファイル名utilityがファイルを開いて読み取ると、 の標準出力が読み取られますsome_other_utility


あなたの例:

cat mouse.jpg | submagic | xargs imageviewer

これは、ファイル名 mouse.jpgimageviewerJPEG ファイルの内容を 経由で送信するのは意味がないので、に送信してくださいxargs

それはただ

echo 'mouse.jpg' | xargs imageviewer

または

xargs imageviewer <<<'mouse.jpg'

bash

の内容を次のように送信しmouse.jpgますimageviewer

cat mouse.jpg | imageviewer /dev/stdin

または、プロセス置換を使用して、

imageviewer <( cat mouse.jpg )

一時ファイルの使用:

tmpfile=$(mktemp)
cat mouse.jpg >"$tmpfile"

imageviewer "$tmpfile"

rm "$tmpfile"

おそらく、

tmpfile=$(mktemp)
cat mouse.jpg | { cat >"$tmpfile"; echo "$tmpfile"; } | xargs imageviewer
rm "$tmpfile"

このパイプラインは、パイプラインの中間部分からファイル名を読み取るまでxargs実行を待機するという事実に依存しています。一時ファイルが作成されるまで、ファイル名は中間のコマンドによって出力されません。imageviewer

答え2

submagic質問の説明の後、回答を編集しました。

では、zshコマンドの出力から一時ファイルを作成できます。 や名前付きパイプなどのデバイスファイルを使用できる と=( ... )は対照的に、形式ではシーク可能な一時ファイルが作成されます。<( ... )/dev/fd...=( ... )http://zsh.sourceforge.net/Doc/Release/Expansion.html#プロセス置換

cat mouse.jpgこれは、画像データをstdoutに送信するコマンドの例にすぎないと仮定すると、次のように使用できます。

imageviewer =(cat mouse.jpg)

zshによって作成された一時ファイルに特定の拡張子が必要な場合は、TMPSUFFIX特殊変数):

(TMPSUFFIX=.jpg; imageviewer =(cat mouse.jpg))

2回目の更新

構文にこだわるなら

cat mouse.jpg | submagic | xargs imageviewer

submagicKusalananda の回答ですでに提案されているコマンドと同様のスクリプトを作成することは可能です。

#! /bin/sh

# A fixed name allows multiple runs without creating lots of files and
# allows a simple script to remove the file afterwards.
TMPFILE=/tmp/submagic.tmp.jpg
rm -f "$TMPFILE" && cat > "$TMPFILE" && echo "$TMPFILE"

シェルのメカニズムとは対照的に、このようなものは実行後に=( cat mouse.jpg )削除されません。$TMPFILEimageviewer

これを実行した後に 2 番目のスクリプトを実行できる場合、imageviewer名前がわかっている場合はファイルを削除できます。

脚本submagic-cleanup

#! /bin/sh

# A fixed name allows a simple script for cleaning up.
TMPFILE=/tmp/submagic.tmp.jpg
rm -f "$TMPFILE"

そうすれば走れる

cat mouse.jpg | submagic | xargs imageviewer
submagic-cleanup

答え3

質問の要件を正確に満たすには、次の操作を実行できます。

cat mouse.jpg | { tf=$(mktemp); cat >"$tf"; echo "$tf"; } | xargs imageviewer

関連情報