lessは私のスクリプトを停止します。なぜこれが起こり、それを防ぐ方法は何ですか?

lessは私のスクリプトを停止します。なぜこれが起こり、それを防ぐ方法は何ですか?

s現在のディレクトリには次のBashスクリプトがあります。

#!/bin/bash
pipe_test() {
    ( set -m; (
        $1
    ); set +m ) | 
    (
        $2
    )
}
pipe_test "$1" "$2"

たとえば、私が電話した場合

./s yes less

スクリプトが停止しました。 (lessIEとIEの代わりに試した他のポケットベルを使用してもmore同様のことが起こりますmostfg

set -mサブシェルのプロセスに別のプロセスグループIDが付与されるように、サブシェルにジョブ制御(アクティブ化)があることを望みます。

私のシステムに関する情報:

$ bashbug
...
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -g -O2 -fdebug-prefix-map=/build/bash-cP61jF/bash-5.0=. -fstack-protector-strong -Wformat -Werror=format->
uname output: Linux jarnos-OptiPlex-745 5.4.0-29-generic #33-Ubuntu SMP Wed Apr 29 14:32:27 UTC 2020 x86_64 x86_64 x86_64 GNU>
Machine Type: x86_64-pc-linux-gnu

Bash Version: 5.0
Patch Level: 16
Release Status: release
$ less --version
less version: 551

ベストアンサー1

これが発生するのは、ジョブ制御(set -m)を有効にすると、プロセスのグループ化だけでなく、「フォアグラウンド」および「バックグラウンド」ジョブを処理するためのメカニズムも提供されるためです。この「メカニズム」は、ジョブ制御が有効になると、順番に実行されるすべてのコマンドがフォアグラウンドプロセスグループになることを意味します。

つまり、そのサブシェル(パイプラインの左側)がジョブ制御を有効にすると、実際にその時点まで端末を所有していたパイプライン全体から端末を盗み、プロセスは例に含まれますless。背景になり、端末が使用できなくなります。その後less 、端末に接続し続けるので停止します。

発行によってfgターミナルがパイプライン全体に返されるので、返却時にすべてがless終了します。各追加コマンドは、ジョブ制御サブシェルで実行されない限り、端末を再度盗みます。

この問題を解決する1つの方法は、単にバックグラウンドでジョブ制御サブシェルを実行することです。

( set -m; (
        $1
    ) & set +m ) | 
    (
        $2
    )

必要に応じて異なるプロセスグループで実行されているコマンドを使用し$1、バックグラウンドモードはターミナルを盗み出してターミナルをパイプに残すのを防ぎます$2

もちろん、これ$1を行うには、inコマンドが端末自体を読み取ってはいけません。それ以外の場合は、端末自体を読み取ろうとするとすぐに停止します。

さらに、上記と同様に追加したい他のジョブ制御サブシェルは、追加するまで同じ「バックグラウンド」処理が必要です。set +mそれ以外の場合は、各追加ジョブ制御サブシェルが再生成されます。端末。

つまり、プロセスの終了のみを目的としてプロセスのグループ化が必要な場合は、プロセスのグループ化を使用してそのpkillプロセスをターゲットにすることを検討できます。例えば、pkill -P信号は対応するプロセスに送信される。表示されたPIDです。これにより、お子様のPIDがわかると、お子様のすべてのお子様(お子様は除く)を対象に指定することができます。

おすすめ記事