스크립트 출력의 자체 리디렉션에 해당하는 대시


9

Bash에서는 현재 실행중인 스크립트 의 모든 향후 stdout 출력을 리디렉션 할 수 있습니다 . 예를 들어이 스크립트를 사용하면

exec > >(logger -t my-awesome-script)
echo 1
echo 2
echo 3

이것은 syslog에서 끝납니다 :

Oct 26 01:03:16 mybox my-awesome-script[72754]: 1
Oct 26 01:03:16 mybox my-awesome-script[72754]: 2
Oct 26 01:03:16 mybox my-awesome-script[72754]: 3

그러나 이것은 Bash 전용이며 리디렉션이있는 벌거 벗은 exec는 Dash에서 작동하지 않는 것 같습니다.

Syntax error: redirection unexpected

Dash 또는 두 셸에서 어떻게 작동합니까?


정확히 필요한 것을 명확히 할 수 있습니까? >대시로 리디렉션 할 수 있습니다 . 나는 당신이 다른 것을 요구하는 것처럼 보이지만 그것이 무엇인지 알 수는 없습니다.
terdon

@terdon 나는 설명을 확장했다.
Alex B

답변:


6

당신은 할 수 있습니다 :

{ commands
....
} | logger -t my_awesome_script

아무 쉘에서나 할 수 있습니다.

모양이 마음에 들지 않으면 스크립트를 함수로 감싸십시오.

#!/bin/sh
run() if     [ "$run" != "$$" ] || return
      then   sh -c 'run=$$ exec "$0" "$@"' "$0" "$@" |
             logger -t my-awesome-script
      fi
#script-body
run "$@" || do stuff

마지막 행은 run ${1+"$@"} || do stuff인수가 유지되도록 해야합니다 .
Adam Katz

@ AdamKatz-좋은 지적, execpt ${1+"$@"}는 아무것도하지 "$@" 않습니다. 어쨌든 다른 문제가있었습니다.
mikeserv

"$@"전달합니다 ""인수를가 없을 때 동안 ${1+"$@"}인수가없는 경우 빈 문자열을 전달합니다. ""빈 따옴표로 구문 분석 하고 따옴표가없는 빈 문자열은 전혀 인수로 해석되지 않으므로 많은 프로그램에서 매우 중요 합니다.
Adam Katz

@AdamKatz-매우 오래된 Bourne 쉘은 (그리고 dash그러한 시스템 에서 찾을 것으로 예상 하지는 않지만 ) , "$@"인수가없는 경우 POSIX 쉘의 널 인수를 대체하지 않는다는 점에서 독특합니다.
mikeserv

1
@AdamKatz-그것은 오래된 bsh에서도 실제로 버그였으며 결코 그렇게 작동해서는 안됩니다. 결국 수정되었지만 예를 들어 Solaris 10에서 여전히 필요한지 여부는 모르겠습니다. 당신은 $ *에 대해 옳습니다-그것은 폭발의 동일한 깔끔한 특성을 나타내지 않습니다-그것의 독창성은 확장의 가변적 인 내용과 관련이 있지만, 그것은 항상 무언가 일 것 "${@+is especially cool $@}" 입니다. 그러나 결국 이전 ${1+”$@"}해결 방법 과 크게 다르지 않습니다 . ksh93이있는 경우 :"${1+quoted" not quoted "quoted again}"
mikeserv

5

명명 된 파이프를 사용하여 공정 대체를 쉽게 시뮬레이션 할 수 있습니다.

mkfifo logger_input
logger -t my_awesome_script < logger_input &
exec > logger_input
echo 1
echo 2
echo 3

실제로 명명 된 파이프는 /dev/fd프로세스 대체가 구현 될 수있는 메커니즘 중 하나입니다 (다른 것 ) bash.


내 의견으로는 가장 다재다능하다 : 나는 티를 사용하여 여러 스트림으로 원활하게 리디렉션 할 수있다. 한 가지만 : 스크립트 끝에 생성 된 logger_input을 삭제하는 것을 잊지 마십시오.
lauhub

2

나는 이것이 가능하지 않다고 생각합니다 dash. man페이지 에서 알 수있는 한 프로세스 대체를 지원하지 않습니다.

해결 방법으로 mikserv가 제안한 것을 시도 하거나 모든 것을 파일로 리디렉션 한 다음 스크립트가 완료된 후 (아마도 스크립트에 있음) 해당 파일의 내용을 로거에 추가하십시오.

$ exec > ~/foo/foo.txt
$ ls
$ echo something
$ cat foo/foo.txt | sudo logger -t my-awesome-script

실제로 다른 쉘보다 프로세스 대체 또는 다른 쉘이 프로세스 대체를 호출하는 것이 더 쉽습니다 dash. 프로세스 대체 /dev/fd/[num]는 익명 파이프 에 대한 링크를 가리키는 인수에 해당 합니다. dash대부분의 다른 쉘과 마찬가지로 임시 파일을 생성하지 않고 익명 파이프가있는 문서를 작성합니다. 따라서 cat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\n기능적으로 동등 할뿐만 아니라 직접 fd의 이름을 지정할 수도 있습니다. 아직도, 당신의 요점은 다른 길로가는 것에 대한 것입니다. 당신 exec은 그것을 읽는 프로세스 와 함께 새로운 fd를 열고 배경을 만들어야 합니다.
mikeserv

2
@ mikeserv : 어떤 의미에서 cat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\n"쉬운"것보다 cat <(get output)?
ruakh

@ mikeserv : 기억해야 할 규칙이 많이 있습니다. 아마 당신은 단순히 눈치 채지 못하도록 그들에게 익숙해 져있을 것입니다.
ruakh

@ruakh-물론 이죠. < >쉘 리디렉션. 기본적으로 두 가지 중 하나만 수행하면 다음 줄에 쌓을 수 있습니다. 하지만 네, 요점이 있습니다-나는 여기 문서를 좋아합니다. 그럼에도 불구하고 기억해야 할 많은 것들이 보편적으로 일할 때 더 쉽다고 생각합니다. 그런 다음 많은 사람들이 다른 껍질을 많이 사용하지 않으므로 아무런 차이가 없습니다. 나는 그들 중 하나가 아닙니다.
mikeserv

1
@ mikeserv : heredocs뿐만 아니라 /dev/fd/3(정확한 형식), 공백에 대한 세부 정보도 있습니다. . . 그 문제에 대해이 모든 접근 방식이 Dash에서 전혀 작동한다는 사실은 모든 구성 요소가있는 다른 쉘에서 작동하지 않을 때 전체 접근 방식이 기억해야 할 특별한 규칙임을 의미합니다. (이것은 어휘가 적은 간단한 영어를 만들려는 시도를 생각 나게합니다. 이들은 persist 같은 단어를 잘라내 지만, keep on 과 같은 어려운 관용구는 무시 합니다 .)
ruakh
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.