Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
10
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

ファイル名をパイプで出力してvimで開く方法

TL;DR

コマンドで取得したファイル名をパイプで出力して、vimで開きたいとき

ls . | tail -1 | xargs -o vim # xargsに-oオプションをつけるのがポイント

でできる。

コマンドの意味を、ちょっと詳しく

xargsを使うと、標準入力から引数を読み込んで任意のコマンドを実行できる。だが以下のコマンドだと、「Vim: Warning: Input is not from a terminal」と言われて、以降のターミナルへの入力がおかしくなってしまう。

ls . | tail -1 | xargs vim # 以降のターミナルへの入力がおかしくなるので注意!

原因は、xargsが対象のコマンドの標準入力を/dev/nullに設定して実行しているため。vimは標準入力がターミナル(/dev/tty)であることを想定している。このことは、以下のコマンドで確認できる。

vim < /dev/tty # これだとOK
vim < /dev/null # 上記のエラーが出て、以降のターミナルへの入力がおかしくなる

ということは、標準入力を現在のターミナルに設定してxargsがコマンドを実行すれば良いので、これで開けるようになる。

ls . | tail -1 | xargs sh -c 'vim $1 < /dev/tty' - # 標準入力をターミナルに指定

もっと簡単に、xargsの-oオプションを使うと、標準入力をターミナルに設定してコマンドを実行してくれるようになる。

     -o      Reopen stdin as /dev/tty in the child process before executing the command.  This is useful if
             you want xargs to run an interactive application.

最初のコマンドにたどり着いた。

ls . | tail -1 | xargs -o vim # xargsに-oオプションをつけるのがポイント

気づいたこと

xargsの-oオプションの説明を読んでいたときに、xargsでマルチプロセスを扱えるのでは?ということに気づいた。調べてみたら、-Pオプションでマルチプロセスが扱えるようなので、今度試してみる。

     -P maxprocs
             Parallel mode: run at most maxprocs invocations of utility at once.
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
10
Help us understand the problem. What are the problem?