파이프를 닫지 않고 bash 변수 할당을 자르는 방법

파이프를 닫지 않고 bash 변수 할당을 자르는 방법

하위 프로세스의 출력에서 ​​초기화되는 Bash 변수에 저장되는 데이터의 양을 제한하는 방법을 찾고 있습니다.

이 잠재적 솔루션의 문제점은 전체 출력을 자르기 전에 저장한다는 것입니다.

#!/bin/bash

COMMAND_TO_RUN="du /"

OUT_DATA=$($COMMAND_TO_RUN)
OUT_RESULT=$?

if [[ $OUT_RESULT -ne 0 ]]; then
    echo "${OUT_DATA:0:10000}" | head mail -s "Command failed" [email protected]
fi

대안은 OUT_DATA=$($COMMAND_TO_RUN | head -c 10000)출력의 처음 10k를 읽을 때 명령을 취소하고 종료 상태를 캡처하기 위해 완료될 때까지 실행하는 명령이 필요합니다.

에서는 아주 쉽게 할 수 있지만 유일한 해결책이 python있기를 바라고 있습니다 bash. 또한 디스크에 쓰지 않고도 가능합니다.

답변1

기능이 있습니다. 가독성을 위해 아래 예제에서는 명령 등을 하드코딩합니다.

truncated_du() {
   du / | { head -c 10000; cat >/dev/null; }
   return "${PIPESTATUS[0]}"
}

out_data="$(truncated_du)"
out_result="$?"

head최대 원하는 양의 데이터를 함수의 표준 출력으로 전달합니다. 데이터가 더 있으면 cat중단하지 않고 삭제합니다 du. 종료 상태는 배열 du에서 검색되어 PIPESTATUS함수에 의해 반환됩니다.

참고: 내 변수는 lower case; 보다이 답변.


함수가 없으면 동일한 솔루션은 다음과 같습니다.

out_data="$(
   du / | { head -c 10000; cat >/dev/null; }
   exit "${PIPESTATUS[0]}"
)"
out_result="$?"

IMO 이런 식으로 읽기가 거의 어렵습니다.

답변2

이는 캡처하는 양을 제한하지만 s 종료 상태로 종료한다고 가정합니다 ( 종료 상태가 존중되지 않기 때문에 read중지하는지 여부는 잘 모르겠습니다 . `head

IFS= read -r -d '' -n $chars_to_capture foo < <($command)

명령이 완료될 때까지 실행되는 것처럼 보이지만 명령의 종료 상태를 얻지 못하고 read도움이 되지 않는 종료 상태를 얻습니다.

$ IFS= read -r -d '' -n 19 foo < <(seq 50; touch somefile; exit 42); echo "exit=$?"; ls -l somefile
exit=0
-rw-r--r-- 1 glennjackman staff 0 Jul 22 22:04 somefile

파일을 터치했다는 사실은 요청한 문자 수를 캡처한 후에도 명령이 중단되지 않는다는 것을 의미한다고 가정합니다.

아마도 서브셸의 파일에 종료 상태를 쓸 수 있을 것입니다.

IFS= read -r -d '' -n 10000 out_data < <( $command_to_run; echo $? > statusfile )
if [[ -f statusfile ]] && [[ "$(<statusfile)" != "0" ]]; then
    printf "%s\n" "$out_data" | head mail -s "Command failed" [email protected]
    rm statusfile
fi

관련 정보