端末から入力を読み取るスクリプトです。 stdoutリダイレクトを使用してスクリプトを呼び出す場合は、ttyとstdoutで印刷するようにスクリプトに指示しますか?

端末から入力を読み取るスクリプトです。 stdoutリダイレクトを使用してスクリプトを呼び出す場合は、ttyとstdoutで印刷するようにスクリプトに指示しますか?

端末にユーザーの入力を必要とするスクリプトがあるため、stdoutをファイルにリダイレクトしてスクリプトを呼び出すと、ユーザーにプロンプ​​トのコンテキストはありません。だから、標準出力を両方のサイトにコピーしたいと思います。

スクリプトは微積分を出力するので、stdoutリダイレクトを許可することはまだ意味があります。

ただし、stdinが提供されている場合(yesコマンドやcronなどの非対話型コンテキストに似ている)、ttyに存在する必要なく出力を許可するのは妥当です。

だから、次のようなロジックを実行したいと思います。

If (test -t 0 && ! test -t 1);
  // Tell stdout to print everything  to tty as well

可能ですか?それとも単に不適切ですか?

答え1

プロンプト文字列に興味がある場合は、通常stderrに移動する必要があります。これは、ほとんどの公益事業会社がヒントを発行したときに行うことです。たとえば、read 'var?promptまたはksh / zsh / yashまたはread -p prompt varを参照してくださいbash

これにより、通常の出力とは別に安全にリダイレクトできます。

stdinがttyにあるがstdoutはそうでない場合は、要求された操作を続けて制御ttyに出力を送信するには、ksh93、zsh、またはbashを含むいくつかのシェルで次のことができます。

if [[ -t 0 && ! -t 1 ]]; then
  exec > >(tee /dev/tty)
fi

ただし、teeバックグラウンドで実行されるため、端末への出力が間違った時間に表示されることがわかります。たとえば、

$ zsh -c 'exec > >(tee /dev/tty); print before; read "var?Prompt: "; print -r "after: $var"' > /dev/null
Prompt: before
what?
after: what?

beforettyに達しました後ろに readプロンプトが発行されました。

したがって、グローバルにこれらのリダイレクトを実行するには、すべてのコマンドに対して実行する必要があります。または、少なくともプロンプトを発行するか、stderrまたは端末に独自に書き込むコマンド間のすべてのコマンドグループに対して実行する必要があります。あるいは、stdout / stderrも各コマンドに対して奇妙な順序で表示されることがあります。 。

#! /bin/zsh -
if [[ -t 0 && ! -t 1 ]]; then
  alias -g '{#}=>&1 > /dev/tty'
else
  alias -g '{#}='
fi
print before {#}
read 'var?prompt: '
print -r after: $var {#}

tee(fdが複数回リダイレクトされる場合は、ここではzshの組み込みツールが使用されます。)

関連情報