実行中の端末をエコーするポイントは何ですか?

実行中の端末をエコーするポイントは何ですか?

私は遅いアプローチを使用しました。

$ ps | grep bash | grep -oP '/[0-9]+' | grep -oP '[0-9]+'

同じことを行うより良い方法は何ですか?

答え1

まあ、単に以下を発行することができます:

tty

例:

$ tty
/dev/pts/0

もしあなたならただ端末番号を取得するには:

$ tty | grep -Po '\d+$'
0

からman tty

名前
       tty - 接続端末のファイル名を出力します。
       標準入力

答え2

このソリューションの利点は、空の文字列を出力し、TTYが次の形式ではない場合に失敗を返すことです/dev/pts/###

tty | grep -Po '(?<=^/dev/pts/)\d+$'

答え3

ps -o tty= -p "$$"

あなたのため制御端子(指定されていない形式ですが、私が知っている実装ではプレフィックスのないデバイスパスです。/dev/)pidを持つプロセスは$$シェルを実行するプロセスです。psそれ自体はそのプロセスの子プロセスであるか、そのプロセスの子プロセスになり、同じセッションにあるため、同じ制御ttyを持ちます。

これはttyがを指すのと同じです/dev/tty

セッションがttyを制御しない場合(通常は、シェルがターミナルで起動されていないが一部のデーモンによって開始されcronシャドウで実行される場合)、?シェルを実行するプロセスが終了すると、何も取得されません。出力。

このttyコマンドは、stdin(存在する場合)で開かれたttyデバイスのパスと次の内容を印刷します。ttyではないそれ以外の場合はエラーが発生します。

だから:

controlling_tty=$(ps -o tty= -p "$$")
case $controlling_tty in
  ('?') echo>&2 'No controlling tty'; exit 1;;
  ('') echo>&2 'Cannot determine the controlling tty'; exit 1;;
  (*) controlling_tty=/dev/$controlling_tty;;
esac
printf '%s\n' "The controlling tty is $controlling_tty"

または

if ! tty_on_stdin=$(tty); then
  echo>&2 'No tty on stdin or cannot determine which it is'
  exit 1
fi
printf '%s\n' "The tty on stdin is $tty_on_stdin"

ほとんどの実際の状況では、とは$controlling_terminal同じ$tty_on_stdinですが、必ずしもそうではありません。

ユースケースに応じて、どちらかを好むこともできます。たとえば、これを使用して、tty入力がどの端末から来たのかを判断できます。どのターミナルプレスがSIGINTを送信しているかをps確認し、出力がどのターミナルに行くかを確認してエラーを見つけます。^Ctty<&1tty<&2

あなたが使用できる:

tty=$(tty) || { tty=$(tty<&3); } 3<&1 || tty=$(tty<&2)

stdin、stdout、またはstderrでttyを探してください$tty

これはzshの特殊変数に含まれています。ただし、3 つのファイル記述子のどれも tty に達していない場合、制御端末があれば制御端末を取得し$TTY、そうでなければ空の文字列 (代わりに) を取得します。/dev/ttynot a tty

とにかく、これはそうでないかもしれません。端末機器擬似端末装置の経路形状は、システムやバージョンによって異なり、等になることがあり/dev/pts/somenumberます/dev/ptyx

関連情報