나는 무엇이든 파이프로 연결될 경우 매개변수로 전달될 수 있는 스크립트를 작성할 수 있기를 원합니다 stdout
(결국 다형성이 되기를 원합니다).
문제는 이 작업을 수행하는 방법을 검색하고 검색했지만 아무 소용이 없다는 것입니다. 다른 작업을 수행하는 방법에 대한 많은 대안 제안은 그렇지 않습니다.
cat /var/log/some.log | grep something | awk '{print $1 $6 $8}' | myscript
대신 왜 이렇게 합니까? : myscript $(!!)
지금 이 순간, 그것이 가능하다는 것을 증명하기 위해...
스크립트에서 "변수를 읽을" 수 있다는 것을 알고 있지만 행에 신경 쓰지 않는다고 가정해 보겠습니다. 전체 스크립트를 텍스트 블록으로 받아들이고 스크립트에서 이를 사용하여 작업을 수행하고 싶다고 가정해 보겠습니다.
나는 정말로 다음을 수행해야 한다:
while read x; do
stdin=$stdin" "$x;
done;
STDIN에서 읽으려면?
더 좋은 방법이 있을 텐데요...
답변1
모든 stdin을 쉘 스크립트로 읽으려면 일반적으로 임시 파일에 캡처하면 됩니다.
TMPFILE=$(mktemp -- "${TMPDIR:-/tmp}/${0##*/}.$$.XXXXXX") || exit
cat > "$TMPFILE"
# Script works with $TMPFILE and its contents,
# ultimately writing everything to stdout.
rm -f -- "$TMPFILE"
시스템 유틸리티도 비슷한 작업을 수행합니다. sort
예를 들어, 표준 출력으로 무엇이든 인쇄하려면 모든 표준 입력을 사용할 수 있어야 합니다.
답변2
입력을 파일 설명자 1로 리디렉션하여 stdout을 읽을 수 있습니다. 정의에 따르면 Stdout은 파일 설명자 1입니다. 파일 설명자 1이 출력에 사용된다는 사실은 기술적인 의무가 아니라 관례의 문제입니다. 그러나 이것은 이상한 일이며 스크립트를 사용하는 사람들을 혼란스럽게 할 것입니다.
read line <&1
전체 파일을 읽으려면 를 사용하십시오 cat
. 변수에 내용을 채우려면 명령 대체를 사용하십시오.
whole_input=$(cat)
whole_input_from_stdout=$(cat <&1)
$(</dev/stdin)
일부 쉘에서는 이를 좀 더 효율적인 단축키로 작성할 수 있습니다 $(cat)
.
이렇게 하면 후행 줄 바꿈이 제거됩니다. 이 동작은 명령 대체에 내장되어 있습니다. 후행 줄 바꿈을 유지하려면 다른 문자 뒤에 숨기고 해당 문자를 제거하십시오.
whole_input=$(cat; echo .); whole_input=${whole_input%?}
입력에 널 바이트가 있는 경우 쉘 변수에는 첫 번째 널 바이트까지의 데이터만 포함됩니다. 일부 쉘에서는 널 바이트가 제거된 모든 데이터를 얻을 수 있습니다. 쉘은 바이너리 데이터를 처리할 수 없습니다. null 바이트를 예약하는 Zsh는 예외입니다.
답변3
당신이 의미하는 바는 표준 입력이나 인수에서 명령의 표준 출력을 처리할 수 있도록 스크립트를 작성한다는 것입니다.
그렇다면 가장 확실한 방법은 매개변수의 개수를 확인하는 것이다.
스크립트가 쉘 변수의 입력을 처리하는 경우:
#! /bin/sh -
if [ "$#" -gt 0 ]; then
# arguments joined with space, the first character of $IFS
input="$*"
else
input=$(cat) # stdin without the trailing newline characters
fi
printf 'I got "%s"\n' "$input"
또는 인수가 전달되지 않으면 stdin의 비어 있지 않은 각 줄을 위치 인수( $@
: $1
, ...)로 읽을 수 있습니다.$2
#! /bin/sh -
NL='
'
if [ "$#" -eq 0 ]; then
set -o noglob
IFS=$NL
set -- $(cat) # split+glob with splitting on NL and glob disabled
fi
echo "I got $# arguments:"
[ "$#" -eq 0 ] || printf ' - "%s"\n' "$@"
또는 입력을 스트림으로 처리하는 경우:
#! /bin/sh -
main() {
# process standard input as a stream
grep -i foo | tr '[:lower:]' '[:upper:]'
# as an example
}
if [ "$#" -gt 0 ]; then
# feed arguments as separate lines through a pipe:
printf '%s\n' "$@" | main
else
# stdin just passed along
main
fi
이들 모두는 다음을 통해 호출할 수 있습니다.
cmd | the-script
또는:
the-script "$(cmd)"
(따옴표를 잊지 마세요. 따옴표가 없으면 출력은 cmd
분할+글로브의 영향을 받습니다!)
또한보십시오:
- 쉘 루프를 사용하여 텍스트를 처리하는 것이 왜 나쁜 습관으로 간주됩니까?
- var=$(</dev/stdin) stdin을 변수로 읽는 데 어떤 문제가 있나요?(대신 사용하고 싶은 경우
input=$(cat)
).
답변4
내가 이해하는 바는 1) 장치를 별도로, 2) 일반적인 데이터 흐름 인터페이스, 3) 특히 라인 리더/라이터 인터페이스, 4) 의미를 고려해야 한다는 것입니다.
stdout
동일한 수명 주기를 가진 프로세스 전용 기술 엔드포인트이며 읽기가 아닌 바이트 스트림에 쓰는 데 사용됩니다. 다른 이름으로 참조하기 위해 참조를 복사할 수 있습니다. 해당 기능은 항상 다음과 같습니다.산출. 프로세스와 함께 생성 및 삭제됩니다. stdin
바이트 스트림을 읽는 것과 동일합니다. 그 능력은 언제나입력하다. 기본 장치에 따라 두 가지 기능을 모두 가질 수 있지만 이는 표준 및 신뢰할 수 있는 모델에서는 알려져 있지 않습니다.
ㅏ바이트 스트림는 쓰기 쪽에서 두 개의 신호( , )를 받아들이고 put
읽기 close
쪽에서 두 개의 해당 신호( , )를 내보내는 일반 인터페이스입니다 byte
. EOD
쓰기 측(예: stdout
)이 하나를 받으면 put
읽기 측도 하나를 받아야 합니다 byte
. 쓰기 쪽이 수락하면 close
읽기 쪽이 을 얻습니다 EOD
. ()는 EOD
설명자가 닫히거나 프로세스가 종료될 때 close
명시적으로 전송됩니다 .stdout
exec >&-
ㅏ행 판독기 또는 기록기추가 신호를 사용하여 바이트 스트림으로 작업하는 특별한 방법이지만 Nor에 고유한 newline
것은 아니며 단지 데이터 변환일 뿐입니다.stdin
stdout
텍스트 라인편리하고 조작이 쉽고 튼튼하기 때문입니다. 이것은라인 프로토콜또는 규율, 역사적 표준, 반복 가능하고 합리적인불가지론자. 신호 newline
는 관습입니다. 그것이 무엇이든 가치가 있어야 합니다. 다른 상태에 의존할 수밖에 없지만 장치에는 켜짐 또는 꺼짐이라는 두 가지 상태만 있습니다. 즉, 바이트 스트림은 장치 중심이고 라인 리더는 데이터 중심입니다.
이를 고려하여 두 프로세스 간에 통신을 원한다고 가정해 보겠습니다.통과하다스피커가 청취자에게 보낼 수 있는 최소 신호인 파이프는 byte
과 입니다 EOD
.반복적으로 할 수는 없다텍스트 줄에서 했던 것처럼 일단 닫히면( EOD
전송되면) 파일 설명자는 다음과 같습니다.재사용 불가(해킹이 가능할지라도). 하지만,반복할 필요가 없는 한, 당신은 신뢰할 수 있습니다 EOD
.
그렇다면 현실적으로 생각해 봅시다.다형성말했듯이 이 작업을 수행할 때 반복 가능한 행 모델이 손실되면 바이트 스트림의 원시 데이터에 문제가 되지 않습니다. 다형성이 문제다모델라인 규칙과 같은 간단한 반복 가능한 프로토콜과 바이트 스트림과 같은 기본 프로토콜 외에 소켓, 파이프, 파일, 테이프, 프린터 또는 기타 프로토콜을 통해 구현될 수 있습니다.
그러나 스트리밍 모델 위에는 두 가지 반복 제어만 있습니다. 읽어야 할 개수를 미리 알고 있거나 신호가 있을 때까지 하나씩 읽는 것입니다. 이를 알면 항상 문제가 되는 텍스트 줄 대신 원본 스트림 위에 좋아하는 규칙을 채택할 수 있습니다.파서. 파서는 스트림을 읽고 자체 언어 모델로 다른 개체를 구성하는 기계입니다.
또한 스트림 상단에서 허용 가능한 인터페이스가 되려면 마지막 반복이 떠난 정확한 지점에서 순차적으로 구문 분석을 계속해야 합니다.
이제 우리는 알아요다형성 + 반복 => 순차 파서, 우리는 표준으로 돌아갈 수 있고 매우 만족할 수 있습니다. 우리에게 필요한 것은케이엡나티에스구현하다에스멍청한.