Bashで実行されたプログラムの出力を取得するには?

Bashで実行されたプログラムの出力を取得するには?

プログラムを実行するとき吹く、たとえば、次の[ls][2]出力を送信します。標準出力fd &1)。そして実行されたプログラムの出力が端末に表示されます。 Bash / terminallsでコマンドの出力を取得するには?

答え1

シェルの子プロセスとして、lsシェルのオープンファイル記述子を継承します。標準ファイル記述子(stdin、stdout、stderr(または0、1、2))は擬似端末に接続され、端末エミュレータによって処理されます。

たとえば(Linuxシステムの場合):

$ ls /proc/$$/fd -l
total 0
lrwx------ 1 muru muru 64 Dec 10 16:15 0 -> /dev/pts/3
lrwx------ 1 muru muru 64 Dec 10 16:15 1 -> /dev/pts/3
lrwx------ 1 muru muru 64 Dec 10 16:15 2 -> /dev/pts/3
lrwx------ 1 muru muru 64 Dec 10 16:15 255 -> /dev/pts/3
$ ls /proc/$(pgrep terminator -f)/fd -l | grep pts/3
lrwx------ 1 muru muru 64 Dec 10 16:15 26 -> /dev/pts/3

つまり、 の出力lsまたはシェル自体はシェルで処理されず、端末エミュレータ (GNOME 端末、ターミネータ、xterm など) で処理されます。


これをテストできます。

ptsLinuxでは、GNOME端末などの端末エミュレータで使用される擬似端末()を見つけます。

$ ls -l /proc/$(pgrep -n gnome-terminal)/fd | grep pts
lrwx------ 1 muru muru 64 Dec 10 18:00 1 -> /dev/pts/1
lrwx------ 1 muru muru 64 Dec 10 18:00 15 -> /dev/pts/20
lrwx------ 1 muru muru 64 Dec 10 18:00 2 -> /dev/pts/1

これで、非標準fd(0、1、2以外のfd)を使用してgnome-terminalシェルに入出力を提供します。端末エミュレータは、このPTSに送信されたデータを読み取り、画面に表示します(色など一部の処理)。この場合は15に接続してくださいpts/20。これまで何かを書くと、この端末に表示されると予想できます。

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

追加資料:


別の場合に私がすることは次のとおりです。

echo $(ls)
a=$(date)
vim `command -v some_script`

~と呼ばれるコマンドの置き換え。コマンドの置き換えでは、コマンドの出力はシェル自体によってキャプチャされ、印刷しない限り(たとえばecho $(ls))端末に到達しません。イベントは以下で処理されました。ホクラキンの答え

答え2

私は質問を命令置換の意味で誤解したことがわかりました。この場合にのみ、シェルは出力処理に参加します。

これも興味を引き起こすことができることを願っています...

strace -p 2140このllを実行する前にecho $(/bin/echo foo)シェルに接続してください。これは結果の一部です。

pipe([3, 4])
pipe([5, 6])
...
read(3, "foo\n", 128)

子プロセスでは、次のことが発生します。

dup2(4, 1)
close(4)
close(3)
...
execve("/bin/echo", ...

シェルはファイル記述子 3 と 4 を連結して分岐します。子プロセスは、stdout新しいプログラムを実行する前にfdを4に設定します。したがって、子プロセスによって作成されたすべての内容は、stdoutfd 3の親シェルから読み取ることができます。

関連情報