Bash에서는 파이프라인의 중간 노드 결과를 어떻게 계산하고 캡처합니까?
예를 들어, 단일 Bash 파이프를 사용하여 정수 목록과 명령 또는 함수가 주어지면 maximum
목록을 표준 출력으로 출력하는 동안 변수에 있는 정수 목록의 최대값을 어떻게 캡처할 수 있습니까?
capture_maximum_and_print_numbers
아래 Bash 스크립트에서는 함수를 단일 파이프가 되도록 변경하는 것이 아이디어입니다 .
function maximum {
awk 'NR==1||$0>x{x=$0}END{print x}'
}
function capture_maximum_and_print_numbers {
local numbers="3\n6\n1\n4\n2\n9\n5\n"
maximum=$(printf $numbers | maximum)
printf $numbers
}
capture_maximum_and_print_numbers
printf "maximum=$maximum\n"
답변1
결과를 변수에 엄격하게 할당하고 숫자 목록을 한 줄로 표준 출력으로 출력하는 경우 다음은 원하는 것을 제공할 것입니다. (나는 max 함수의 이름을 함수의 기능에 맞게 변경했으며 변수는 $maximum
저장된 결과 자체에 해당합니다):
function calc_max {
awk 'NR==1||$0>x{x=$0}END{print x}'
}
function capture_maximum_and_print_numbers {
local numbers="3\n6\n1\n4\n2\n9\n5\n"
export maximum=$(printf $numbers | tee /dev/tty | calc_max)
}
capture_maximum_and_print_numbers
echo max_result="$maximum"
#You have stored the max_result variable and can pass it to whatever you want.
tee
긴 명령 파이프라인 중간에 "현재" 결과를 다른 파일에 저장하거나 표준 출력으로 출력하는 등의 작업에 사용할 수 있습니다. 단일 파이프라인을 별도의 대상이 있는 여러 복사본으로 분할하는 동시에 "기본" 파이프라인이 체인 아래로 계속 처리되도록 허용합니다.
tee dev/tty
tty
현재 터미널의 파이프 에 해당하며 /dev/tty
모든 *nix 시스템에 나타납니다.
답변2
#!/bin/sh
generate_data () {
shuf -i 0-1000 -n 10 -r
}
print_maximum () {
awk 'NR == 1 || m < $0 { m = $0 } END { print m }'
}
exec 3>&1
maximum=$(
generate_data |
tee /dev/fd/3 |
print_maximum
)
exec 3>&-
printf 'maximum = %d\n' "$maximum"
이것은 임의의 숫자를 전달하고 tee
파일 설명자 3과 stdout에 복사합니다 tee
. 표준 출력은 print_maximum
생성된 숫자 중 가장 큰 숫자를 찾아 출력하는 으로 읽혀집니다.
파일 설명자 3은 처음에 쉘의 표준 출력 스트림의 복사본으로 열리게(사용됩니다) exec 3>&1
, 이는 파일 tee
디스크립터가 에 기록될 때(쓰기를 통해 /dev/fd/3
) 데이터가 쉘의 표준 출력에 표시된다는 것을 의미합니다. 파일 설명자는 나중에 닫힙니다(사용됨 exec 3>&-
).
이 스크립트는 /bin/sh
bash-isms를 사용할 필요가 없으므로 bash-isms를 사용합니다. 그럼에도 불구하고 파일 설명자 3으로 작동하고 시스템 제공 경로에 의존하지 않는다는 bash
것이 보장됩니다 ./dev/fd/3
예제를 실행하세요:
$ sh script
918
787
290
998
737
1000
845
374
497
809
maximum = 1000
grep
모든 출력이 스크립트의 표준 출력에서 생성된다는 것을 보여주기 위해 생성된 데이터가 가능하다는 것을 보여줄 수 있습니다.
$ sh script | grep -F 0
100
807
maximum = 807
$ sh script | grep -F 0
440
207