스크립트가 실행되면 그 안에 있는 명령이 일부 텍스트를 stdout/stderr로 출력할 수 있습니다. Bash 자체도 일부 텍스트를 출력할 수 있습니다.
그러나 여러 스크립트를 동시에 실행하면 오류가 어디서 발생하는지 파악하기 어려울 수 있습니다.
그러면 스크립트의 모든 출력에 접두사를 삽입하는 것이 가능합니까? 그것은 다음과 같습니다:
#!/bin/bash
prefix 'PREFIX' &2
echo "wrong!" >&2
그 다음에:
$ ./script.sh
PREFIXwrong!
답변1
선택한 접두사를 추가하는 프로세스 교체로 stderr/stdout을 리디렉션할 수 있습니다. 예를 들어 다음 스크립트는 다음과 같습니다.
#! /bin/bash
exec > >(trap "" INT TERM; sed 's/^/foo: /')
exec 2> >(trap "" INT TERM; sed 's/^/foo: (stderr) /' >&2)
echo foo
echo bar >&2
date
다음과 같은 출력이 생성됩니다.
foo: foo
foo: (stderr) bar
foo: Fri Apr 27 20:04:34 IST 2018
처음 두 줄은 stdout과 stderr을 입력에 foo:
추가하는 sed 명령으로 각각 리디렉션합니다. 쉘 내장 호출은 종료 스크립트를 사용하거나 . 이렇게 하면 종료 신호도 수신했기 때문에 종료 시 파일 설명자가 사라지기 때문에 쉘이 스크립트를 강제로 종료하지 않도록 할 수 있습니다. 실제로 기본 스크립트에서 종료 트랩을 계속 사용할 수 있으며 종료 트랩을 실행할 때 생성된 모든 출력을 처리하기 위해 계속 실행됩니다. 하위 쉘은 메인 스크립트가 끝난 후에도 종료되어야 프로세스가 영원히 실행되지 않습니다.foo: (stderr)
trap
Ctrl+C
SIGTERM
kill $pid
stdout
sed
sed
sed
답변2
라인을 대체하는 방식으로 출력을 파이프할 수 있습니다.
some long running stuff | sed -e 's/^/Some said: /;'
또한 확인24337
또는 터미널/...(1)탭/탭의 별도 파일/화면으로 별도의 출력을 직접 지정합니다.
답변3
Bash의 한 가지 옵션은 다음과 같이 프로세스 교체로 리디렉션하여 이를 수행하는 것입니다.
./script.sh > >(sed 's/^/script: /') 2> >(sed 's/^/script (err): /' >&2)
이것은 출력이 순서에 맞지 않을 수 있는 문제를 가지고 있습니다(Charles Duffy가 주석에서 언급했듯이). 이것도 정말 불편해요. 하지만 이에 대한 래퍼 함수를 만들 수 있습니다.
prefixwith() {
local prefix="$1"
shift
"$@" > >(sed "s/^/$prefix: /") 2> >(sed "s/^/$prefix (err): /" >&2)
}
prefixwith "From script" ./script.sh
또는 명령 이름을 앞에 붙여서 더 쉽게 만들 수 있습니다.
prefixoutput() {
local prefix="From ${1##*/}"
"$@" > >(sed "s/^/$prefix: /") 2> >(sed "s/^/$prefix (err): /" >&2)
}
prefixoutput ./script.sh