現在使用されている端末エミュレータを確認するにはどうすればよいですか?


15

gnome-terminalとGuakeがインストールされています。これらのターミナルエミュレーターが起動すると、これらのターミナルエミュレーターに異なる起動メッセージが表示されるようにします。これを実現するために、どのコードを.bashrcに書くべきですか?

回答:


10

この関数は仕事をする必要があります:

container() {
    pid=$$
    while true; do
        pid=$(ps -h -o ppid -p $pid 2>/dev/null)
        case $(ps -h -o comm -p $pid 2>/dev/null) in
        (gnome-terminal) echo "Running in gnome terminal";return;;
        (xterm) echo "Running in xterm";return;;
        (rxvt) echo "Running in rxvt";return;;
        (python) if [ ! -z "$(ps -h -o args -p $pid 2>/dev/null | grep guake)" ]; then echo "Running in Guake"; return; fi ;;
        esac
        [[ $(echo $pid) == 1 ]] && break
    done
}
container

いい答え!container定義後に関数を実際に呼び出すことを忘れないでください。
ロッシュ

私はこれが明らかであると思っていましたが、あなたは正しいです、それに応じて更新された答え。
jlliagre

@jlliagreコードを試しました。gnome-terminalではスムーズに動作しますが、Guakeでは問題があります。何も出力しません。代わりに、デッドロック状態のようにフリーズします。使用するにはCtrl + Cを押す必要があります。コードを本当に理解していなかったので、どこが間違っているのかわかりません。
VedVals

コードが修正されました。guakeがpythonで実行されていなかったため、関数が終了できないバグがありました。フィードバックをお寄せいただきありがとうございます。
jlliagre

申し訳ありませんが、まだうまくいきません。エラーを与えますbash: [: too many arguments。役立つ場合は、bash v4.2.24、python v2.7.3を入手しました。
VedVals

10

これを試して:

echo $TERM

これはより信頼できますが、プログラムによって台無しになる可能性があります。しかし、私のxterm場合はlinux、Linuxコンソールの略だと思うttys にあります。


2
$TERMは、実際のエミュレーター自体ではなく、使用しているターミナルエミュレーターによって自己報告された仕様を参照する変数です。たとえば、私のシステムでecho $TERMは、xterm実際にlxterminalを実行していても戻ります。何が起こっているかは、lxterminalがxtermコンプライアンスを自己報告することです。lxterminalは実際には完全にxtermに準拠していないため、注意する必要があります。通常、specファイルはにあり/usr/share/terminfoます。
スタッズ16

7

親プロセス名をgrepすることにより、端末エミュレーター名を取得できます。したがって、すべてのターミナルエミュレータで動作します。

bash、zshなど:

basename "/"$(ps -f -p $(cat /proc/$(echo $$)/stat | cut -d \  -f 4) | tail -1 | sed 's/^.* //')

魚殻付き:

basename "/"(ps -f -p (cat /proc/(echo %self)/stat | cut -d \  -f 4) | tail -1 | sed 's/^.* //')

ただし、ターミナルエミュレータを起動するとプログラム引数がキャッチされることに注意してください。
ロボベンクライン

SSHを使用して接続している場合、これは機能しますか?
user3731622

@ user3731622それはしません!クライアントから転送する必要があります。
エンリコ

2

多くのLinuxシステムのecho $TERMリターンxtermについては、上記のstazherの投稿を参照してください。

実際の端末を使用するには、次を実行します。

1:現在実行中のすべてのターミナルインスタンスを閉じます。

2:通常の方法で新しいターミナルを開きます。

3:次のようにコマンドを入力します。

ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)

4:返品は次のようになります。

lxterminal --geometry=135x20

内訳は次のとおりです。

だから:ps「プロセスステータス」です

psオプション-oは、指定されたキーワードのスペースまたはコンマ区切りリストに関連する情報を表示します。複雑に聞こえますが、実際はそうではありません。(スペースまたはコンマ)で区切られた(キーワードのリスト)指定。

そのため、(キーワードのリスト)は'cmd='リスト内の1つのキーワードのみです。そのため、ターミナルを開くためのコマンドを表示するだけです。

psオプション-pは「プロセスIDによる」ですこれはpsにとって非常に素晴らしいオプションです。問題は、psにこのプロセスIDを渡す必要があることです。だから、プロセスIDを取得する方法は?式を解きます $(ps -o 'ppid=' -p $$)

ここで、もう少し深く考え始めなければなりません。このbashワンライナーを発明したいのですが、そうではありませんでした。https://wiki.archlinux.org/からそれを盗んだと思いますが、再び見つけることができませんでした。それらの人は素晴らしいですが、多くの場合、多くの勉強をするまで彼らが何をすべきかを理解できません。私たちができることは、私が説明するので、今それを理解することです。

そのため$、bashには展開演算子があります。「ラップ解除」を考えるのが好きです。したがって、$(foo -opt bar)「foo -opt bar」を展開または展開します。しかし、bashでは、単一の丸括弧(...)がサブシェルを開きます。

したがって、ドーターシェルで実行されるように$(foo -opt bar)「foo -opt bar」展開します。非常に奇妙で理解しにくい。

さて、今はほぼ同じコマンドを再び実行していますps -o 'ppid=' -p $$が、今回はps(プロセスステータス)が、娘シェルインスタンス内から彼が見ることができるものを示しています

-oキーワードのリスト、前と同じ1つのキーワードですが、ppid=これは親シェルのプロセスIDを直接要求しています!! ドーターシェル内から!とても賢いですね これを理解できると、とても興奮します!

-p繰り返しますが、 "by process id"およびbash $$のプロセスIDです。

