shスクリプトで「\ 033 [6n」の結果を取得する方法

shスクリプトで「\ 033 [6n」の結果を取得する方法

私はどんなシェルでも動作する結果を得るためにウェブを検索し、技術をテストするのに10時間を費やしました(#!/bin/sh)。

readBASHでは、キャッチする文字数を知り、区切り文字が見つかるとすぐに終了するので、比較的簡単です。

stty -icanon -echo; echo -en "\033[6n"; read -d R -n 12 ESCPOS; stty "$x_TERM"; \
ESCPOS=`echo "$ESCPOS" | tail -c +3`; echo "$ESCPOS"

すべてのシェルと互換性のあるshスクリプトバージョンを作成するには?

答え1

コピーした場所https://unix.stackexchange.com/a/88327

/bin/shPOSIXを使用しているとしますsh(Bourneシェルを使用できるSolaris 10以前では、代わりにそれを使用してください/usr/xpg4/bin/sh)。

if [ -t 0 ] && [ -t 1 ]; then
  old_settings=$(stty -g) || exit
  stty -icanon -echo min 0 time 3 || exit
  printf '\033[6n'
  pos=$(dd count=1 2> /dev/null)
  pos=${pos%R*}
  pos=${pos##*\[}
  x=${pos##*;} y=${pos%%;*}
  stty "$old_settings"
fi

全体の応答が一度に最大0.3秒待機すると仮定します。これは一般的にターミナルエミュレータとptyデバイスに適用されますが、シリアルターミナルには必ずしもそうではありません。 8バイトを読むまで待つように(各バイト間最大0.3秒)変更できますが、min 8 time 3答えが8バイトより短い場合は常に最小0.3秒かかり、答えがない場合は常に0.3秒かかるという欠点があります。 。

awk -F'[^0-9]+' -v RS=R '{print $3, $2; exit}'で使用できますmin 1 time 0。これは、他の実装(入力処理を開始する前に入力データでいっぱいのバッファを蓄積する必要がある)awkと組み合わせて使用​​できます。mawk

結局、自分の答えのように、一度に1バイトずつ読み込むのが最も安定しています。応答を送信しないエンドポイントを説明するためにタイムアウトを追加する必要があるかもしれません。

答え2

メモ:

unlike the wrongly copied and continually upvoted answer provided
(points scoring?), the following script IS NON-BLOCKING, and does
not care what length returned input may be.  IE it will work with 
ANY screen size.

SHの使用はより複雑で、組み込みの拡張コマンドラインバージョンが見つかりませんでした。read結局、STDINへの言及が見つかり、dd結果は次のとおりです。内蔵SHバージョンは使用できますが、echo許可されていません。echo -en/bin/echo -enprintf

#!/bin/sh
x_TERM=`stty -g`
stty -icanon -echo
printf "\033[6n"
ESCPOS=""
X=""
I=0
while [ ! "$X" = "R" ]; do
  X=`dd bs=1 count=1 2>/dev/null`
  I=`expr $I + 1`
  if [ $I -gt 2 -a ! "$X" = "R" ]; then
    ESCPOS="$ESCPOS$X"
  fi
done
stty "$x_TERM"
#echo "$ESCPOS"
CSRLIN=`echo "$ESCPOS" | cut -d \; -s -f 1`
POS=`echo "$ESCPOS" | cut -d \; -s -f 2`
echo "$CSRLIN"
#exit 0 <= dont use inline

私は2つの異なるスクリプトで同じコードを使用しています。 1つは出力用CSRLINで、もう1つは出力用ですPOS

編集する:. CSRLINこのスクリプトを他のスクリプト(たとえば、シェルがインタラクティブモードにする必要があるため)で使用するには、インライン化する必要があります。

乾杯

ポール

関連情報