Bash 스크립트에서 stdout 및 stderr 리디렉션

Bash 스크립트에서 stdout 및 stderr 리디렉션

다음 스크립트가 있습니다(줄 번호는 참조용으로만 사용됨).

#!/bin/bash

1-  for version in `ls -al ./atk/ | grep ^d | grep -Ev '\.$' | awk -F' ' '{print $8}'`
2-      do
3-          grep $version ./atk/versions #&>/dev/null <--(first ran with this comment out)
4-          if [ $? -ne 0 ]
5-              then
6-                  printf '%-15s\n' "$version"
7-          fi
8-      done

있는 그대로 실행하면 라인 1은 다음을 화면에 보냅니다. (나는 이것을 정말로 원하지 않고 stdout/stderr가 로 이동하기를 원 /dev/null하지만 이에 대해서는 나중에 자세히 설명합니다.)

aaaaa--------
bbbbb       |
ccccc       |
ddddd       |------------ wil be stored in the version variable
eeeee       |
fffff       |
ggggg--------

$version2행에서는 다음을 포함하는 "버전" 파일을 찾습니다.

12345
aaaaa
67890
ccccc
09876
fffff

$version"versions" 파일에 없으면 $versions가 표준 출력으로 인쇄됩니다 .

출력은 다음과 같아야 합니다.

bbbbb
ddddd
eeeee
ggggg

라인 1이 출력을 로 보내고 /dev/null, 라인 3이 출력을 다시 stdout 및 stderr로 보내도록 하려면 어떻게 해야 합니까?

이상한 점은 3행 끝의 주석 처리를 제거하면 /dev/nullstdout과 stderr이 !로 리디렉션되지만 모든 것이 잘 작동한다는 것입니다.

나는 다음을 시도했다:

for version in `ls -al ./atk/ | grep ^d &>/dev/null | grep -Ev '\.$' | awk -F' ' '{print $8}'` &>/dev/null

이는 내가 보고 싶지 않은 라인 1의 출력을 억제할 뿐만 아니라 코드를 수정한 후에도 보고 싶은 라인 3의 출력도 억제합니다.

for version in `ls -al ./atk/ | grep ^d | grep -Ev '\.$' | awk -F' ' '{print $8}'` &>/dev/null
    do
        exec &>/dev/tty  ++++++++++++++ trying to reset stdout and stderr back to the origal setting
        grep $version ./atk/versions #&>/dev/null

다시 말하지만, 모든 출력을 로 보내도록 명시적으로 요청할 때 주석 처리되지 않은 3행이 작동하는 이유는 무엇입니까 /dev/null?

답변1

1행에서 백틱 안의 명령은 해당 명령을 보냅니다.표준 출력루프 for.... 명령에서 오류가 발생하지 않는 한(예: ls디렉터리 경로 누락에 대한 불만 표시) 화면에 아무 것도 쓰지 않습니다.

3번째 줄 grep은 씁니다.표준 출력, 하지만. 어쩌면 -q자동 모드 플래그를 원할 수도 있습니다 .

나는 그것이 아마도 더 간단하게 처리될 수 있다고 생각하기 때문에 실제로 하고 싶은 것이 무엇인지 이해하려고 노력하고 있습니다.

for item in atk/*
do
    test -d "$item" && echo "${item/*\/}" | grep -Fvf atk/versions
done

그런데 명령 보간에 역따옴표를 사용하는 것은 더 이상 좋은 코딩 스타일로 간주되지 않습니다. 이 구조를 사용하는 것이 더 좋습니다 $( ... ). 예를 들어for version in $( ls ... awk )

관련 정보