vim
〜find | xargs
を呼び出すときは、こんな感じ
find . -name "*.txt" | xargs vim
警告を受けます
Input is not from a terminal
とその後の動作がかなり壊れている端末ですそれはなぜなんでしょうか?
この質問は、明示的に回避する方法についてではなく、理由についてでした。これは質問され、答えた、elsewhere
146 None 2011-09-15
xargs
経由でプログラムを呼び出すと、プログラムの標準入力(標準入力)は/dev/null
を指します。(xargsは元の標準入力を知らないので、次善の策を実行します)
$ true | xargs filan -s 0 chrdev /dev/null 1 tty /dev/pts/1 2 tty /dev/pts/1 $ true | xargs ls -l /dev/fd/
Vim は、その標準入力が制御している端末と同じであることを期待しており、端末関連のさまざまな ioctl を標準入力で直接実行します。/dev/null
(または非ttyファイル記述子) で実行された場合、これらのioctlは無意味であり、ENOTTYを返しますが、これは静かに無視されます
私の推測では、より具体的な原因があります。起動時に Vim は古いターミナル設定を読み込んで記憶し、終了時にそれを復元します。私たちの状況では、”古い設定” が non-tty fd (ファイル記述子) に対して要求されると、Vim はすべての値を空にしてすべてのオプションを無効にして受け取り、あなたのターミナルに不注意に同じものを設定してしまいます
vim < /dev/null
を実行して終了し、stty
を実行すると<undef>
が大量に出力されます。Linux では、stty sane
を実行すると、ターミナルが再び使えるようになります (ただし、iutf8
のようなオプションは失われているので、後になって小さな問題を引き起こす可能性があります)
Vim はターミナル制御のために /dev/tty
を開くことができるが、開かないので、これは Vim のバグと考えることもできるだろう。(起動時のある時点で、Vim は stderr を stdin に複製します。これにより、Vim はあなたの入力コマンドを – 書き込み用に開かれた fd から – 読むことができますが、それさえも初期の段階では十分に行われていません)
104 user1686 2011-09-15
(grawityの説明に続き、xargs
がstdin
を/dev/null
に指していること)
この問題の解決策は、-o
パラメータをxargs
に追加することです。man xargs
から
-o
コマンドを実行する前に、子プロセスで
/dev/tty
として標準入力を再オープンします。 これは、対話型アプリケーションを実行したい場合に便利です
したがって、以下のコードの行は、あなたのために動作するはずです
find . -name "*.txt" | xargs -o vim
GNU xargsは2017年のいくつかのリリースからこの拡張機能をサポートしています(長いオプション名--open-tty
で)
古いバージョンや他のバージョンの xargs では、明示的に /dev/tty
を渡すことで問題を解決することができます
find . -name "*.txt" | xargs bash -c '</dev/tty vim "$@"' ignoreme
(ignoreme
は$0を取るためにあるので、$@はxargsからの全ての引数となります)
153 James McGuigan 2012-05-23
一番簡単な方法です
vim $(find . -name "*foo*")
33 trolol 2014-03-08
xargs にパイピングするのではなく、find で -exec オプションを使えば問題なく動作するはずです
find . -type f -name filename.txt -exec vi {} +
22 Chris Wraith 2013-03-10
代わりにGNUパラレルを使ってください
find . -name "*.txt" | parallel -j1 --tty vim
または、一括してファイルを開きたい場合
find . -name "*.txt" | parallel -Xj1 --tty vim
のようなファイル名を正しく扱うこともできます
My brother's 12" records.txt
イントロ動画をご覧ください。http://www.youtube.com/watch?v=OpaiGYxkSuQ
9 Ole Tange 2011-09-16
最良ではないかもしれませんが、私が使っているスクリプトです (vim-open
という名前)
#!/usr/bin/env ruby
require 'shellwords'
inputs = (ARGV + (STDIN.tty? ? [] : STDIN.to_a)).map(&:strip)
exec("</dev/tty vim #{inputs.flatten.shelljoin}")
は、例えば vim-open a b c
と ls | vim-open
で動作します
0 localhostdotdev 2019-05-07