私は、グラフィックデスクトップを使用するよりも、ターミナルウィンドウでGUIアプリケーションを起動する方が好きです。一般的な苦情は、開発者がこのタイプの使用を予期しないことが多いため、アプリケーションがstdoutまたはstderrに役に立たない、秘密、または情報のないメッセージを一括印刷することです。 & を使用してバックグラウンドでプログラムを実行すると、ジョブの作成と終了に関するレポートが生成されるため、端末でさらに混乱が発生します。
コマンドライン引数を受け入れてオートコンプリートを処理するこれらの問題の回避策は何ですか?
関連:https://stackoverflow.com/questions/7131670/make-bash-alias-that-takes-parameter
答え1
標準エラーを直ちにリダイレクトすることは、以前の/dev/null
エラーメッセージを隠してエラーを診断するのが難しいかもしれないので、悪い考えです。次のzshスクリプトを使用することをお勧めしますstart-app
。
#!/usr/bin/env zsh
coproc "$@" 2>&1
quit=$(($(date +%s)+5))
nlines=0
while [[ $((nlines++)) -lt 10 ]] && read -p -t 5 line
do
[[ $(date +%s) -ge $quit ]] && break
printf "[%s] %s\n" "$(date +%T)" "$line"
done &
ただ実行してみてください:start-app your_command argument ...
スクリプトは最大5秒間最大10行のメッセージを出力します。ただし、アプリケーションが直ちにクラッシュした場合(たとえば、分割エラーのため)、エラーメッセージは表示されません。もちろん、必要に応じてこのスクリプトをさまざまな方法で変更できます。
注:zshで補完機能を使用するには、start-app
次のようにします。
compdef _precommand start-app
バッシュから:
complete -F _command start-app
(でおよびexec
からtime
コピー/usr/share/bash-completion/bash_completion
)。
答え2
この答えはbashについてです。たとえば、ev
PDFビューアEvinceを起動する便利なコマンドを作成するために.bashrcで実行した操作は次のとおりです。
ev() { (evince "$1" 1>/dev/null 2>/dev/null &) }
complete -f -o default -X '!*.pdf' ev
最初の行は関数を定義しますev
。コマンドラインで関数を使用すると、関数名は次のように認識されます。
ev foo.pdf
(これはエイリアスとは異なるメカニズムであり、優先度が低いです。)stdinとstdoutへのEvinceの出力はbitbucket(/ dev / null)に送信されます。 &記号はタスクをバックグラウンドに残します。コマンドを括弧で囲むと、そのコマンドはサブシェルで実行されるため、バックグラウンドジョブの作成または完了に関するメッセージは印刷されません。
私の.bashrcの2行目はbashのフル機能を使用して、evコマンドの引数がpdf拡張子を持つファイルでなければならないことをbashに伝えます。これは、私のディレクトリにfoo.tex、foo.auxなどのファイルもある場合、ev foo
Tabを入力して押すと、bashがファイル名をfoo.pdfに完成することがわかります。
答え3
command
もう1つの可能性はダウングレードを使用することです。exec
特別な次の一般的な既存の組み込み機能に組み込み:
alias shh='command exec >/dev/null 2>&1'
これで、次のことができます。
(shh; call some process &)
command
これだけがうまくいかないことがわかりました。zsh
(ほとんどの他のシェルと同様)しかし、うまくいかない場合は、次のようにすることができます。
alias shh='eval "exec >/dev/null 2>&1"'
...これはどこでも機能します。
実際には、次のようにすることもできます。
alias shh='command exec >"${O:-/dev/null}" 2>&1'
だからあなたはこれを行うことができます:
O=./logfile; (shh;echo can anyone hear &)
O=; (shh; echo this\? &)
cat ./logfile
出力
can anyone hear
@vinc17のコメントについて議論した後、ほぼすべてのGUIアプリケーションのコンソール出力は通常X
stty(対応するコンソール)用であることに注意する価値があります。ファイルX
からアプリケーションを実行すると、X
.desktop
生成された出力はX
仮想端末にルーティングされます。これはX
最初に始まったttyです。このtty番号を使用してアドレスを指定できます$XDG_VTNR
。
しかし、奇妙なことに - ちょうど使い始めたのかstartx
- これ以上書くことはできないようです/dev/tty$XDG_VTNR
。(私の考えでは、その可能性が高いと思います)v1.16で最近実装された主な変更に関連して、要件の代わりにXorg
ユーザーセッションで実行できます。systemd
根特権。
しかし、私はこれを行うことができます:
alias gui='command exec >/dev/tty$((1+$XDG_VTNR)) 2>&1'
(gui; some x app &)
これで、すべてのコンソール出力が私のptyの代わりsome x app
にルーティングされます。次のようにいつでも最後のページを取得できます。/dev/tty$((1+$XDG_VTNR))
xterm
fmt </dev/vcs$((1+$XDG_VTNR))
いずれにせよ、最良の方法は、出力ロギングにのみいくつかの仮想端末を使用することです。これは通常これのためにすでに予約されていますが、この記事を幸せにするために必要なことをしたく/dev/console
ないかもしれません。おそらく基本的に印刷をchown
行うことができる機能があるでしょうので、そのように使用することが可能だろうと思いました。printk
/dev/console
これを行う別の方法は、具体的にフーティこの目標を達成します。たとえば、xterm
ウィンドウを開いたままにして実行結果を環境変数に保存し、その値をtty
出力先として使用できます。gui
これにより、すべてのログが別々のログウィンドウにルーティングされ、必要に応じてスクロールできます。
私が一度書いたことがある回答bash
興味があれば、歴史と似たようなことをする方法を学ぶことができます。