web-dev-qa-db-ja.com

Bash:ターミナルがサードパーティアプリによって開かれているかどうかを確認する方法

Bashスクリプト(具体的には~/.bashrc)には、端末が私によって直接開かれた場合にのみ何かを行い、アプリを通じて開かれた場合は何か他のことを行います。 VSコード。どうすればケースを判断できますか?そのための変数はありますか?前もって感謝します。

9
PaperBag

おそらく、シェルの祖先をさかのぼって、「あなた」に相当する何かによって開始されたのか、それとも別のプログラムによって開始されたのかを調べることで、おそらくそれを行うことができます。

シェルのPID(プロセスID)を取得し、そのPPID(親プロセスID)から取得します。それがどこから来たのかを伝える何かに到達するまで、上がっていきます。あなたのシステムで実験する必要があるかもしれません-少なくとも、私はそれが普遍的であるかどうかを知りません。

たとえば、私のシステムでは、シェルのPIDを取得し、psを使用して、それがbashであることを示します。

$ echo $$
18852
$ ps --pid 18852
  PID TTY          TIME CMD
18852 pts/1    00:00:00 bash

18852のPPIDを取得します。

$ ps -o ppid= -p 18852
18842

PPID(18842)が何であるかを調べます。

$ ps --pid 18842
  PID TTY          TIME CMD
18842 ?        00:00:02 gnome-terminal

Gnome-terminal、つまりターミナルエミュレーター/ターミナルウィンドウが表示されます。他のプログラムによって起動されたシェルがターミナルエミュレータウィンドウで実行されていない場合は、それで十分かもしれません。

十分でない場合は、次のレベルに進みます。

$ ps -o ppid= -p 18842
 2313
$ ps --pid 2313
  PID TTY          TIME CMD
 2313 ?        00:00:00 init

これは、gnome-terminalinitによって開始されたことを示しています。別のプログラムによって起動されたシェルには、何か異なるものがあると思います。

10
Mark Smith

Visual Studio Codeに関する限り、明らかに 統合端末の追加の環境変数 を設定する方法があります。したがって、この構成を使用するようにVisual Studioをセットアップします。

"terminal.integrated.env.linux": {
  "visual_studio": "true"
}

そして~/.bashrc内:

if [ -n "$visual_studio" ]; then
    # do something for Visual Studio
else
    # do something else for other types of terminal
fi

一般に、bashプロセスに与えられた環境に依存できます。たとえば、 $TERM変数 で、if..then...else...fiまたはその他の同様の[ "$TERM" = "xterm" ]ブランチを実行します。ケースバイケースで、各コンソールでenvを実行して環境の違いを調査し、それをenv > output_console1.txtおよびdiff output_console1.txt output_console2.txtのようにファイルに保存できます- コメントのデザート

9

特定のサードパーティアプリについて話している場合は、環境変数を使用します。ほとんどのプログラムは、新しいプロセスをfork + execするときに、環境全体を変更せずに渡します。

したがって、確認できるカスタムenv変数でこのアプリを起動します。例えばalias vs=RUNNING_FROM_VSCODE=1 VSCodeのようなエイリアスを作成するか、次のようなラッパースクリプトを作成します。

#!/bin/sh
export RUNNING_FROM_VSCODE=1
exec VSCode "$@"

.bashrcで、次のことができます

if (($RUNNING_FROM_VSCODE)); then
   echo "started from inside VSCode"
   # RUNNING_FROM_VSCODE=0  # optional if you only want the immediate child
fi

式がゼロ以外の整数に評価される場合、bash算術ステートメント(( ))はtrueです(これが上記の1を使用した理由です)。空の文字列(設定されていないenv varの場合)はfalseです。 bashブール変数には便利ですが、trueを簡単に使用して、従来のPOSIXで確認することもできます。

if [ "x$RUNNING_FROM_VSCODE" = "xtrue" ]; then
   echo "started from inside VSCode"
fi

アプリのほとんどがその子の環境をクリアする場合で、$PATHを変更せずに渡す場合、ラッパーでこれを使用できます。

#!/bin/sh
export PATH="$PATH:/dev/null/RUNNING_FROM_VSCODE"
exec VSCode "$@"

そして、bash [[ "${PATH%RUNNING_FROM_VSCODE}" != "$PATH" ]]のようなパターンマッチでそれを確認し、PATHからサフィックスを削除すると変更されるかどうかを確認します。

これは、プログラムが見つからない外部コマンドを探しているときに、1つの余分なディレクトリルックアップを無害に実行するはずです。 /dev/nullはどのシステムのディレクトリでもないため、PATH検索で以前のPATHエントリで探しているものが見つからない場合はすぐにENOTDIRになります偽のディレクトリとして使用しても安全です。 。

2
Peter Cordes

これが私の2セントです。 .bashrcに追加するだけです。 terminalsをお気に入りの端末に、exportコマンドを自分の端末に置き換えます。

run_in_terminal(){
  local parent_command="$(ps --no-headers --pid $PPID -o command | awk '{print $1;}')"
  local parent="$(basename $parent_command)"
  local terminals=( gnome-terminal st xterm ) # list your favorite terminal here
  if [[ ${terminals[*]} =~ ${parent} ]]; then
    # Your commands to run if in terminal
    export MY_VAR_IN_TERMINAL="test"
  fi
}
run_in_terminal
1
Zalatik