任意のコマンドを実行し、子プロセスと対話(具体的な詳細は省略)してから、終了するのを待つことができる関数を作成しようとしています。成功すると、入力はrun <command>
まるで裸のように動作します<command>
。
子プロセスと対話しなかった場合は、単に次のように書いたことでしょう。
run() {
"$@"
}
ただし、実行中に対話する必要があるため、coproc
およびを使用してより複雑な設定を使用しますwait
。
run() {
exec {in}<&0 {out}>&1 {err}>&2
{ coproc "$@" 0<&$in 1>&$out 2>&$err; } 2>/dev/null
exec {in}<&- {out}>&- {err}>&-
# while child running:
# status/signal/exchange data with child process
wait
}
(これは単純化されています。すべてのcoproc
リダイレクトが実際に役に立つ作業を実行するわけではありませんが、"$@" &
実際のプログラムではリダイレクトが必要です。)
コマンドは"$@"
何でも構いません。私の機能は、run ls
などrun make
で動作しますがrun vim
。 Vimがバックグラウンドプロセスであり、端末アクセス権がないことを検出して編集ウィンドウを表示するのではなく、それ自体が停止するため、失敗したようです。 Vimが正しく動作するように修正したいと思います。
coproc "$@"
親シェルが「バックグラウンド」になっている間に「フォアグラウンド」で実行されるようにするにはどうすればよいですか?「子供との対話」部分は端末で読み書きすることはないので、フォアグラウンドで実行する必要はありません。 ttyの制御権をコルーチンに渡してくれて嬉しいです。
run()
私がやっていることでは、親プロセスと"$@"
子プロセスにあることが重要です。私はこの役割を変えることはできません。しかし、私はできる前景と背景を変更します。 (ただ何をすべきかわからない。)
私はVim固有のソリューションを探しているわけではありません。私はpseudo-ttyを避けることを好みます。私の理想的な解決策は、stdinとstdoutがtty、パイプに接続されている、またはファイルからリダイレクトされたときに同じようにうまく機能します。
run echo foo # should print "foo"
echo foo | run sed 's/foo/bar/' | cat # should print "bar"
run vim # should open vim normally
なぜコプロセスを使用するのですか?
私はcoprocなしでこの問題を書くことができます。
run() { "$@" & wait; }
私はちょうど同じ行動を使用しました&
。しかし、私のユースケースではFIFO coproc設定を使用していますcmd &
。coproc cmd
なぜptysを避けるべきですか?
run()
自動化された環境で使用できます。パイプやリダイレクトに使用されている場合はエミュレートする端末がなく、ptyを設定するとエラーが発生します。
期待を使わないのはなぜですか?
私はvimを自動化したり、vimに入力を送信したり、そのようなものを送信したくありません。
ベストアンサー1
次のようにコードを追加しました。
interact() {
pid=$1
! ps -p $pid && return
ls -ld /proc/$pid/fd/*
sleep 5; kill -1 $pid # TEST SIGNAL TO PARENT
}
run() {
exec {in}<&0 {out}>&1 {err}>&2
{ coproc "$@" 0<&$in 1>&$out 2>&$err; } 2>/dev/null
exec {in}<&- {out}>&- {err}>&-
{ interact $! <&- >/tmp/whatever.log 2>&1& } 2>/dev/null
fg %1 >/dev/null 2>&1
wait 2>/dev/null
}
fg %1
すべてのコマンドに対して実行され(%1
同時操作に必要に応じて変更)、一般的な状況では、次の2つのいずれかが発生します。
interact()
何fg
もしないため、すぐに返されます。interact()
(たとえば、5秒後にHUPをセカンダリプロセスに送信します)、セカンダリfg
プロセスは元々実行されたのと同じstdin / out / errを使用してフォアグラウンドにインポートされます(確認できます)。この金額ls -l /proc/<pid>/df
)。
最後の3つのコマンドでは、/ dev / nullへのリダイレクトは外観的です。run <command>
個別に実行するときとまったく同じように見えます。command