구분 기호 문자를 어떻게 인쇄하고 사용자가 표준 입력을 읽는 동안 줄을 편집할 수 있도록 하려면 어떻게 해야 합니까?

구분 기호 문자를 어떻게 인쇄하고 사용자가 표준 입력을 읽는 동안 줄을 편집할 수 있도록 하려면 어떻게 해야 합니까?

표준 입력에서 읽는 간단한 스크립트를 작성하려고 합니다. ; 문자를 구분 기호로 사용하여 입력 줄을 종료하고 사용자가 줄을 편집할 수 있도록 합니다.

내 테스트 스크립트는 다음과 같습니다.

#!/bin/bash

while true; do

  read -e -d ";" -t 180 -p "><> " srcCommand

  if [ $? != 0 ]; then
    echo "end;"
    echo ""
    exit 0
  fi
  case "$srcCommand" in
    startApp)
       echo "startApp command";;
    stopApp)
       echo "stopApp command";;
    end)
       echo ""
       exit 0
       ;;
    *)
       echo "unknown command";;
  esac
done

이것은 작동하지만 구분 기호 ';'를 인쇄하지 않습니다. 숯:

# bash test.sh
><> startApp
startApp command
><> stopApp
stopApp command
><> end

-e 옵션을 제거하면 인쇄되지만 ; 사용자는 백스페이스 문자를 사용하여 실수를 수정할 수 없으며 에코된 문자열은 구분 기호 바로 뒤에 있습니다.

# bash test.sh
><> startApp;startApp command
><> stopApp;stopApp command
><> end;

구분 기호 문자를 어떻게 인쇄하고 사용자가 표준 입력을 읽는 동안 줄을 편집할 수 있도록 하려면 어떻게 해야 합니까?

예상되는 동작은 다음과 같습니다.

# bash test.sh
><> startApp;
startApp command
><> stopApp;
stopApp command
><> end;

감사해요

답변1

저는 zsh라인 편집기에 더 많은 기능이 있고 훨씬 더 사용자 정의가 가능한 곳을 사용하겠습니다.

#! /bin/zsh -
insert-and-accept() {
  zle self-insert
  # RBUFFER= # to discard everything on the right
  zle accept-line
}
zle -N insert-and-accept
bindkey ";" insert-and-accept
bindkey "^M" self-insert
vared -p "><> " -c srcCommand

이상을 사용하면 bash-4.3다음과 같은 해킹으로 비슷한 작업을 수행할 수 있습니다.

# bind ; to ^Z^C (^Z, ^C otherwide bypass the key binding when entered
# on the keyboard). Redirect stderr to /dev/null to discard the
# useless warning
bind '";":"\32\3"' 2> /dev/null

# new widget that inserts ";" at the end of the buffer.
# If we did bind '";":";\3"', readline would loop indefinitely
add_semicolon() {
  READLINE_LINE+=";"
  ((READLINE_POINT++))
}
# which we bind to ^Z
bind -x '"\32":add_semicolon' 2> /dev/null

# read until the ^C
read -e -d $'\3' -t 180 -p '><> ' srcCommand

해당 버전에서는 ;항상 현재 커서 위치가 아닌 입력 버퍼의 끝에 삽입됩니다. 다음으로 변경 add_semicolon:

add_semicolon() {
  READLINE_LINE="${READLINE_LINE:0:READLINE_POINT++};"
}

커서에 삽입하고 오른쪽에 있는 모든 항목을 삭제하려면 또는:

add_semicolon() {
  READLINE_LINE="${READLINE_LINE:0:READLINE_POINT};${READLINE_LINE:READLINE_POINT}"
  READLINE_POINT=${#READLINE_LINE}
}

커서에 삽입하고 싶지만 접근 방식과 같이 오른쪽에 있는 내용을 유지하려는 경우 zsh.

;in 을 원하지 않는 경우 예를 $srcCommand들어 나중에 언제든지 제거할 수 있지만 / srcCommand="${srcComman//;}"로 표시되도록 하려면 위젯에 삽입해야 합니다 .zlereadline

관련 정보