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

결국 자신의 답변처럼 한 번에 한 바이트씩 읽는 것이 가장 안정적입니다. 응답을 보내지 않는 엔드포인트를 설명하기 위해 시간 제한을 추가해야 할 수도 있습니다.

답변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

나는 두 개의 서로 다른 스크립트에서 동일한 코드를 사용하고 있습니다. 하나는 출력용 CSRLIN이고 다른 하나는 출력용입니다 POS.

편집하다:. CSRLIN이 스크립트를 다른 스크립트(예 : 셸이 대화형 모드에 있어야 하기 때문에) 에서 사용하려면 인라인해야 합니다 .

건배

관련 정보