私は遅いアプローチを使用しました。
$ 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
確認し、出力がどのターミナルに行くかを確認してエラーを見つけます。^C
tty<&1
tty<&2
あなたが使用できる:
tty=$(tty) || { tty=$(tty<&3); } 3<&1 || tty=$(tty<&2)
stdin、stdout、またはstderrでttyを探してください$tty
。
これはzshの特殊変数に含まれています。ただし、3 つのファイル記述子のどれも tty に達していない場合、制御端末があれば制御端末を取得し$TTY
、そうでなければ空の文字列 (代わりに) を取得します。/dev/tty
not a tty
とにかく、これはそうでないかもしれません。偽端末機器擬似端末装置の経路形状は、システムやバージョンによって異なり、等になることがあり/dev/pts/somenumber
ます/dev/ptyx
。