私のシェルがターミナルで実行されているかどうかをどうやって確認できますか?

私のシェルがターミナルで実行されているかどうかをどうやって確認できますか?

私のシェルが端末に「接続」されているときにのみ実行したいと思います。つまり、私のstdinが端末の入力から出て、stdout(そしてstderr?おそらく重要ではないかもしれません)が印刷/反転されたときにのみ実行したいのです。端末の特定の作業。

GNU / Linuxの詳細(たとえば)に直接依存せずにこれを行うにはどうすればよいですか/proc/self

答え1

isattyこれを確認する機能です、しかも-ttestコマンドシンボルシェルスクリプトからアクセスできます。

-ティー ファイル記述子

ファイル記述子番号が真の場合ファイル記述子端末が開いて接続されました。偽ならファイル記述子有効なファイル記述子番号ではないか、ファイル記述子番号ファイル記述子開いていないか開いていますが、端末に接続されていません。

以下を使用して、FD 0(標準入力)がTTYであることを確認できます。

test -t 0

FD 1 と 2 に対して同じ操作を実行して、出力ストリームとエラーストリーム、またはその両方を確認できます。

test -t 0 -a -t 1 -a -t 2

このコマンドは、記述子が端末に接続されている場合は0(成功)を返し、そうでない場合はfalseを返します。

test[「ブラケットテスト」としても使用できるコマンド:

 if [ -t 0 ] ; then ...

この条件を作成する慣用的な方法です。

答え2

すでに提供されている素晴らしい回答の上に追加のメモを追加するだけです。ファイル記述子0テストは、[ -t 0 ]tty行規則を使用してデバイスファイルであるファイルを開きます(通常、これは無害なtermio(s)ioctl()が成功したかどうかを確認することによって行われます)。

また、これは反対側に端末または端末エミュレータ(実際のユーザーがキーボードを入力する場合)があるという意味ではありません(ほとんどの場合、おそらく興味のあるほとんどの場合はおおよその数値で十分ですが)。 。

tty および pty デバイスは、データ転送またはプロセス間通信メカニズムとしても使用できます。

たとえば、次のようにできます。

(stty raw -echo; myscript) < /dev/ttyS0

RS232を介して受信したコンテンツをに送信しますmyscript

echo test | ssh -tt host myscript

stdinmyscriptはptyデバイスです(sshdもう一方の端では最終的に(ssh経由で接続されている)端末ではなく、端末が提供するパイプですecho

RS232 行または pty の反対側の端に端末があるかどうかをさらに確認するには、変数が設定されていて$TERM空でないことを確認して[ -n "$TERM" ]送信します。装備状況報告fdエスケープシーケンスを渡し、応答を受信したことを確認します(および除く[ -t 0 ][ -n "$TERM" ]

printf >&0 '\e[5n'

\e[0nほとんどの端末は「a」で応答します。

これでいくつかの問題があるため、視覚的なTUIアプリケーションを実行するためにこれを確認したくない限り、この方法はお勧めできません。この場合、同様のライブラリを使用することをお勧めし、ncursesデバイスIDを送信することをお勧めします。代わりに、DSRの代わりに定義シーケンスを使用して、次よりも正確に端末タイプを照会します$TERM

  • ありがたいことに、ほとんどの場合、stdinは端末ではなく読み取り専用モードで開いているためprintfエラーが発生しますが、stdinが読み取り+書き込みモードで開かれたttyデバイスの場合、そのデバイスを送信する副作用があります。もう一方の端までの順序。たとえば、上記のsshの例では、シーケンスは実際に端末に送信されます(ただし、応答は標準入力には表示されません)。
  • 応答を安定して移植可能に読み取ることは困難です。 tty 行規則を一時的に変更し、一度に 1 バイトずつ読み取る必要があります。また、応答が表示されない場合は、放棄して端末がないと判断するタイムアウトを決定する必要があります。人々が衛星接続を介してダイヤルアップすることを考えると、これはタイムアウトが長くなることを意味します。
  • バックグラウンドで端末のデータを読み取ると、SIGTTIN信号を使用してスクリプトが一時停止します。

関連情報