私が理解したことはpipe
、例えば、
command1 | command2
command1
出力をに送信しますcommand2
。しかし、これがうまくいくことを願っています。
echo "tmp.pdf" | evince
しかしそれは真実ではない。echo "tmp.pdf"
出力はどこに送信されますか?
答え1
あなたの理解は正しいです。このシーケンスはcommand1 | command2
出力(STDOUT)をcommand1
入力(STDIN)に送信しますcommand2
。コマンドevince
が機能しない理由は、evince
STDINがファイル名を受け入れないためです。
答え2
パイプは読み取り用に開くプログラムに出力を送信します。シェルパイプでは、これはあなたの例のパイプシンボルの右側にあるプログラムですevince
。
tmp.pdf
標準入力に表示するファイル名を送信しています。しかし、evinceは標準入力には興味がありません。ファイルで動作するすべてのプログラムと同様に、ファイル名がコマンドライン引数として渡されることを期待しています。コマンドラインにファイル名を渡さないと、ファイルを開く機能が提供されます。コマンドライン引数は標準入力と同じではありません。人間は物事によって異なる入力機関を持っています(例えば鼻を介して食べ物を食べることはできません)、同様にプログラムは目的に応じて情報を受け取る方法が異なります。
Evinceは読むことができます文書(ファイル名ではありません)標準入力:evince /dev/stdin <"tmp.pdf"
。 (一部のUnixバリアントでは機能しない可能性があります。)ファイル名は、/dev/stdin
「標準入力で開かれたすべてのファイル」を意味します。コマンドラインで使用されるプログラムは通常、ファイル名を指定せずに標準入力を読み取りますが、GUIプログラムは通常読み取られません。 Evincecat tmp.pdf | evince /dev/stdin
はページ間を移動するときにファイルを前後に表示できる必要があるため、パイプからのデータ(たとえば、機能しない)ではなく、通常のファイルのみを開くことができます。
答え3
最近私が気づいたように、次のようにこの問題を解決できます。まず、検索コマンドを使用して、evinceで開くファイルのパスを見つけます。この結果はevinceにパラメータとして渡されます。ファイル名がabc_xyz.pdfであり、それを開こうとするとします。その後、 - を実行できます
evince "$(sudo locate xyz | grep abc)"
。 pdfファイル名にスペースが含まれている場合は、二重引用符が必要です。つまり、結果をさらにフィルタリングするために$(sudo locate xyz | grep abc)
別のコード(でリンクされているsudo locate xyz
)を使用する理由です。grep abc
しかし、ここには問題があります。つまり、Locateを実行して更新を続ける必要があるということですsudo updatedb
。 pdfの場所を新しいディレクトリに変更したと仮定すると、itzデータベースがまだ更新されていないため、locatedはitzの新しい場所を見つけることができません。ただし、リアルタイム検索操作を実行するには、「and」条件で「find」コマンドを使用できます。たとえば、次のようにできます。
evince "$(find ~/ -iname "*abc*" -a -iname "*xyz*" -type f)"
-iname
大文字と小文字を区別しない検索と-a
yesと条件のために引数としてevince.here引数に渡します。-type f
ファイルのみが返されます。