だから私は今何時間もこれに触れています。次の質問があります。
stdout
viaに作成されたコマンド(node.jsスクリプト)を実行していますprocess.stdout.write
。インタラクティブなので、ある時点で終了します。
シャットダウン結果が必要なため、子シェルを作成しますが、親シェルでもアクティブにする必要があるため、次のように出力を親シェルにリダイレクトします。
exec 4>&1; res=$(exec 3>&1 1>&4; node test.js)
この注文のアイデアは何ですか?
1>&4
node test.jsの出力がデフォルト(親)シェルに送信されることを確認してください。プロセスの結果をサブシェルに書き込み3>&1
ます$res
。
はい(疑似コード):
//node.js script:
process.stdout.write('write to parent shell because 1>&4')
writeToPipe('/dev/fd/3', 'write the RESULT to subshell so that we can have it in the $res variable')
質問がありますか?
問題は(おそらく私のシェル/ Unix側の誤解によるものです)、単に書きたくないということです。なぜなら/dev/fd/3
他の人も書いているとしたらどうでしょうか?単にオンにして使用するのは/dev/fd/3
良い実装ではないと思います。fd/3
誰かが私のプロセスを複数呼び出してクラッシュした場合はどうなりますか?
私がどのように解決しようとしているのか
私は次のようにできると思います。
tmppipe=$(mktemp -u)
mkfifo "$tmppipe"
毎回固有の名前付きパイプを作成し、競合を避けることができるからです。
問題は、私はそれを動作させることができないということです。 「マイナーな代替」として、最初は次のことを試しました。
exec 4>&1; res=$(exec "$tmppipe">&1 1>&4; node test.js)
しかし、これはうまくいきません。私は名前付きパイプに対してこの構文が機能しないと思いますが、端末に権限の問題があることを知らせて終了します。
答え1
test.js
私は、あなたと何らかの形で対話型の会話を共有するためにパイプとファイル記述子を使用して作業する予定だと思います。
たとえば、標準出力を使用してtest.js
ユーザーに質問をすると、ユーザーは標準入力に応答できます。プログラムは何らかの方法で標準出力に最終出力を提供する必要があるため、コマンド置換test.js
にデータを提供するには、代替の標準出力に接続するファイル記述子3を構成し、最終出力をここに作成する必要があります。記述子の中間test.js
。
これはちょっと恥ずかしいですね。
ツールの最終出力(対話型質問、診断エラーメッセージ、進行状況バーなど)の一部ではない対話型ユーザー会話を処理するために一般的に許可される方法は、標準エラーストリームに出力することです。デフォルトでは、これはこれらのメッセージを端末に直接送信するため(ファイル記述子2へのリダイレクトが設定されていないと仮定して)、コマンドオーバーライドによってキャプチャされたり、パイプなどを介して送信された結果ではありません。
これがシェルや他の多くのツールがどのように機能するかです。シェルは標準エラーをプロンプトします。シェルは標準エラーにステートメント出力(ある種のメニュー)をbash
書き込み、コマンドはselect
標準エラーストリームにread -p 'text'
印刷され、text
ユーザーにプロンプトを表示し、(明らかに)標準エラーにエラーメッセージを出力します。
したがって、コードを次のように単純化できます。
res=$(node test.js)
ここではtest.js
、標準エラーストリームでユーザーと対話し、標準入力ストリームからユーザー入力を読み取り、最後に標準出力ストリームからいくつかの出力を生成します。この出力はres
シェルの変数に保存する必要があります。
シェルでの簡単なデモbash
:
res=$( read -p 'enter something: '; printf 'You entered "%s"\n' "$REPLY" )
printf '"$res" is now "%s"\n' "$res"
res
意志の最終価値いいえenter something:
ユーティリティが標準エラーストリームに書き込む文字列を含みますread
。