このコマンドについて学びました:
echo -e "\a"
はローカル システムでビープ音を鳴らしますが、次のコマンドでは、
echo -e "\a" >/dev/console
リモート システムでビープ音を鳴らします。
これはなぜでしょうか? この>/dev/console
部分は何をしているのでしょうか?
echo -e "\a"
リモート マシンで実行すると、リモートではなくローカルでビープ音が鳴るのはなぜですか?
「echo」コマンドが sudo と相性が悪いのはなぜですか?
OSI レイヤーのようなスキームはありますか? 外部ドキュメントを提供してください。
私はstdout/stderrをファイルにリダイレクトすることについて基本的な知識しかありませんが、質問はおそらく「Gnu/Linux/カーネル」がリダイレクトを要求するようにどのように設計されているかに関するものでしょう。
リモートビープ音が機能するには、「 > /dev/console」を参照してください。
リモートではecho "Hello World"
/dev/console へのリダイレクトが必要ですか?
答え1
echo
出力を stdout に書き込みます。これがファイル記述子 1 です。
を使用するとecho -e '\a'
、実装に応じてecho
、BEL 文字 (ASCII では 0x7 バイト値) の後に LF (改行文字とも呼ばれます) が書き込まれるか、-e \a
LF が書き込まれるか、または-e
BEL と LF が書き込まれます。
BEL 文字のみを記述する場合は、 と記述しますprintf '\a'
。
いずれにせよ、この質問の核心にはあまり違いはありません。printf
、のように、echo
書き込む必要があるものを標準出力に書き込みます。
リダイレクトなしで対話型シェルのプロンプトでそのコマンドを入力すると、stdout はシェルから継承されます。シェルが または のような端末エミュレータによって起動された場合xterm
、ファイル記述子 1 はデバイス ファイル上で ( によって)screen
開かれます( Linux ではまたはを参照)。これが擬似端末ペアのスレーブ側になります。xterm
/dev/pt<something>
lsof -ad1 -p "$$"
readlink -f /proc/self/fd/1
ここで知っておくべき唯一の重要なことは、それが何らかの通信チャネルであるということです。パイプに少し似ていますが、ユーザーとのやり取りに役立ついくつかの追加機能があります。
が BEL をそのデバイス ファイルに書き込むとprintf
、その BEL は反対側の何かに送信されます。この場合xterm
、それはターミナル エミュレーター自体です。BEL 文字は、ターミナルとターミナル エミュレーターが何らかの方法でユーザーに警告する制御文字です (\a
は警告の略)。警告は、ビープ音、チャイム、または画面の視覚的な点滅、またはその両方です。xterm
通常は、XBell()
X11 API 呼び出しを使用してこれを行うか、視覚的なベルを使用するように構成されている場合はウィンドウを点滅させます。screen
自体は、BEL を単に転送します。ホスト接続されている端末とその画面ウィンドウがアクティブになっている端末を指定するか、端末に閃光設定方法に応じて、制御シーケンスまたは「Wuff, Wuff!!」(sic) メッセージが表示されます (を参照info screen vbell
)。
getty
グラフィック セッション外で Linux を実行している PC にログインすると、fd 1 が ( によって) デバイスに開かれます/dev/tty<1-...>
。ここで、端末エミュレータを実装し、出力にモニターを使用し、入力にキーボードを使用するのはカーネルです。同じ原理で、 がprintf
そこに BEL を書き込むと、カーネルは PC スピーカーのビープ音を鳴らします。
上の対話型シェルのプロンプトでそのコマンドを実行するとssh
、fd 1 も擬似端末デバイス ( ) になります。/dev/pt<something>
今回は、リモート システムでリモート ユーザーのログイン シェルを開始した ssh サーバーによって開始されます。擬似端末ペアのもう一方の端には ssh サーバーがあります。その BEL (または他の重要なもの) を受信すると、ssh サーバーはそれを暗号化された接続を介して ssh クライアントに送信し、ssh クライアントはそれを stdout に書き込みます。これは最終的に、現在使用している端末ウィンドウに表示されます。
で
printf '\a' > /dev/console
シェルは、/dev/console
実行する前にファイル記述子 1 (stdout) 上のファイルを開きますprintf
。
現在/dev/console
、少なくとも Linux では、 はシステム メッセージを受信するための tty デバイス ファイルです。/dev/console
は通常、別の tty デバイスにリダイレクトします。 PC では、デフォルトでは であり、これは/dev/tty0
現在アクティブな仮想端末を指しますが、これはブート時にconsole=/dev/anything
カーネル パラメータを使用して変更できます (たとえば、console=/dev/ttyS0
最初のシリアル デバイスにするなど)。また、 を使用すると、後で (出力部分については) 変更することもできます ( をTIOCCONS
ioctl()
参照xterm -C
)。
いずれにせよ、それは通常マシン自体に接続されている端末になります。したがって、そこに BEL を出力することは、そのマシンがシステム メッセージをユーザーに送信するために使用するチャネルを使用していることをそのマシンの管理者に警告することを目的としています。
ログインしているすべてのユーザーにメッセージを書き込むには、アプリケーションを使用するwall
か、write
ユーザーが通知を無効にしていない限り、1人のユーザー(1つの端末デバイス)にのみアプリケーションを使用することもできます(mesg n
)