func
表形式の出力またはjson出力を生成できる関数があります。この問題を解決する従来の方法は、次のパラメータを使用することです。
$ func -j | jq .firstField
$ func -t | awk '{print $1}'
私は「事前に見て」パイプラインの次のステップに基づいて出力タイプを推測したいと思います。理想的な使い方は簡単です。
$ func | jq .firstField
$ func | awk '{print $1}'
func どこかで、パイプラインの次のステップの0番目のパラメータが含まれていることを確認すると想像してくださいj
。その場合はjsonを作成し、そうでない場合はテーブルを作成します。
Bashはそのような魔法を許可しますか?それでは、どうすればいいですか?
答え1
/proc
プロセスツールを使用してプロセスツリー内または存在する場合は、タイプファイルシステムをマイニングして回収できる以外に、パイプラインに関連付けられた公式のメタデータやクエリAPIはありません。親シェルは(おそらく)メモリのどこかに完全なパイプを持ち、関連するさまざまなサブプロセスについて知っています。ただし、ランダムcat
(例外を除いて意味なし)パイプが進行中のサブプロセスをcat | cat | cat | ...
知ることができるAPIはありません。cat
パイプラインとその同僚が誰であるかを見てみましょう。
% cat | cat -b | cat -e | cat -n
一意のフラグを使用すると、pstree(1)
他の端末に表示されているものがわかりやすくなります。
| \-+= 35276 jhqdoe -zsh (zsh)
| |--- 44661 jhqdoe cat -n
| |--- 03968 jhqdoe cat -b
| |--- 96165 jhqdoe cat -e
| \--= 26975 jhqdoe cat
cat -e
しかし、これはパイプが何であるかを知らせずcat -n
、猫のバッグがすべて親シェル35276のプロセスグループに属していることを伝えます。
% ps ao ppid,pid,command | grep '[ ]cat'
35276 44661 cat -n
35276 96165 cat -e
35276 3968 cat -b
35276 26975 cat
どのパイプまたは記述子が何に接続されているかを確認するpidまたはコマンドがあるシステムにある場合は、プロセスが属する/proc
プロセスグループから何がどのように接続されているかを判断できます。たとえば、Linuxでlsof
同様のcatパイプラインを実行すると、パイプ14301040を共有するため、接続してコマンドを実行cat -e
できます。cat -n
-bash-4.2$ lsof -p 23591 | grep pipe
cat 23591 jhqdoe 0r FIFO 0,9 0t0 14301039 pipe
cat 23591 jhqdoe 1w FIFO 0,9 0t0 14301040 pipe
-bash-4.2$ lsof -p 23592 | grep pipe
cat 23592 jhqdoe 0r FIFO 0,9 0t0 14301040 pipe
したがって、情報が利用可能であっても情報を把握するには、非ポータブルツールを使用して多くの情報を掘り下げて再構成する必要があります。
親シェルは入力後にパイプを書き換える方法を提供できますが、ZSHフック機能は実行するpreexec
コマンドを書き換える方法を提供しないようです。 (これらの機能は、LISPマクロを使用してプログラマーがコードを書き換えることを可能にする方法と似ている可能性があります。)親シェルは、子プロセスがパイプを調べるために使用できるAPIの種類を提供することができます。このタイプの追加はシェルに書き込む必要があります。 。
ただし、複雑なパイプラインを構築できます。
func | ( cd ... && ... | ( ... | awk ... ) )
この場合、誤ってfunc
検索awk
できない場合、またはプロセスパイプライン検索機能は、次のパイプライン要素のすべてのコマンドを再帰的に検索する必要があります。この場合、おそらくインスタントawk
になります。func
または、この動作を設定したことを忘れてawk
誤って修正され、バグを見つけるのが難しいかもしれません。
答え2
少なくともLinuxではこれを行うことができました。これを示すスクリプトは次のとおりです。https://gist.github.com/MatrixManAtYrService/790a4a058bc841b0ceb2eb0263fb5d88
使用例:
❯ cat -b | ./luigi | jq .
[
{
"pid": "20832",
"name": "cat -b",
"node": {
"write": "5157339",
"read": null
}
},
{
"pid": "20833",
"name": "bash ./luigi",
"node": {
"write": "5157341",
"read": "5157339"
}
},
{
"pid": "20834",
"name": "jq .",
"node": {
"write": null,
"read": "5157341"
}
}
]