私はしばしば、繰り返しの方法でファイル(wdiffなど)の入力を受け入れるコマンドラインプログラムに比較的短い文字列データ(数行程度)を提供したいと思います。もちろん、1つ以上の一時ファイルを作成し、そこに文字列を保存してから、ファイル名を引数として使用してコマンドを実行できます。しかし、私の考えでは、データが実際にディスクに書き込まれている場合、このプロセスは非常に非効率的になります。 。ファイルをwdiffとして保存します。パイプなどの擬似ファイルを使用して、実際にデータをディスクに書き込むことなく一時的に保存する(またはしきい値を超える場合にのみ書き込む)など、この問題を回避するための推奨方法はありますか? wdiffには2つのパラメーターが必要です。私が理解する限り、これはwdiff <"text"
。
答え1
command1 <( command0 )
Bashでは、stdoutをリダイレクトcommand0
し、それをcommand1
コマンドライン引数としてファイル名に渡すリダイレクト構文を使用できます。これは…プロセスの交換。
ファイル名コマンドライン引数を使用する一部のプログラムは実際には真のランダムアクセスファイルを必要とするため、この手法はこれらのプログラムでは機能しません。ただし、以下を使用するとうまく機能しますwdiff
。
user@host:/path$ wdiff <( echo hello; echo hello1 ) <( echo hello; echo hello2 )
hello
[-hello1-]
{+hello2+}
その後、FIFOを生成し、内部コマンドを<( )
FIFOにパイプし、FIFOのファイル記述子をパラメータとして渡します。何が起こっているのかを確認するには、次の方法で何もせずにecho
パラメータを印刷します。
user@host:/path$ echo <( echo hello )
/dev/fd/63
名前付きパイプを作成する方が柔軟ですが(複数のプロセスを使用して複雑なリダイレクトロジックを作成したい場合)、多くの目的に十分で使いやすいです。
>( )
出力として使用したい場合の構文もあります。
$ someprogram --logfile >( gzip > out.log.gz )
また、見ることができますBashのマニュアルページ「プロセスの置き換え」セクションそしてBashリダイレクトチートシート関連技術を確保するために
答え2
使う名前付きパイプ。たとえば、
mkfifo fifo
echo -e "hello world\nnext line\nline 3" > fifo
-e
改行文字()を正しく解釈するようにechoに指示します\n
。これはブロックされます。つまり、パイプからデータを読み取るまでシェルは停止します。
同じディレクトリのどこかに別のシェルを開きます。
cat fifo
他のシェルをリリースするエコーを読んでください。パイプはディスク上のファイルノードとして存在しますが、それらを通過するすべてのデータはメモリから発生しません。&
エコ背景()を設定できます。
パイプには64kバッファ(Linux)があり、ソケットのようにいっぱいになるとライターがブロックされるため、ライターを早期に終了しない限りデータは失われません。
答え3
wdiffは2つのファイル名引数が必要であるという点で特別な場合ですが、1つの引数だけが必要で、ファイル名引数以外のものは受け入れを固執拒否するすべてのコマンドに対して2つのオプションがあります。
ファイル名「-」(つまり、マイナス記号)は約1/2の時間動作します。これは、問題のコマンドとコマンド開発者が状況を把握して期待どおりに処理したかどうかによって異なります。例えば
$> ls |猫 -
/dev/stdinという擬似ファイルはLinuxに存在し、コマンドにファイル名が絶対に必要な場合に使用できます。これは、特別なファイル名処理を実行するためにコマンドを必要としないため、機能する可能性が高くなります。 fifoが有効な場合、またはbashプロセスの交換メソッドが機能する場合は、このメソッドも機能する必要があり、シェルに限定されません。例えば
$> ls |cat/dev/stdin