読者です 読者をやめる 読者になる 読者になる

vimとxargsで表示がおかしくなる

まとめてファイルを開く必要があるときに以下のようにやることがある

$ find . -name '*.txt' | xargs vim

だがこんなwarningが出た上、vimを終了した後にターミナルの表示がおかしくなる

Vim: Warning: Input is not from a terminal
# vim終了後
$ git status                                                                                                                                                                                                              
On branch master
                Your branch is up-to-date with 'origin/master'.

                                                               nothing to commit, working directory clean
                                                                                                         %     

別のウィンドウを使えば済むがこのたびにターミナルを変えるのは面倒なため解決策がないか調べてみた
解決策はこちらのページに見つかった
vim - Invoking vi through find | xargs breaks my terminal. Why? - Super User

どうやらxargsを実行するとstdinが/dev/nullに設定されてしまうことが原因らしい
この状態に陥ってしまったターミナルを正常に戻すためには以下のコマンド

$ stty sane

また、xargsを使う段階でオプションを使うことで解決できる模様

# BSD(OSX)
$ find . -name '*.txt' | xargs -o vim
# GNUだと上記オプションがないため(自分では試してない)
$ find . -name "*.txt" | xargs bash -c '</dev/tty vim "$@"' ignoreme

そもそもxargsを使わないという手段が2つ

$ find . -name '*.txt' -exec vim {} +
$ vim $(find . -name '*.txt')

1つ目の方法は初めて見たが、{}がfindによって渡される結果を表し、+でそれらを渡せる最大の数ごとに分割してvimに渡すという意味になるらしい
つまりxargsは同じことをする
勉強になりましたー

参考ページ
find -execとxargs - うまいぼうblog
xargs - Wikipedia