シェルからコマンドをパイプするプロセスを分岐した人は誰ですか?

シェルからコマンドをパイプするプロセスを分岐した人は誰ですか?

シェルで次のコマンドを検討してください。ls|less

今、私たちはlsそれを知り、less2つの異なるプロセスで実行します。私たちは、シェルが一連の関数のls1つを使用してexec()プログラムをロードするサブプロセスを分岐して生成することを知っています。

私の質問は:誰がコマンドを実行したプロセスを分岐しましたかless?シェルですか、それともコマンドを実行するプロセスですかls

答え1

いくつかの実験:

$ yes | sleep 10m &
[1] 32395 32396
$ pstree -pa $(ps -o ppid= -p $(pgrep yes))
zsh,29630
  ├─pstree,32402 -pa 29630
  ├─sleep,32396 10m
  └─yes,32395

両方のプロセスの親プロセスがシェルであることがわかります。

より長いパイプを使用してください。

$ sleep 10m | sleep 10m | sleep 10m | sleep 10m &
[1] 32320 32321 32322 32323
$ pstree -pa $(ps -o ppid= -p $(pgrep sleep -o)) 
zsh,29630
  ├─pstree,32498 -pa 29630
  ├─sleep,32473 10m
  ├─sleep,32474 10m
  ├─sleep,32475 10m
  └─sleep,32476 10m

実際、これらのプロセスは依然としてシェルの子プロセスです。

サブシェルの使用:

$ sleep 10m | ( sleep 10m | sleep 10m ) | sleep 10m &
[1] 595 596 597
$ pstree -pa $(ps -o ppid= -p $(pgrep sleep -o))     
zsh,29630
  ├─pstree,610 -pa 29630
  ├─sleep,595 10m
  ├─sleep,597 10m
  └─zsh,596
      ├─sleep,598 10m
      └─sleep,599 10m

答え2

これはシェルです。psコマンドが示すように、この場合、PPIDはlessシェルのPIDになります。

これらのプロセスには共通点はあまりありlsませんless。前者の標準出力が後者の標準入力に接続されるだけです。

答え3

使用するシェルによって異なります。

電話してみてください:

yourshell -c 'echo bla | read VAR; echo $VAR'

そして印刷された内容を確認してください。もう一つのチェックは、以下を実行することです。

yourshell -c 'ps -f| more'

別のシェルを使用し、PIDとPPIDを確認してください。

各シェルは独自のアプローチを使用します。

答え4

パイプラインの一部を分岐するシェルで実際に分岐を実行するサブプロセス。それはほぼすべてです。ただし、子プロセスは通常維持されず、通常は呼び出しプロセスに置き換えられます。

sh -c 'echo "$$"
    sh -c "echo \"\$PPID\"" |
    cat'

14546
14546

...しかし、子供だけに与えるなら何もないまだやるべきこと...

sh -c 'echo "$$"
    { sh -c "echo \"\$PPID\""; :; } |
    cat'

14556
14557

…周りに回っています。しかし、実際にこれと一緒に暮らす必要はありません。

sh -c 'echo "$$"
    { exec sh -c "echo \"\$PPID\""; :; } |
    cat'

14563
14563

関連情報