スクリプトからターミナルを識別するにはどうすればいいですか?

スクリプトからターミナルを識別するにはどうすればいいですか?

そして、「 」とは言わないでください。$TERM常に ですxterm

bashスクリプトは、どのターミナルで実行されているか、具体的には iTerm、Terminal.app、または実際には xterm であるかをどのように判断できますか?

resetTerminal.appとiTerm2ではすぐには動作しない¹ので質問します。ただし、iTerm2はターミナルリセット( \x1b]50;ClearScrollback\x07)を実行するためのエスケープシーケンスを認識します。これを検出できれば、reset正しい動作をするエイリアスで上書きできます。私の知る限り、Terminal.appにはリセットシーケンスがなく、人々はそれを回避するために馬鹿げたトムハッカーに頼る

ここでの私の最終目標は、resetOS X と Linux のどちらで作業していても、ローカルで作業していても SSH 経由でリモートで作業していても、同じように動作することです。(どちらで作業しているかを覚えておくのは面倒ですし、reset && command-that-outputs-a-bunchアップエンターで作業できると便利です。) Terminal.app と iTerm は、正しく実装されていないため、この計画に支障をきたしていますreset

つまり、単純にオーバーライドするだけではreset不十分です。Linux マシンの場合、gnome-terminal正しいエスケープ シーケンスを送信するには、 または iTerm のどちらを使用しているかを認識する必要があります。

ioctl端末に何を問い合わせるか(必要な場合でも)方法はありますか?本当には?

¹この質問の目的上、リセットは画面をクリアし、カーソルをリセットし、スクロールバック バッファを消去する必要があります。

答え1

使用$TERM_PROGRAM

iTerm は に設定しiTerm.app、Terminal.app は に設定しますApple_Terminal

答え2

$TERMは現在実行中のターミナル エミュレータとはまったく関係ありません。これは単にデフォルトのターミナルであり、任意の値に設定できます。実行中のターミナル エミュレータの名前を取得するには、ps現在のシェルの親プロセスの PID を取得します。

注意: 以下は OSX では失敗しますが、Linux では問題なく動作するはずです。

現在のシェル プロセスの PID は です$$。そこから、 を使用してpsプロセス ツリーを表示し、現在のシェル セッションの親の PID を印刷できます。

ps -axjf | awk -v pid=$$ '($2==pid){print $1}'

次に、その PID を に渡してps、コマンド名を印刷するように指示します。

ps -o comm=  $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}')

これで名前が切り捨てられます。名前を理解するには十分ですが、スクリプトには適さないかもしれません。完全な名前を取得するには、次のようにします。

ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | awk '{print $NF}'

これは、いくつかの異なる端末を使用してシステム上で取得したものです。

  1. terminator

    $ ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | 
       awk '{print $NF}'
    /usr/bin/x-terminal-emulator
    
  2. gnome-terminal

    $ ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | 
       awk '{print $NF}'
    /usr/lib/gnome-terminal/gnome-terminal-server
    
  3. xterm

    $ ps --no-headers $(ps axjf | awk -v pid=$$ '($2==pid){print $1}') | 
       awk '{print $NF}'
    xterm
    

答え3

親プロセスの名前またはパスを取得する移植可能な方法を次に示します。

iTerm2: ターミナル2:

$ ps -p $(ps -p $$ -o ppid=) -o comm=
/Applications/iTerm.app/Contents/MacOS/iTerm

Ubuntu の gnome-terminal:

$ ps -p $(ps -p $$ -o ppid=) -o comm=
gnome-terminal

ターミナルアプリ:

$ ps -p $(ps -p $$ -o ppid=) -o comm=
login

loginTerminal.app がデフォルトのログイン シェルで新しいシェルを開くように設定されている場合、ターミナルではなくシェルの親プロセスが開かれることに注意してください。

このcomm列は、OS X のコマンドの完全なパスと、Linux の procps 実装で 15 文字に切り捨てられたコマンド名です。

関連情報