나는 그것에 대해 많은 어려움을 겪고 읽었으며 bash가 사용하기에 가장 좋은 도구가 아닐 수도 있다는 것이 분명합니다. 그러나 이 구멍을 너무 깊이 파고들었기 때문에(이미 너무 많은 코드가 존재합니다) 나는 마지막 생각에 이르렀습니다. 솔루션이 존재하는지, 어떤 모습일지 알고 싶습니다.
내 목표: 내장 명령, 함수 또는 다른 스크립트 등 무엇이든 될 수 있는 명령줄 호출을 래핑하고 다음을 수행하는 "my_run"이라는 함수입니다.
- 명령줄을 호출합니다.
- stderr를 파일(file_e)로 보내고 각 줄에 타임스탬프를 찍습니다.
- stdout을 별도의 파일(file_s)로 보내고 각 줄에 타임스탬프를 표시합니다.
- 콘솔에서 출력을 렌더링합니다(따라서 위의 티셔츠).
- 명령의 종료 반환 코드를 반환합니다.
저는 1~4명이 일하고 있고 실제로 5명도 일하고 있지만 동일한 목표를 달성하기 위한 다른/더 나은 방법이 있는지 궁금합니다.
현재 이는 값을 파일에 저장하고 변수로 읽어서 수행됩니다. 내가 말했듯이 - 작동합니다.
내 요청
변수에 "내부적으로"(아래 18행) 값을 할당하고 중간 파일을 사용하지 않고 외부에서 사용할 수 있도록 하는 방법이 있습니까?
파이프가 하위 쉘을 생성하고 환경이 해당 하위 쉘에서 다시 전달되지 않으며 shopt -s lastpipe
(대화형 쉘에서 작업 관리 비활성화 set +m
) 도움이 될 것이라는 것을 알고 있지만 '마지막 파이프에서'를 할당하지 않기 때문에 이것은 그렇지 않습니다. 나를 위해 그것을 사용한 적이 없습니다.
이런 일을 한 사람이 있습니까?
내가 관심 있는 코드는 다음과 같습니다.
01 EXIT_CODE_TMP=$(mktemp)
02 unset MY_RUN_EXIT_CODE
03 MY_RUN_EXIT_CODE=0
04
05 # This is my failed attempt to try and capture the return code.
06 #shopt -s lastpipe
07
08 # This is where all the work is done:
09 # * Redirect stderr(2>) into stdout(&1), stdout(1>) in to
10 # stream:3(&3)
11 # * grabs the code and dumps into a temp file
13 # * Tees while adding a timestamp into the *.2err log file
14 # * Redirects stream:3(3>) into stdin(&1), and stdin(1>) into
15 # stderr(&2), basically reverting back
16 # * Tees while adding a timestamp into the *.1std log file
17 { {
18 2>&1 1>&3 "${1}" "${@:2}" || echo $? > $EXIT_CODE_TMP
19 } | tee >(_ts "E" > "/tmp/log.${MY_RUN_NAME}.2err")
20 } 3>&1 1>&2 \
21 | tee >(_ts > "/tmp/log.${MY_RUN_NAME}.1std")
22
23 # Reads the exit code form the temp file (and deletes the file)
24 MY_RUN_EXIT_CODE=$(( 0 + 0$(cat $EXIT_CODE_TMP; rm $EXIT_CODE_TMP) ))
코드를 테스트하고 싶다면 내 개인 폴더에 전체 기능 사본을 넣어두었습니다.하스테바인.
업데이트: 범위 설명
질문은 bash
구체적이고 다른 곳에 해결책이 있다는 것을 알고 있지만 이를 위해서는 다른 셸을 설치할 수 없는 환경에서 실행해야 합니다.
답변1
사용하기가 더 쉽습니다 zsh
. bash에서 zsh로 전환하면 더 많은 두통이 사라질 수 있습니다.
{
the-command(s)-you-want-to-redirect
} > >(ts "%FT%T%z OUT:" >&1 > file_s) 2> >(ts "%FT%T%z ERR:" >&2 > file_e)
여기서는 Moreutil을 사용하여 ts
타임스탬프를 수행합니다.