여러 줄 출력을 Bash 변수로 캡처
다음을 출력하는 스크립트 'myscript'가 있습니다.
abc
def
ghi
다른 스크립트에서는, 다음과 같이 전화합니다.
declare RESULT=$(./myscript)
★★★★★★★★★★★★★★★★★」$RESULT
를 얻다
abc def ghi
로 저장하여 '\n'자로할 수 요?echo -e
실제로 결과에는 다음과 같은 내용이 포함되어 있습니다.
echo "$RESULT"
표시되는 내용은 다음과 같습니다.
echo $RESULT
되어 있듯이그는 (1) 버전( 「」 「」 「」, 「」(1) 「」 「」입니다.echo "$RESULT"
는 변수에 간격(탭, 등)을 (2) 가 없는 버전()은 따옴표가 없는 버전 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」(2개)echo $RESULT
탭 및의 각 는 하나 이상의 공백, 탭 및 줄바꿈의 각 시퀀스를 1개의 공백으로 바꿉니다.따라서 (1) 입력 변수의 모양을 유지하는 반면 (2)는 단일 공백으로 구분된 'words'로 잠재적으로 매우 긴 단일 출력 행을 생성합니다(여기서 'word'는 공백이 아닌 문자의 시퀀스입니다. 어떤 단어에도 영숫자가 있을 필요는 없습니다).
또 하나의 함정은 명령어 대체입니다.$()
: 후행의 줄바꿈을 삭제합니다.항상 중요한 것은 아니지만 출력된 내용을 그대로 유지하려면 다른 행과 인용문을 사용해야 합니다.
RESULTX="$(./myscript; echo x)"
RESULT="${RESULTX%x}"
이는 가능한 모든 파일 이름을 처리하는 경우(잘못된 파일에서 작업하는 것과 같은 정의되지 않은 동작을 방지하기 위해) 특히 중요합니다.
특정 행에 관심이 있는 경우 result-array를 사용합니다.
declare RESULT=($(./myscript)) # (..) = array
echo "First line: ${RESULT[0]}"
echo "Second line: ${RESULT[1]}"
echo "N-th line: ${RESULT[N]}"
@l0b0의 답변에 더해 스크립트에 의해 출력되는 후행 뉴라인을 유지하고 스크립트의 리턴 코드를 확인해야 하는 상황이 있었습니다.그리고 l0b0의 답변의 문제는 '에코 x'가 $?를 0으로 재설정하고 있었다는 것이다.그래서 저는 아주 교활한 해결책을 생각해냈습니다.
RESULTX="$(./myscript; echo x$?)"
RETURNCODE=${RESULTX##*x}
RESULT="${RESULTX%x*}"
다중 출력 구문 분석
서론
당신의 ★★★★★★★★★★★★★★★★★★★.myscript
3번, 3번, 3번, 3번, 3번.
myscript() { echo $'abc\ndef\nghi'; }
또는
myscript() { local i; for i in abc def ghi ;do echo $i; done ;}
OK는 )../
아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아.
myscript
abc
def
ghi
결과코드참조
결과 코드를 확인하기 위해 테스트 기능은 다음과 같습니다.
myscript() { local i;for i in abc def ghi ;do echo $i;done;return $((RANDOM%128));}
1. 여러 출력을 하나의 변수에 저장하여 새로운 라인을 표시하다
조작이 올바릅니다.
RESULT=$(myscript)
결과 코드에 대해 다음을 추가할 수 있습니다.
RCODE=$?
같은 행이라도:
RESULT=$(myscript) RCODE=$?
그리고나서
echo $RESULT $RCODE
abc def ghi 66
echo "$RESULT"
abc
def
ghi
echo ${RESULT@Q}
$'abc\ndef\nghi'
printf '%q\n' "$RESULT"
$'abc\ndef\nghi'
그러나 변수 정의를 표시하려면declare -p
:
declare -p RESULT RCODE
declare -- RESULT="abc
def
ghi"
declare -- RCODE="66"
2. 어레이 내의 여러 출력 해석, 사용mapfile
답변 저장처myvar
변수:
mapfile -t myvar < <(myscript)
echo ${myvar[2]}
ghi
표시하다$myvar
:
declare -p myvar
declare -a myvar=([0]="abc" [1]="def" [2]="ghi")
결과코드참조
결과 코드를 확인해야 하는 경우 다음을 수행할 수 있습니다.
RESULT=$(myscript) RCODE=$?
mapfile -t myvar <<<"$RESULT"
declare -p myvar RCODE
declare -a myvar=([0]="abc" [1]="def" [2]="ghi")
declare -- RCODE="40"
3. 복수 출력의 연속 해석read
명령어 그룹 내
{ read firstline; read secondline; read thirdline;} < <(myscript)
echo $secondline
def
변수 표시:
declare -p firstline secondline thirdline
declare -- firstline="abc"
declare -- secondline="def"
declare -- thirdline="ghi"
자주 사용하는 항목:
{ read foo;read foo total use free foo ;} < <(df -k /)
그리고나서
declare -p use free total
declare -- use="843476"
declare -- free="582128"
declare -- total="1515376"
결과코드참조
동일한 선행 절차:
RESULT=$(myscript) RCODE=$?
{ read firstline; read secondline; read thirdline;} <<<"$RESULT"
declare -p firstline secondline thirdline RCODE
declare -- firstline="abc"
declare -- secondline="def"
declare -- thirdline="ghi"
declare -- RCODE="50"
여기서 대부분의 솔루션을 사용해 본 결과, 가장 쉬운 것은 temp 파일을 사용하는 것입니다.여러 줄 출력으로 무엇을 하고 싶은지 잘 모르겠지만, 읽기를 사용하여 한 줄씩 처리할 수 있습니다.실제로 할 수 없는 유일한 것은 모든 것을 같은 변수에 쉽게 고정시키는 것이지만, 대부분의 실용적인 목적을 위해서는 이 모든 것을 훨씬 쉽게 처리할 수 있습니다.
./myscript.sh > /tmp/foo
while read line ; do
echo 'whatever you want to do with $line'
done < /tmp/foo
빠른 해킹을 통해 요청된 작업을 수행할 수 있습니다.
result=""
./myscript.sh > /tmp/foo
while read line ; do
result="$result$line\n"
done < /tmp/foo
echo -e $result
이렇게 하면 행이 추가됩니다.네가 작업하면 코드도 쓸 수 있어, 난 그냥 너무 게을러.
편집: 이 케이스는 완벽하게 동작하지만, 이 케이스를 읽는 사람들은 당신이 당신의 stdin을 while loop 안에 쉽게 찌그러뜨릴 수 있다는 것을 알아야 합니다.그러면 당신은 당신에게 한 줄을 실행하고 stdin을 클리어하고 종료하는 스크립트를 줄 수 있습니다.내 생각엔 ssh가 그렇게 할 것 같아?최근에 확인했습니다.다른 코드 예는 https://unix.stackexchange.com/questions/24260/reading-lines-from-a-file-with-bash-for-vs-while 입니다.
한 번 더!이번에는 다른 파일 핸들(stdin, stdout, stderr이 0-2이므로 bash에서 &3 이상을 사용할 수 있습니다).
result=""
./test>/tmp/foo
while read line <&3; do
result="$result$line\n"
done 3</tmp/foo
echo -e $result
mktemp도 사용할 수 있지만 이것은 간단한 코드 예시입니다.mktemp의 사용법은 다음과 같습니다.
filenamevar=`mktemp /tmp/tempXXXXXX`
./test > $filenamevar
그런 다음 파일의 실제 이름과 마찬가지로 $filenamevar를 사용합니다.아마 여기에 설명이 필요없을 텐데 댓글에 어떤 분이 불평을 하시네요.
이것은 어떻습니까? 각 행을 변수에 읽어들이고 나중에 사용할 수 있습니다! myscript 출력은 myscript_output이라는 파일로 리다이렉트 됩니다.
awk '{while ( (getline var < "myscript_output") >0){print var;} close ("myscript_output");}'
언급URL : https://stackoverflow.com/questions/613572/capturing-multiple-line-output-into-a-bash-variable
'programing' 카테고리의 다른 글
WPF 데이터 그리드에서 그리드선 색상 지정 (0) | 2023.05.28 |
---|---|
여러 명령어의 Bash 종료 상태를 효율적으로 확인 (0) | 2023.04.08 |
'source'와 함께 도커 파일에서 RUN 명령을 사용하면 작동하지 않습니다. (0) | 2023.04.08 |
공백이 있는 파일 목록에서 반복 (0) | 2023.04.08 |
"Windows Defender SmartScreen으로 인해 인식할 수 없는 앱이 시작되지 않았습니다"를 방지하는 방법 (0) | 2023.04.08 |