ユーザーが開いた端末の数を検出する方法


9

私はUbuntuのを使用していますし、手動で変更することができますbashにシェルプロンプトの色を使用します

export PS1="\e[0;32m[\u@\h \W]\$ \e[m" 

ただし、新しいターミナルまたはタブを開くたびに、シェルプロンプトの色が自動的に変更されるようにしたいと思います。基本的なtty TERMには16色があり、16個を超えるターミナルが開いている場合は色を回転しても問題ありません。解決策は、私が通じ接続したときに動作しますPuttytmuxまたはscreen

私の考えは.bashrc、ユーザーが開いた新しいターミナルセッションを検出し、グローバルカウンターをから\e[0;31m[に増やすシェルスクリプトを記述して、そこに配置すること\e[0;47m[です。ユーザーが開いた端末の数を検出するにはどうすればよいですか?

回答:


8

開いているターミナルの数を取得する必要がある場合は、自分が所有しているファイルの数を数えます/dev/pts(ただし、グラフィカルターミナルエミュレーターではなく、バックグラウンドプロセスによって開かれたものも含まれます)。または、Jacobの応答の最初の行に示されているように、ターミナルエミュレーターの子プロセスの数をカウントします。

新しいバージョンでは機能しないwhoため、の出力に依存したり、gnome-pty-helperプロセスを探したりしないでくださいgnome-terminal

現在、ほとんどすべてのグラフィカル端末エミュレーター(パテを含む)とマルチプレクサー(画面、tmux)は256色をサポートしています。このパレットを使用すると、本当に素敵な色のプロンプトが表示されます。

非常に単純なソリューションに対する私の推奨は、現在のttyラインの番号に基づいて色を決めることです。たとえば、ttyコマンドの出力を処理して、数値のみを取得し、そこから色を導き出します。特定のtty行番号は一度に1つの端末にのみ与えられます。同じ端末番号がカーネルによって再発行される前に、まずその端末を閉じる必要があります。これを256色と組み合わせると、特定の時間に同じ色が2度表示されないことが自動的に保証されます(16色を使用しても、均等な分布が得られます)。グローバルカウンターを維持する必要も、端末やプロセスをカウントする必要もありません。


1
との美しいアイデアtty。私たち/他の人たちはその「質問」に集中しすぎて、「必要性」全体に他の解決策があるかもしれないことを忘れていたと思います:)ランダムカラーセレクターの実装を試してみます。256色の場合、同じ/類似の色を選択することはあまりありません。ただし、指定されたpts番号の色を手動で設定すると、パーソナライズが向上します。
GreggD 2016年

@TedM。はい、質問はXY質問のように、「各端末で異なる色にしたいので、端末の数を数えるにはどうすればよいですか?」
egmont

@TedM。ランダムもいいアイデアです!(確定的マッピングのプロパティの1つは、sudoを実行した後、新しいユーザーが同じプロンプトの色を簡単に設定できることです。これは、元の
質問者

1
ランダマイザーは非常に簡単です:(color="\e[38;5;"$(((RANDOM % 231 )+1))"m"グレースケールを拒否するには231のみ)。ただし、これらの色の多くは単に異なる色合いであり、それらのいくつかは暗いためほとんど見えない可能性があり、実際には誰もそれを使用しないと思います...
GreggD

質問者のUbuntuバージョンはわかりません。16.04では間違いなくgnome-pty-helperはもうありません(git.gnome.org/browse/vte/commit/?id=299c700)。古いバージョンの正確なプロセス階層をチェックするためにダウングレードするつもりはありません。以前はそのようなプロセスがあったことは知っていますが、親子階層がどのように見えるかは完全にはわかりません。ちなみに、元の返答から子プロセス数の考え方を取り入れたので、「(あなたも)」ということはわかりませんが、気にしないでください。
エモント2016年

5

シングルユーザーの状況で、の例をとると、xtermのPIDの数を数えるだけxtermです。xtermウィンドウごとに個別のPIDを作成します。
gnome-terminalただし、単一のpidを実行しますが、良いニュースは、すべてのウィンドウやタブごとに子プロセスを作成することです。次のコマンドでこれらの子プロセスを取得できます。

pgrep -P <pid_of_gnome-terminal>

ただし、対処するいくつかの複雑な問題があります。

  • あなたの質問を読んで、この場合のユーザーは実際にはx-sessionの所有者であると想定するかもしれません。通常、単に$USER-variableを使用できますが、これは、現在ログインしているのユーザーと一致しない場合があり$DISPLAYます。

  • マルチユーザーの状況では、(どちらの)端末アプリケーションに属しているPIDが必ずしも現在のに属しているとは限りません$DISPLAY。関連するpidとchild-pidのみを分割する必要があります。

  • Unity(15.10以下)では、2番目のユーザーがログインすると、追加のプロセスが開始され(gnome-pty-helper)、これはで子プロセスとして表示されますgnome-terminalが、プロセスには(明らかに)ウィンドウまたはタブがありません。上メイト、プロセスはとにかく存在します。

要するに

端末アプリケーションのタブやウィンドウの数を数えるには、次のことを行う必要があります。

  • 複数のPID または 1つのPID $DISPLAY(Xセッション)を持つターミナルアプリケーションを実行しているかどうかを確認します
  • 実行中のプロセスから、関連するPID のみを分割し、これで実行します$DISPLAY
  • アプリケーションがpid(windows / tabsの場合)の子プロセスを実行する場合は、実行されているかどうかgnome-pty-helperを確認して、数を修正してください。

ただし、現在開いているウィンドウやタブの数を確実に見つけるために、これは非常にうまくスクリプト化できます。

スクリプト

以下のスクリプトでは、ターゲットの端末アプリケーションが引数として使用されています。このスクリプトは、テストした多くの端末で動作します。Tilda現時点では例外です。

  • 2人のユーザーがログインしています。1人(現在ではない)に2つのgnome-terminalウィンドウ、1人(画像の1人)に3つのgnome-terminalウィンドウ、2つのxtermウィンドウがあります。

ここに画像の説明を入力してください

コマンド:

/path/to/get_terms.sh gnome-terminal

出力:

3

ながら

/path/to/get_terms.sh xterm

出力:

2

スクリプト

#!/bin/bash

terminal=$1

# get the user running the current x-session
username=$(who | grep $DISPLAY | head -1 | awk '{print $1}')
# get the pid of the terminal for the current user
userpid=$(pgrep -u $username $terminal)
# check what type the terminal is (multi pid/single pid)
npids="$(echo "$userpid" | wc -w)"
# in case of a single pid, count the children
if [ "$npids" -eq 1 ]; then
  # check if gnome-pty-helper runs (starts when multiple users are logged in)
  ptpid=$(pgrep gnome-pty-helpe)
  # get number of child- procs
  let "orig = $( pgrep -P $(pgrep -u $username $terminal) | wc -w )" 
  # if pty-helper runs, correct the number of child procs
  if [ -n "$ptpid" ] && [ -n "$userpid" ]; then
    let "n_terms = $orig-1"; else let "n_terms = $orig"
  fi
  # if no child procs run, n-terminals = n-counted pids (difference Mate <> Unity)
  if [ "$n_terms" -eq 0 ]; then echo $orig; else echo $n_terms; fi
# in case of multiple pids, count the pids
elif [ "$npids" -gt 1 ]; then echo $npids
fi

使用するには

  • スクリプトを空のファイルにコピーし、として保存しget_terms.sh、実行可能にして、次のコマンドで実行します。

    /path/to/get_terms.sh <terminal_application>

ここではgnome-pty-helper、ログインしているユーザーが1人だけの場合(再起動直後)でも常に1つ実行しています。任意の数のターミナルを開くと、同じヘルパーで2番目に実行されます。あなたの新しいスクリプトはmate-terminalで機能しているようです(そのゼロを引き起こすことはできませんでした)が、xtermでは、1つしか開いていない0と、それは表示され、2番目の後にのみ適切な数を示し始め、gnome-terminalで常に1つ少なく表示されます(1つ0だけが開かれているときに出力します)。
GreggD 2016年

@TedM。おかげで、それは現在修正されている有用な情報です。
Jacob Vlijm 2016年

私はあなたの「情熱」に本当に感心します:) ...しかし、gnome-terminalにはまだ問題があります。1は1を与え、2は1を与え、3は2を与え、4は3を与えます。さらに、私の新しい発見であるMATEの「ティルダ」(私の答えの1つの余分な「不明」端末)もgnome-terminalと同じ問題を抱えていますが、それはタブです。xtermとmate-terminalは正常に動作しているようです。
GreggD 2016年

@TedM。言及してくれてありがとう!ばかげた質問ですが、本当に最新のコードを使用していますか?Mate 15.10では、すべてのテストを例外なく実行します。あなたのメイトバージョンは何ですか?Unityでは、すべてがすでに正常に機能しています。
Jacob Vlijm 2016年

@TedM。私のかなり空いている15.10 Mateにも、デフォルトで存在しています。テストを完全に再実行しただけです!明日くらいに、編集したスクリプトを実行して出力をどこかに投稿して、あなたのケースで何が例外を引き起こしているのかを確認してもらえますか?
Jacob Vlijm 2016年

1

awk道:

who | awk 'BEGIN{count=0}{ if(NR!=1){count++} }END{print count}'

説明:

上記の1つのライナーコマンドでawkは、ターミナルの数を見つけるために使用されます。awkプログラム内では、whoコマンドが返す行数を確認しているだけです-1。


これは私には0を返しますが、これは明らかに正しくありません...
Zanna

これは私のmate-terminalとxtermにとって非常にうまく機能し、防弾のようです。
GreggD 2016年

簡潔に:who | awk 'END{print NR - 1}'、何が欲しいの行数であるから- 1
muru

0

単純な方法としては、単に実行することもできますSystem Monitor(ターミナルから開始する場合は、を記述する必要がありますgnome-system-monitor)。[プロセス]タブで、実行中のプロセスを名前で並べ替えBash、リスト内の出現回数をカウントします(並べ替えるとすべてがまとめられます)名前なので、数えるのは簡単です)。

ユーザーごとに開いている端末の数を確認する場合Bashは、検索する必要がありGnome Terminalます。ターミナルを開くGnome Terminalと、プロセスリストにも表示されますが、ターミナルをさらに開いても1つだけ残ります。の[表示]ボタンをSystem Monitor使用すると、表示するプロセスを設定できます。すべてのプロセス/ユーザープロセス/アクティブ...


OPは結果を使用して端末の色を自動的に設定することを望んでいるため、これは実際に関連するオプションではないようです。
Jacob Vlijm 2016年

申し訳ありませんが、彼はスクリプトでそれを使用したいと思っています。しかし、ps -ef | grep UserName | grep bash | grep -v grep | wc -lは機能しませんか?
NonStandardModel
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.