이건 아주 간단해요
#!/bin/bash
echo "What is your name?"
read name
echo "Your name is: $name"
하지만 이름이 아니라 중첩된 태그와 모든 특수 문자가 포함된 큰 HTML 블록을 처리하고 싶다면 어떻게 해야 할까요? (대화형으로 붙여넣을 블록)
터미널 입력을 통해 bash 스크립트를 사용하여 HTML 코드 전체 블록을 변수에 어떻게 저장할 수 있습니까?
답변1
read
read a line을 사용하는 대신 입력에서 직접 읽는 데 사용할 수 있습니다 cat
. 이것은 다음에서 읽을 것입니다표준 입력(일반적으로 프롬프트에 직접 입력하는 경우 터미널) 다음과 같이 작성합니다.표준 출력(또한 터미널). Ctrl/D를 사용하여 입력을 종료합니다.
cat
보다 일반적인 경우, cat
명령은 인수로 나열된 다른 파일에서 읽습니다.표준 입력지정하지 않으면 모든 입력이 다음에 기록됩니다.표준 출력.
이것을 프로그램에 넣고,
#!/bin/bash
echo "What is your name?"
name=$(cat)
printf 'Your name is: "%s"\n' "$name"
이 예에서는 출력이 변수로 전송됩니다 $name
.
답변2
다음과 같은 것을 시도해 볼 수 있습니다.
read -r -d name <<-EOF
코드를 삽입하세요. 원하는 만큼 많은 줄을 붙여넣을 수 있습니다. EOF
bare를 입력하여 줄을 끝냅니다.
답변3
임시 파일 비활성화에 대해 언급하지 않았기 때문에 텍스트 편집기를 사용하는 이상한 해결책이 있습니다.
# Variables
INPUT_TEXT=
TEMP_FILE=temp.html
# Set default editor for the system as nano unless defined
# Hard-code if you can, more consistent usage and users cannot invoke any program they desire through environment variable
EDITOR="${EDITOR:=nano}"
# WARNING: This line here might be a security issue, as it exposes use of a text editor freely, even if you hard-code the editor.
# Get input in a subshell (that's the key part here)
# The &3,&1,&2 redirections are beyond my grasp, but it is said it swaps stdout and stderr. The end goal here is to get TUI interaction with the subshelled command (likely nano in this script).
$( ${EDITOR} $TEMP_FILE 3>&1 1>&2 2>&1 );
# If above subshell ran successfully and user exitted saving the file
if [ $? = 0 ] && [ -f $TEMP_FILE ];
then
INPUT_TEXT=$(cat $TEMP_FILE);
# Remove temporary file, only when actually created
rm $TEMP_FILE;
fi;
echo "$INPUT_TEXT"
한 줄 형식:
EDITOR=${EDITOR:=nano}; INPUT_TEXT=; TEMP_FILE=temp.txt; $($EDITOR $TEMP_FILE 3>&1 1>&2 2>&1); if [ $? = 0 ] && [ -f $TEMP_FILE ]; then INPUT_TEXT=$(cat $TEMP_FILE); rm $TEMP_FILE; fi; echo "$INPUT_TEXT"
편집: HTML로 구체적으로 작업하려는 경우 구문 강조를 사용하여 그에 따라 파일 확장자를 설정할 수 있습니다.
답변4
대신 zsh의 줄 편집기(zle)를 사용 zsh
하고 입력에 개행 문자를 포함할 수 있는 변수 편집기를 bash
사용할 수 있습니다 .vared
#! /bin/zsh -
text=
vared -p 'text: ' text
printf 'Got: <%s>\n' "$text"
텍스트에 리터럴 개행 문자를 입력하려면 + 를 입력 하거나 Alt, Enter+가 환경의 다른 항목에 바인딩된 경우 +를 입력하거나 + 다음에 +를 입력합니다. (+는 개행 문자 또는 문자를 보내고 캐리지 리턴 또는 캐리지 리턴이라고도 보냅니다. ) zsh 쉘 프롬프트에서와 같습니다.EscEnterAltEnterCtrlVCtrlJCtrlJ^J
\n
Enter^M
\r
Enter텍스트를 별도로 제출하세요.
를 bindkey '^M' self-insert-unmeta
호출하기 전에 리터럴 줄 바꿈을 입력하도록 추가 하고 사용자가 +를 사용하여 텍스트를 제출 하도록 할 수 있습니다 (또는 다른 키 또는 키 조합을 여기에 바인딩 ).vared
EnterCtrlJaccept-line
zle 지원 덕분에여러 터미널 에뮬레이터는 괄호로 묶인 붙여넣기 기능을 지원하고 기본적으로 활성화합니다., 거기에 여러 줄의 텍스트를 붙여넣을 수 있어야 합니다. 대괄호 붙여넣기를 활성화할 수 없는 경우 터미널 에뮬레이터는 일반적으로 붙여넣을 때 '를 '로 ^M
변환하므로 위와 같이 리바인딩하면 작동합니다 .\n
\r
보안상의 이유로 터미널 에뮬레이터에서는 많은 제어 문자를 붙여넣는 것을 허용하지 않으며 이를 허용하도록 구성하더라도 일부 제어 문자(예: SIGINT, SIGTSTP ^C
) ^Z
는 tty 장치에서 가로채서 SIGINT, SIGTSTP 신호를 보냅니다. . 그러나 이는 HTML 텍스트에는 문제가 되지 않습니다.
bash
read -e
사용자로부터 텍스트를 읽으려면 해당 줄 편집기를 사용해야 합니다 . bash
줄 편집기( readline
)를 사용하면 Ctrl+ V와 개행 문자를 사용하여 Ctrl텍스트를 입력할 수도 있습니다 J.
따라서 다음과 같이 할 수 있습니다.
IFS= read -e -rd $'\r' -p 'text: ' text
printf 'Got: <%s>\n' "$text"
^M
텍스트에 문자를 삽입하는 것은 허용되지 않습니다 . bash 변수는 NUL 문자를 포함할 수 없기 때문에 -d ''
대신 NUL까지 읽고 +를 사용하여 -d $'\r'
텍스트를 제출할 수 있습니다.CtrlSpaceEnter
readline
대괄호 붙여넣기도 이제 지원되며 최신 버전에서도 기본적으로 활성화됩니다. 이전 버전의 경우 다음을 추가할 수 있습니다.
set enable-bracketed-paste`
대상 ~/.inputrc
또는 추가:
bind 'set enable-bracketed-paste' 2> /dev/null
호출하기 전에 스크립트에 read
.
또는 moreutils'를 사용하여 vipe
텍스트 입력을 위해 사용자가 선호하는 편집기를 실행할 수 있습니다.
text=$(vipe</dev/null)
vipe
가 없으면 zsh
다음을 수행할 수 있습니다.
(){
${VISUAL:-${EDITOR:-vi}} $1
text=$(<$1)
} =()
후행 줄 바꿈을 제거하는 작업에 주의하세요.
미리 설정은 다음 방법을 모두 사용하여 수행할 수 있습니다:
text=seed; vared -p 'text: ' text
IFS= read -e -rd $'\r' -i seed -p 'text: ' text
text=$(echo seed | vipe)
(){
${VISUAL:-${EDITOR:-vi}} $1
text=$(<$1)
} =(echo seed)
또한 read -e
첫 번째 솔루션을 제외한 모든 솔루션은 대화형으로만 작동합니다. echo some text | those-scripts
예를 들어, 당신은 그것을 할 수 없습니다. 그러나 stdin이 터미널에서 나오는지 확인하고 text=$(cat)
그렇지 않은 경우 사용할 수 있는 검사를 추가할 수 있습니다.
if [ -t 0 ]; then
# stdin is a terminal, use any of the solutions above
else
text=$(cat)
fi