Twitterをボケーッと眺めていたところ、xargsで呼び出したコマンドにキー入力をしたいという内容があったので、どうやったらできるのか調べてみた。

通常、対象のプロセスで標準入力が開いてないとだいたいの(というか、普通の)コマンドは処理を待たずに終了してしまう。なので、なんとかしてターミナルを標準入力として渡してやればいいということになる。

1. /dev/ttyを読み込ませる

以下のように、/dev/ttyをxargsで呼び出したコマンド内部で読み込ませる事で、ターミナルの入力を渡すことができる。

command... | xargs -I@ sh -c '</dev/tty command... @'

例えば、以下のようにすることでxargsで受け付けたファイルに対して対話式にrmをすることができる。

ls -1 | xargs -I @ sh -c '</dev/tty rm -i @'

2. xargsの-aオプションを使用する

この話題を会話していたツイートで、xargsの-aオプション(ファイルからxargsで処理するデータを受け付けるオプション)を利用する方法もあるよという内容をおしえてもらった。

つまり、パイプから受け付けると標準入力がそのまま使えないので、-aでファイルとしてプロセス置換を利用してコマンドの結果を取得して、それをxargsからコマンドに渡すことで標準入力をそのまま使えるよ、という仕組みになる。 以下のような感じでコマンドを実行することになる。

xargs -I@ -a <(command...) command_in_xargs... @

rmでやった場合はこんな感じになるようだ。 command...にxargsに渡す出力を渡すコマンドが入る。

xargs -I@ -a <(command...) rm -i @

rmとかの単純なものであれば、xargs側で-pオプション(--interactive)を使って実行可否を確認するとかすればいいのだろうけど、コマンド個別の内容に回答するのならばこの方法が便利な気がする。


参考