時々、新しい (ubuntu) ボックスで作業しているときに、次のように入力するgit
と警告が表示されます:
The program 'git' is currently not installed. You can install it by typing:
apt-get install git-core
そのようなことが起こった場合、次のようにすることで最後の行を取得できることがわかっています。
!! 2>&1 | tail -n 1
しかし、その( )の結果をapt-get install git-core
最も簡単に実行するにはどうすればよいでしょうか?
私はできると気づいた
`!! 2>&1 | tail -n 1`
しかし、実際に出力をパイプして実行する方法もあるのでしょうか? これは機能しないようです:
!! 2>&1 | tail -n 1 | sh
また、この2>&1
部分は少し面倒なので、それを実現するより簡単な方法があるかどうかも知りたいです。
編集
これを何らかの方法で変数に保存し、その変数を実行することもできます。
!! 2>&1 | tail -n 1 | (store as $mycmd)
$mycmd
stdout
しかし、少なくとも変数がコマンドの右側にある場合、変数にパイプする方法がわからないのです。
答え1
システムに存在しないコマンドを入力すると、bash は関数を実行します。この関数には、メッセージを出力するスクリプトcommand_not_found_handle()
の呼び出しがあります。/usr/lib/command-not-found
ウブントゥ 12.04
最初は、このスクリプトのソースを変更して、stdout
代わりににメッセージを出力すると考えstderr
ましたが、スクリプトのソースを読んでいるときに、不足しているパッケージをインストールするかどうかを尋ねるように構成できることが分かりました。
変数をエクスポートすると、COMMAND_NOT_FOUND_INSTALL_PROMPT
不足しているパッケージをインストールするように求められます。
pbm@ubuntu:~$ git
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git
pbm@ubuntu:~$ export COMMAND_NOT_FOUND_INSTALL_PROMPT=""
pbm@ubuntu:~$ git
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git
Do you want to install it? (N/y)y
sudo apt-get install git
[sudo] password for pbm:
Ubuntuの古いバージョン
残念ながら、他に選択肢はないCOMMAND_NOT_FOUND_INSTALL_PROMPT
ので、いくつか見つけました:
1) 12.04 からパッケージをインストールします - 問題はないはずです - Python のスクリプトがいくつかあるだけなので動作するはずです (テストされていません)。
2)stderr
を に変更しますstdout
。これを行うには、ファイルを編集し/usr/lib/python2.7/dist-packages/CommandNotFound/CommandNotFound.py
、行 237 と 240stderr
をに変更します。stdout
その後は次のように使用できます:
pbm@ubuntu:~$ git
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git
pbm@ubuntu:~$ `git`
//Installation begins
-y
237 行目と 240 行目のコマンドにオプションを追加する場合は、apt-get
構文も使用できます!! | sh
。
3) このスクリプトの 242 行目を次のように変更することもできます。
print >> sys.stderr, _("You can install it by typing:")
f = open("%s/.install-missing" % os.path.expanduser('~'),'w')
print >> sys.stderr, "sudo apt-get install %s" % packages[0][0]
print >> f, "sudo apt-get install %s" % packages[0][0]
f.close()
この方法では、ファイルにコマンドが取得される~/.install-missing
ため、エイリアスを作成できます。
alias im="chmod +x ~/.install-missing; ~/.install-missing"
呼び出すとim
パッケージがインストールされます。
答え2
あなたは正しい方向に進んでいました:
!! 2>&1 | tail -n 1 | sh
...しかし、オプションがありませんシュ。 考慮する:
!! 2>&1 | tail -n 1 | sh -s
apt-get を実行するにはおそらく root アクセスが必要になるため、次の点を考慮してください。
!! 2>&1 | tail -n 1 | sudo sh -s
答え3
次のようなことができます:
!! 2>&1 | tail -n 1 > /tmp/cmd; bash /tmp/cmd; rm /tmp/cmd
対話型プログラムは、入力(この場合は「Y」)を期待しますが、最初のコマンドが終了するとすぐに stdin ファイル記述子が閉じられるため、パイプではうまく動作しないようです。
答え4
変数eval
とコマンド置換を使用できると思います (ただし、これがどれほど安全であるかはわかりません)。
TEST_VAR=$(!! 2>&1 | tail -n 1); eval $TEST_VAR
上記の点については、私が間違っていることが証明されても構いません。私はこれを、bash 補完の自動提案ではなくコマンドを使用して Red Hat マシンでテストしていますがecho
、原理は同じであるはずです。
結局のところ、aptitude install git と入力する方が早いでしょう...