7

時々、何かをするためにターミナルセッションからGUIプログラムを起動しなければなりません。いくつかのHTMLファイルを表示するのは通常Chromeであり、いくつかのタスクは似ています。ただし、これらのプログラムはいたるところに警告をスローし、実際に何かを書くのはばかげている可能性があるため、私は常にstderr/stdoutをにリダイレクトしたいと思っていました/dev/null

大丈夫なようですが、単純なBash関数を作成することにしました。その($PROGRAM &) &>/dev/nullため、毎回繰り返す必要はありません。

だから今のところ私の解決策は次のようなものです:

#
# silly little function
#
gui ()
{
  if [ $# -gt 0 ] ; then
    ($@ &) &>/dev/null
  else
    echo "missing argument"
  fi
}

#
# silly little example
#
alias google-chrome='gui google-chrome'

だから私が疑問に思っているのは:

  • まだきびきびしているエイリアスの無限のリストなしで方法はありますか?
  • これを達成するためのさまざまな戦略はありますか?
  • 他のシェルは異なるソリューションを提供しますか?

これらの質問をする際に、あなたの戦略と解決策が私のものから大幅に逸脱する可能性があることを指摘したいと思います。出力を/dev/ nullにリダイレクトし、それをエイリアシングすることが私が知っている唯一の方法でしたが、より効率的なまったく異なる方法があるかもしれません。

したがって、この質問:-)

4

4 に答える 4

2

他の人がコメントで指摘しているように、本当の問題は、コマンドラインでGUIアプリと非GUIアプリを区別する方法だと思います。そのため、私が考えることができる最もクリーンな方法は、スクリプトのこの部分を配置することです。

  #!/bin/bash

  if [ $# -gt 0 ] ; then
    ($@ &) &>/dev/null
  else
    echo "missing argument"
  fi

と呼ばれるファイルに入れて、それをあなたの中に入れますgui(あなたの中にあることを確認してください)。これで、次のコマンドでGUIアプリを起動できます。chmod +x~/bin/~/bin$PATH

`gui google-chrome`

プロンプトで。

または、上記を実行してから、次を使用することもできますbind

bind 'RETURN: "\e[1~gui \e[4~\n"'

これにより、次のことが可能になります。

google-chrome

guiプロンプトで、前に自動的に追加されますgoogle-chrome

F12または、上記のアクションをでの代わりにRETURNバインドすることができます

bind '"\e[24~": "\e[1~gui \e[4~\n"'

起動したいものとgui非GUIを区別するため。

ここここでのバインディングに関する詳細。

これらの選択肢は、無限のエイリアスから抜け出す方法を提供します。の組み合わせ:

  • guiあなたを入れて~/bin/、そして
  • 上記のようにguitoの使用をバインドしますF12

最も理想的な(ハッキーではありますが)ソリューションのようです。


更新-@EnnoWeichertの結果の解決策:

このソリューションの締めくくり...

これにより、エイリアス(多少風変わりな方法で)とさまざまなエスケープエンコーディング(網羅的ではなく実用的な方法で)が処理されます。

これを入れて$(HOME)/bin/quiet

#!/bin/bash -i

if [ $# -gt 0 ] ; then
  # Expand if $1 is an alias
  if [ $(alias -p | awk -F "[ =]" '{print $2}' | grep -x $1) > 0 ] ; then
    set -- $(alias $1 | awk -F "['']" '{print $2}') "${@:2}"
  fi
  ($@ &) &>/dev/null
else
  echo "missing argument"
fi

そしてこれは$(HOME)/.inputrc

#
# Bind prepend `quiet ` to [ALT][RETURN]
#
# The condition is of limited use actually but serves to seperate
# TTY instances from Gnome Terminal instances for me.
# There might very well be other VT emulators that ID as `xterm`
# but use totally different escape codes!
#
$if $term=xterm
  "\e\C-j": "\eOHquiet \eOF\n"
$else
  "\e\C-m": "\e[1~quiet \e[4~\n"
$endif
于 2012-11-19T16:08:58.610 に答える
0

まず、マウスの使用量を減らすため、ターミナルからGUIアプリケーションを起動することをお勧めします。オプションと引数の点で、より高速で便利です。たとえば、ブラウザを取り上げます。クリップボードにURLがあり、貼り付ける準備ができているとします。たとえば、ice(Iceweaselの場合)と入力し、Shift-Insert(貼り付ける)を押してEnterキーを押します。これをアイコン(おそらくメニュー内)をクリックするのと比較して、ウィンドウがロードされるのを待ち(スタートアップページがある場合はさらに悪いことに)、URLバーをクリックして(またはCtrl-Lを押して)、次にCtrl-Vを押します。 。だから、これが機能することを望んでいることを理解しています。

しかし、これがエイリアスと関数の「無限の」リストをどのように必要とするかはわかりません。本当に多くのGUIアプリケーションを使用していますか?それでも、エイリアスは1行です。引数を処理するのに実用的な関数は、おそらく1〜5行の(スパース)コードです。そして、一度だけ設定する必要があるとは思わないでください。必要に応じて、1つずつ設定してください。やがて、あなたはそれらすべてを手に入れるでしょう。

また、urxvt(Perl拡張機能があります)のようなタブ付きターミナルがある場合は、「GUI:s」から「CLI:s」に移行するとメリットがあります。ダウンロードには、rtorrentがあります。IRCの場合、irssi; XEmacs(またはemacs)の代わりに、emacs -nw; 音楽をストリーミングするためのvlcへのCLIインターフェイスがあります。メールの場合、Emacsのrmail。などなど!狩りに行く:)

(私が遭遇した唯一の悲しい例外は、失われた原因だと思います。ブラウザです。Lynx、W3Mなどは技術的な観点からは素晴らしいかもしれませんが、現代のWebページのように、それは必ずしも問題ではありません。これらのテキストのみのブラウザを念頭に置いて設計されたものではありません。正直なところ、これらのページの多くは、これらのブラウザではあまり明確に見えません。)

ヒント:タブ付き端末を最大限に活用するには、「タブの変更」ショートカットを「閉じる」必要があります(たとえば、前のタブの場合はAlt-J、次のタブの場合はAlt-Kで、矢印キーを使用しないでください)。到達します)。