ps -o 'ppid=' -p $$、または$$最初のシェルから直接要求する他のコマンドを呼び出す場合、彼はpid = 1、またはxWindowから、またはデスクトッププログラムからpidを言うか、実際のシェルのpidを取得します。何度も尋ねると、毎回異なる答えが返ってくるかもしれません!

しかし、娘を呼び出して「パパは誰ですか」と尋ねると、彼女はあなたに教えてくれます!非常に賢い。この方法を発明する天才になれたらいいのにと思います。


AUは1つの投稿内で適切な内訳を許可しません。申し訳ありませんが、ブログシステムとの戦いや複数の投稿を行うつもりはありません。たぶん、あなたはアイデアを得ることができます。
スタッシャー16

あなたの他の答えは、質問に対する答えではなく、この答えに対する洗練された有益なコメントのようです...質問に完全に答えます。----を使用して中央に線を引きますか?ボタンもあります。
ザンナ

私はOPの質問に正確かつ詳細に答えたと思います。ブログ編集システムを理解して終了する前に、あなたは私に飛びつきました。賛成票を投じて、私はそれに慣れています。
-stazher

1
私はあなたに飛びついたとは思わない、私はちょうどレビューをしていた...あなたの投稿をより完全にしてくれてありがとう
-Zanna

ご回答ありがとうございます。ごめんなさい、たぶん私はあなたに飛びつきました。大変おaび申し上げます。
-stazher

1

使用するpstreeawkeasyest方法をされています。

pstree -sA $$ | awk -F "---" '{ print $2 }'

説明する

  1. pstreeof $$(通常のプロセス)でプロセスのツリーを表示します。
  2. pstree引数:

    • -s:プロセスの親を表示する
    • -A:出力を純粋なASCIIで表示します。
  3. awkこのツールは、パターンをスキャンし、-F引数はプロセスを分割するために使用されます。

  4. 最後に、2番目の一致パターン(この場合は端末エミュレーター名)のみを出力'{ print $2 }'するawkように指示します。

あなたはおよそよろしいですか$2?私の場合は、中に何パイプされawk、実際にあるsystemd---lightdm---lightdm---upstart---gnome-terminal----bash---pstree...
エンリコ・マリア・デ・アンジェリス

@EnricoMariaDeAngelisヤ。ご観察ありがとうございます。私の場合、ターミナルエミュレータはsystemdサービスで直接初期化されます。コードを再度確認し、修正して編集します。
silvadev

キーボードショートカットを使用してエミュレータを起動すると、これは機能しません。XFCEでは、xfsettingsd使用している端末の代わりに取得します。
マイケルホフマン

あなたは最後から開始した場合、より良い作品:pstree -sA $$ | head -n1 | awk -F "---" '{ print $(NF-1) }'
lleaff

0

あなたは正しいです、私は見出しの質問に答えただけで、身体の質問には答えませんでした。それでは、ボブのヤーおじさん。

上記の回答の1つでは、ケースの切り替えが何であるかはわかりません。このようなケースの切り替えは必要ありません。私の〜/ .bashrcスクリプトは実際には単純な1行のみであり、すべてのechoコマンドはただの楽しみのためです。説明方法...

開始時の用語は〜/ .bashrcを読み取り、.bashrcに表示されるコマンドを実行します。したがって、どの用語が呼び出されても、彼は.bashrcを読み取り、コマンドを実行します。したがって、.bashrcで必要な構造は、ある用語または別の用語の動作を変更または除外することだけです。望ましい動作は、すべての用語で同じコマンドを実行することであるため、ケースの切り替えは不要です。ターミナル自体が、彼がどのように呼ばれたかを教えてくれるので、区別する必要はありません。

注(1)guakeのテストは行いませんでしたが、jlliagreによる最初の回答で言及した他のすべてのテストで動作します。

注(2)wikiのマークダウンでの書式設定により、図のようにカットアンドペーストすることはできません。下線文字を削除するなど、各バックティックを削除し、実際のバックティックを追加するps必要があり-p $$)ます。前後にはスペースがありません。

〜/ .bashrcのスクリプト

# show welcome message for actual terminal in use
echo "Welcome.  You are attempting to use"
echo ""
echo _backtick_ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)_backtick_
echo ""
echo "Good Luck and God Speed."

これはとても楽しかったです。これを自分の〜/ .bashrcに追加しました。


Tildaでテスト済みのNote(1)に従って、正常に動作します。GuakeはTildaに似ていますが、Pythonで書かれているため、Guakeについてはまだ知りません。
-stazher

0

bashを使用している場合、このコマンドが役立ちます。

which $(ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$))


0

ZSHを使用している場合は、ZSHビルトインのみを使用して/proc/$pid/{stat,cmdline}直接操作する、より優れた(より高速な)ソリューションがあります。

get-terminal-emulator() {
    if [[ $TTY = "/dev/tty"* ]]; then
        echo "linux-console"
        return
    fi
    local pid=$$ name=''
    while true; do
        proc_stat=(${(@f)$(</proc/${pid}/stat)})
        name=${proc_stat[2]//[()]/}
        case "${name}" in
            gnome-terminal|konsole|rxvt|xterm)
                echo "${name}"; return ;;
            python*)
                local cmdline=(${(@f)$(</proc/${pid}/cmdline)})
                if [[ "$cmdline" =~ "\\bguake.main\\b" ]]; then
                    echo "guake"; return
                fi
                ;;
        esac
        if test "$pid" = "1" -o "$pid" = ""; then
            echo "unknown"
            return
        fi
        pid=${proc_stat[4]}       
    done
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.