
次のような標準入力ストリームがあるとします。ファイルの内容そして、ファイル名を引数として指定し、標準入力ストリームのファイル内容で構成されたファイルに対してそのコマンドを実行したいと考えています。
例えば、コマンド
imageviewer mouse.jpg
magic
これを同等にする魔法の線が欲しい
cat mouse.jpg | magic
これはまたはmagic
ではどのように見えるでしょうか?zsh
bash
できれば、こんな感じにしたいです
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
あると考えます。feh
sxiv
背景この質問は、メール クライアントを使用してメールに添付された複数の画像ファイルを開こうとしたときに思いつきましたneomutt
。Neomutt は、添付ファイルにタグを付け、そのファイルの内容を入力可能なコマンド ラインにパイプする機能を提供します。したがって、ここでは、指定された標準入力ストリームで何かを実行するコマンド ラインのみを提供できます。これが質問の出所です。しかし、私は元の問題には興味がなく、この質問にのみ興味があります。
答え1
少なくともbash
、プロセス置換:
utility <( some_other_utility )
これはutility
、ファイル名utility
がファイルを開いて読み取ると、 の標準出力が読み取られますsome_other_utility
。
あなたの例:
cat mouse.jpg | submagic | xargs imageviewer
これは、ファイル名 mouse.jpg
imageviewer
JPEG ファイルの内容を 経由で送信するのは意味がないので、に送信してください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
submagic
Kusalananda の回答ですでに提案されているコマンドと同様のスクリプトを作成することは可能です。
#! /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 )
削除されません。$TMPFILE
imageviewer
これを実行した後に 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