最後に、この問題を回避する1つの解決策は、 (ターミナルエミュレータを含む&)で(を使用して)バックグラウンドプロセスとして「GUI:s」を起動することです。~/.xinitrcあまり柔軟性はありませんが、コンピュータを使用するたびにいつも使用するものには最適です。

于 2012-11-20T01:14:57.567 に答える
0

それは醜いハックですが、私は時々nohup同様のニーズに使用します。コマンドの出力をリダイレクトするという副作用があり、プログラムをターミナルセッションから独立させます。

デスクトップ環境でGUIプログラムを実行する場合、プログラムはウィンドウマネージャーセッションで終了するため、リソースリークのリスクはほとんどありません。それにもかかわらず、それを考慮に入れる必要があります。

別のターミナルセッションを開くオプションもあります。たとえば、Gnomeではを使用できますgnome-terminal --comand 'yourapp'
しかし、これは多くの役に立たないターミナルウィンドウを開くことになります。

于 2012-11-19T14:22:49.867 に答える
0

さて、私は1つの機能で十分だと考え続けました。エイリアス、バシズム、ナンセンスはありません。しかし、拡張や補完などの通常の使用に影響を与えることなくそれを行う唯一の方法は、コマンドの最後に関数を配置することであるように思われました。これは、最初に想定するほど簡単ではありません。

printf "%b" "\u"最初に、現在の行を切り取って別の行を接続し、貼り付けて、最初に1つか2つの引用符を付けるために呼び出す関数を検討しましたprintf。次に、必要なことをほとんど実行しません。終わり。どうすればいいのかわかりませんが、申し訳ありません。そして、たとえそうだとしても、シェルescapeが実行するターミナルエミュレーターは言うまでもなく、シェルがシーケンスを解釈する方法が異なるため、この方法で実際の信頼性/移植性を期待することはできませんでしsttyた。もしそうなら、あなたはここでそれを見つけることができません...とにかく今。

代わりに、最終的には、現在のコマンドを実際に/proc/{PID}/cmdline変数にコピーし、(恥ずかしそうに)完全に強制終了し、最後に好きなようにラップすることにしました。プラス面として、これは非常に簡単に実行でき、非常に迅速に実行でき(どちらの方法でも「効率」について議論することは想像できますが)、元の入力に関係なく、エイリアス、変数、関数など。POSIXにも移植可能であり(POSIXの名前で指定する必要があるかどうかは思い出せkill SIGNALSませんが)、間違いなくナンセンスではありません。

一方、その優雅さは確かに多くの要望を残しており、おそらく心配する価値はありませんが、それは完全に1つを無駄にし、シェルスパムを完全PID.に阻止するわけではありません。つまり、私のシェルではバックグラウンドレポートを有効にしているので、最初に実行したときに、シェルは2行でaを開いて無駄にしたことを親切に通知します。また、ファイル記述子と直接インターフェースするのではなくコピーするので、パイプなどに問題があると思います。これは私がすぐに自分自身を修正することができ、そしておそらくそうするでしょう。jobssetPID../cmdline0;

これを修正します。つまり、実行できると思われるように、代わりに使用する方法が見つからない場合は、SIGTSTP+SIGCONT最初にサブシェルの外側でプロセスを一時停止し、次にサブシェルの出力をリダイレクトした後にプロセスを続行します。これは私がまだ発見していない理由で信頼できないように見えますが、有望だと思います。おそらくnohuptrap(効果的rehupには)必要なものですが、それらをどのように組み合わせるのかはよくわかりません...

エイミーウェイ、それ以上の苦労なしに、私の半中絶された、後方のGUIランチャー:

% _G() { ( 
    _gui_cmd="$(tr '\0' ' ' </proc/"$\!"/cmdline )" ; 
    kill -9 "$\!" ; 
    exec eval "${_gui_cmd} &" ) 
    &>/dev/null 2&>1 
}
% google-chrome-beta --disk-cache-dir="/tmp/cache" --disk-cache-size=100000000 &_G                                                   
[1] 2674
[1]  + 2674 killed     google-chrome-beta --disk-cache-dir="/tmp/cache" --disk-cache-   
%

したがって、同様のことを行おうとすると発生する可能性のある別の問題は、シェルが想定する拡張の順序です。私のようなトリックがなければ、前のコマンドが引数として関数を引っ掛ける前に、関数を拡張するのに深刻な問題が発生することは間違いありません。_G元のコマンドのバックグラウンド命令に関数呼び出しを追加するだけで、不必要な冗長性なしにこれを防ぐことができたと&思います。実行したいコマンドの最後に追加&_Gするだけで、幸運を祈ります。

-マイク

PSわかりました。最後の文を書くと、で何ができるかを考えるようになりますtee

于 2013-11-21T21:26:12.990 に答える