쉘 스크립트는 Enter 및 Tab 키를 통해 "읽기"를 허용합니다.

쉘 스크립트는 Enter 및 Tab 키를 통해 "읽기"를 허용합니다.

쉘 스크립트에서 다음과 같은 경우:

read my_variable

Enter입력을 저장하는 키입니다.

기능을 제거하지 않고 Tab동일한 작업을 수행할 수 있는 방법이 있습니까?EnterEnter

답변1

read -e약간 과잉일 수도 있지만 유틸리티에서 Readline 도구를 활성화하는 를 사용하여 얻을 수 있습니다 read. 그 시점에서는 원하는 결과를 얻으려면 키만 누르면 됩니다.

하지만 주의하세요. Readline은 단순성을 위해 완성, 기록 등과 같은 다른 많은 기능도 제공합니다 read my_variable. 이러한 기능이 필요하지 않은 경우 명시적으로 키 바인딩을 지우고 필요하지 않은 기능을 비활성화해야 합니다 read -e.

명령줄의 개념 증명 예:

(bind 'TAB: accept-line'; IFS= read -re var && echo "$var" || echo ko)

bind경고가 표시되기는 하지만 스크립트에서도 이 작업을 수행할 수 있습니다 (리디렉션을 사용하여 경고를 침묵시킬 수 있음 2>/dev/null).

스크립트의 명령에 대한 대안은 bind영향을 미치려는 스크립트를 호출하기 전에 사용자 정의 inputrc 파일을 제공하는 것입니다. 실제 문서는 필요하지 않습니다. 여기 문서이면 충분합니다.

위의 예는 스크립트를 통해 구현됩니다.

#!/bin/bash

export INPUTRC=/dev/fd/3

script2.sh 3<<EOF
TAB: accept-line
set history-size 0
EOF
# this example 'inputrc'-like file also disables history support

위 스크립트는 사용자 정의 inputrc 파일을 파일 설명자 3의 Here Document로 준비하고 실행 중인 셸은 환경 변수의 지시에 따라 파일을 읽습니다 script2.sh.INPUTRC

그 다음에 script2.sh:

#!/bin/bash

echo start
bind -q accept-line 2>/dev/null  # shows which keys are configured to accept input
IFS= read -re var && echo "$var" || echo ko
echo end

입력을 기다리기 전에 read스크립트는 다음과 같이 인쇄합니다.

accept-line can be invoked via "\C-i", "\C-j", "\C-m".

디스플레이 Tab( Ctrl-I예: 위에 표시된 것 \C-i)는 줄 더하기 Return(예: Ctrl-M캐리지 리턴) 또는 줄 바꿈( Ctrl-J)을 허용합니다.

좀 더 "실제"의 예를 들면 다음과 같습니다.

#!/bin/bash

bind 'TAB: accept-line' &>/dev/null

echo "enter your name:"
IFS= read -re var 

echo "your name is: $var"

이 길로 내려가면 꼭 보세요Readline 사용자 가이드, 귀하의 항목 중 하나 이상이 감소되었습니다 man bash. set convert-meta off비ASCII 문자에 대한 더 나은 지원을 위해 해당 설정에 대해 특별히 언급할 가치가 있을 것입니다.

답변2

일반적으로 이를 수행할 수 있는 방법은 // 특수 문자("대체 줄 끝")를 termios(3)Tab으로 설정하는 것입니다. 이를 지원하는 시스템에서는 /도 사용할 수 있습니다.stty(1) VEOLeolVEOL2eol2

안타깝게도 read내장 셸은 항상 개행 문자(또는 bashif 에 -d사용된 다른 구분 기호 , 여러 구분 기호는 지원되지 않음)를 읽으려고 시도합니다.

이 문제를 해결할 수 있는 한 가지 방법은 var=$(dd count=1 bs=big)대신 명령 대체를 사용하는 것입니다 read. 다음은 이에 대한 예입니다.

while :; do

        t=$(stty -g)
        stty eol ^I
        trap : INT
        var=$(dd bs=10k count=1 2>/dev/null; echo x)
        stty "$t"
        trap - INT
        var=${var%x}
        [ "$var" ] || break
        var=${var%[$'\n\t']}

        printf '{%s}\n' "$var"

done

터미널 설정을 저장하고 복원 합니다 t=(stty -g).stty "$t"

Control-C가 쉘/루프(및 그에 따른 모든 합병증 및 쉘 관련 동작)를 종료하는 것을 방지하고 및 명령 대체만 종료하도록 trap : INT합니다 .trap - INTdd

다음은 명령 대체에서 후미 줄 바꿈이 제거되는 것을 방지하는 트릭 $(...; echo x)입니다 . 이는 단순히 빈 변수를 누르 거나 루프를 종료하는 사용자를 구별할 수 있도록 하기 위해 필요합니다 .${var%x}EnterControl-CControl-D

마지막으로 ${var%[$'\n\t']}후행 줄 바꿈이나 탭이 변수에서 제거됩니다. or 와 같은 문자열을 지원하지 않는 쉘에서는 $'...'이를 다음으로 바꿀 수 있습니다.dashyash

nltab='<literal tab here>
'
...
var=${var%[$nltab]}

관련 정보