[bash] 여러 줄 출력을 Bash 변수로 캡처
다음을 출력하는 스크립트 ‘myscript’가 있습니다.
abc
def
ghi
다른 스크립트에서는 다음과 같이 호출합니다.
declare RESULT=$(./myscript)
그리고 $RESULT
가치를 얻는다
abc def ghi
줄 바꿈 또는 ‘\ n’문자로 결과를 저장하여 ‘ echo -e
‘로 출력 할 수있는 방법이 있습니까?
답변
실제로 RESULT에는 다음과 같은 내용이 포함되어 있습니다.
echo "$RESULT"
당신이 보여주는 것은 당신이 얻는 것입니다 :
echo $RESULT
의견에서 언급했듯이, 차이점은 (1) 큰 따옴표로 묶인 변수 버전 ( echo "$RESULT"
) 은 변수 (줄 바꿈, 탭, 여러 공백 및 모두)에 표시된대로 값의 내부 간격을 유지하지만 (2) ) 따옴표없는 버전 ( echo $RESULT
)은 하나 이상의 공백, 탭 및 개행의 각 시퀀스를 단일 공백으로 바꿉니다. 따라서 (1) 입력 변수의 모양을 유지하는 반면 (2) 단일 단어로 구분 된 ‘단어’를 사용하여 잠재적으로 매우 긴 단일 출력 행을 만듭니다 ( ‘단어’는 공백 문자가 아닌 일련의 문자입니다. 어떤 단어에서도 영숫자가 될 수 없습니다).
답변
이것의 또 다른 함정은 명령 대체 — $()
— 마지막 줄 바꿈을 제거 한다는 것 입니다. 당신이 정말로 유지하려면 아마 항상 중요하지만 정확하게 출력 무엇인지, 다른 라인과 일부 인용을 사용해야합니다 :
RESULTX="$(./myscript; echo x)"
RESULT="${RESULTX%x}"
파일 이름 을 잘못 처리 하는 등 정의되지 않은 동작을 피하기 위해 가능한 모든 파일 이름 을 처리 하려는 경우 특히 중요합니다 .
답변
특정 행에 관심이있는 경우 결과 배열을 사용하십시오.
declare RESULT=($(./myscript)) # (..) = array
echo "First line: ${RESULT[0]}"
echo "Second line: ${RESULT[1]}"
echo "N-th line: ${RESULT[N]}"
답변
에 의해 주어진 대답에 추가 @ l0b0 나는 단지 내가 모두 필요한 상황이 스크립트에 의해 후행 뉴 라인 출력을 유지했다 및 스크립트의 리턴 코드를 확인하십시오. 그리고 l0b0의 대답의 문제는 ‘echo x’가 $를 재설정하고 있다는 것입니다. 다시 제로로 돌아가서 …이 교활한 해결책을 생각해 냈습니다.
RESULTX="$(./myscript; echo x$?)"
RETURNCODE=${RESULTX##*x}
RESULT="${RESULTX%x*}"
답변
여기에서 대부분의 솔루션을 시도한 후에 가장 쉬운 것은 임시 파일을 사용하는 것이 분명했습니다. 여러 줄 출력으로 무엇을하고 싶은지 잘 모르겠지만 read를 사용하여 한 줄씩 처리 할 수 있습니다. 실제로 할 수없는 유일한 일은 동일한 변수에 쉽게 넣을 수 있지만 대부분의 실제 목적을 위해 이것은 다루기가 더 쉽습니다.
./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
이것은 여분의 줄을 추가합니다. 작업하면 코드를 작성할 수 있습니다. 너무 게으르다.
편집 :이 사례는 완벽하게 작동하지만 이것을 읽는 사람들은 while 루프 내에서 stdin을 쉽게 스쿼시 할 수 있으므로 한 줄을 실행하고 stdin을 지우고 종료하는 스크립트를 제공합니다. ssh처럼 내가 생각하는 것입니까? 방금 최근에 다른 코드 예제를 보았습니다 : /unix/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");}'