回答:
この関数は仕事をする必要があります:
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
bash: [: too many arguments
。役立つ場合は、bash v4.2.24、python v2.7.3を入手しました。
これを試して:
echo $TERM
これはより信頼できますが、プログラムによって台無しになる可能性があります。しかし、私のxterm
場合はlinux
、Linuxコンソールの略だと思うttys にあります。
$TERM
は、実際のエミュレーター自体ではなく、使用しているターミナルエミュレーターによって自己報告された仕様を参照する変数です。たとえば、私のシステムでecho $TERM
は、xterm
実際にlxterminalを実行していても戻ります。何が起こっているかは、lxterminalがxtermコンプライアンスを自己報告することです。lxterminalは実際には完全にxtermに準拠していないため、注意する必要があります。通常、specファイルはにあり/usr/share/terminfo
ます。
親プロセス名を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/^.* //')
多くの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を取得します。何度も尋ねると、毎回異なる答えが返ってくるかもしれません!
しかし、娘を呼び出して「パパは誰ですか」と尋ねると、彼女はあなたに教えてくれます!非常に賢い。この方法を発明する天才になれたらいいのにと思います。
使用するpstree
とawk
easyest方法をされています。
pstree -sA $$ | awk -F "---" '{ print $2 }'
pstree
of $$
(通常のプロセス)でプロセスのツリーを表示します。pstree
引数:
-s
:プロセスの親を表示する-A
:出力を純粋なASCIIで表示します。awk
このツールは、パターンをスキャンし、-F
引数はプロセスを分割するために使用されます。
'{ print $2 }'
するawk
ように指示します。$2
?私の場合は、中に何パイプされawk
、実際にあるsystemd---lightdm---lightdm---upstart---gnome-terminal----bash---pstree
...
xfsettingsd
使用している端末の代わりに取得します。
pstree -sA $$ | head -n1 | awk -F "---" '{ print $(NF-1) }'
あなたは正しいです、私は見出しの質問に答えただけで、身体の質問には答えませんでした。それでは、ボブのヤーおじさん。
上記の回答の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に追加しました。
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
}
container
定義後に関数を実際に呼び出すことを忘れないでください。