development

stdin의 다중 입력을 변수로 읽는 방법과 쉘 (sh, bash)에서 출력하는 방법은 무엇입니까?

big-blog 2021. 1. 6. 20:45
반응형

stdin의 다중 입력을 변수로 읽는 방법과 쉘 (sh, bash)에서 출력하는 방법은 무엇입니까?


내가 원하는 것은 다음과 같습니다.

  1. 여러 줄 입력에서 stdin변수로 읽기A
  2. 다양한 작업을하다 A
  3. 파이프 A(구분 기호를 잃지 않고 \n, \r, \t다른 명령 등)

현재 문제는 read개행에서 읽기를 중지하기 때문에 명령으로 읽을 수 없다는 것입니다 .

다음과 cat같이 stdin을 읽을 수 있습니다 .

my_var=`cat /dev/stdin`

,하지만 인쇄 방법을 모르겠습니다. 줄 바꿈, 탭 및 기타 구분 기호는 그대로 있습니다.

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

#!/usr/local/bin/bash

A=`cat /dev/stdin`

if [ ${#A} -eq 0 ]; then
        exit 0
else
        cat ${A} | /usr/local/sbin/nextcommand
fi

이것은 나를 위해 일하고 있습니다.

myvar=`cat`

echo "$myvar"

주위의 따옴표 $myvar가 중요합니다.


Bash에는 다른 방법이 있습니다. man bash언급 :

명령 대체 $(cat file)는 동등하지만 더 빠른 것으로 대체 될 수 있습니다 $(< file).

$ myVar=$(</dev/stdin)
hello
this is test
$ echo "$myVar"
hello
this is test

는 일을한다

#!/bin/bash
myVar=$(tee)

예, 저에게도 효과적입니다. 감사.

myvar=`cat`

와 같다

myvar=`cat /dev/stdin`

그래. 로부터 bash매뉴얼 페이지

큰 따옴표로 묶는 문자는 $,`, \ 및 히스토리 확장이 활성화 된 경우!를 제외하고 따옴표 안에있는 모든 문자의 리터럴 값을 유지합니다. $ 및`문자는 큰 따옴표 안에 특별한 의미를 유지합니다.


출력 끝에서 후행 줄 바꿈을 유지하는 데 관심이 있다면 다음을 사용하십시오.

myVar=$(cat; echo x)
myVar=${myVar%x}
printf %s "$myVar"

여기 에서 트릭을 사용합니다 .


[업데이트 됨]

파이프에 아무것도 없으면이 할당은 무기한 중단됩니다 ...

var="$(< /dev/stdin)"

We can prevent this though by doing a timeout read for the first character. If it times out, the return code will be greater than 128 and we'll know the STDIN pipe (a.k.a /dev/stdin) is empty.

Otherwise, we get the rest of STDIN by...

  • setting IFS to NULL for just the read command
  • turning off escapes with -r
  • eliminating read's delimiter with -d ''.
  • and finally, appending that to the character we got initially

Thus...

__=""
_stdin=""

read -N1 -t1 __  && {
  (( $? <= 128 ))  && {
    IFS= read -rd '' _stdin
    _stdin="$__$_stdin"
  }
}

This technique avoids using var="$(command ...)" Command Substitution which, by design, will always strip off any trailing newlines.

If Command Substitution is preferred, to preserve trailing newlines we can append one or more delimiter characters to the output inside the $() and then strip them off outside.

For example ( note $(parens) in first command and ${braces} in second )...

_stdin="$(awk '{print}; END {print "|||"}' /dev/stdin)"
_stdin="${_stdin%|||}"

ReferenceURL : https://stackoverflow.com/questions/212965/how-to-read-mutliline-input-from-stdin-into-variable-and-how-to-print-one-out-in

반응형