標準入力を使用しているときに現在の「stty -g」設定を保存できますか?

標準入力を使用しているときに現在の「stty -g」設定を保存できますか?

消費していますが、それについて文句を言うスクリプトsttyの現在の設定を保存してから復元したいと思います。stdinstty -g

stty: '標準入力': デバイスに不適切な ioctl

stdinファイル記述子を閉じて、オーバーライドされたsttyFDを持つサブシェルを呼び出してみました。stdin私は分離する方法を知らないし、stty -g助けやアドバイスが欲しい。

私は特にPOSIXの互換性に興味があります。 Bash / Zsh-ismsを使用しないでください。

問題を再現するための最小スクリプト:

#!/usr/bin/env sh

# Save this so we can restore it later:
saved_tty_settings=$(stty -g)
printf 'stty settings: "%s"\n' "$saved_tty_settings"

# ...Script contents here that do something with stdin.

# Restore settings later
# (not working because the variable above is empty):
stty "$saved_tty_settings"

print 'foo\nbar\n' | ./sttytestエラーを表示するには実行してください。

答え1

@icarusでコメント:

おそらくsaved_tty_settings=$(stty -g < /dev/tty)

実際には正しい方向を指していましたが、それは物語の終わりではありません。

次の状況では、同じリダイレクトを適用する必要があります。また覆う stty状態も同じだ。それ以外の場合はInvalid argumentioctl エラーが発生します。また覆うステップ...

正しいアプローチ:

saved_tty_settings="$(stty -g < /dev/tty)"

# ...do terminal-changing stuff...

stty "$saved_tty_settings" < /dev/tty

これは私がテストした実際のスクリプトです。プロセス全体をクラシックBourneシェルスクリプトで書き直しました。

#!/bin/sh
# This is sttytest.sh

# This backs up current terminal settings...
STTY_SETTINGS="`stty -g < /dev/tty`"
echo "stty settings: $STTY_SETTINGS"

# This reads from standard input...
while IFS= read LINE
do
    echo "input: $LINE"
done

# This restores terminal settings...
if stty "$STTY_SETTINGS" < /dev/tty
then
    echo "stty settings has been restored sucessfully."
fi

テスト実行:

printf 'This\ntext\nis\nfrom\na\nredirection.\n' | sh sttytest.sh

結果:

stty settings: 2d02:5:4bf:8a3b:3:1c:7f:15:4:0:1:ff:11:13:1a:ff:12:f:17:16:ff:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0
input: This
input: text
input: is
input: from
input: a
input: redirection.
stty settings has been restored sucessfully.

Debian Almquist Shell dash0.5.7およびGNU Coreutils 8.13を使用するstty

関連情報