다음 스크립트가 있습니다(줄 번호는 참조용으로만 사용됨).
#!/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--------
$version
2행에서는 다음을 포함하는 "버전" 파일을 찾습니다.
12345
aaaaa
67890
ccccc
09876
fffff
$version
"versions" 파일에 없으면 $versions가 표준 출력으로 인쇄됩니다 .
출력은 다음과 같아야 합니다.
bbbbb
ddddd
eeeee
ggggg
라인 1이 출력을 로 보내고 /dev/null
, 라인 3이 출력을 다시 stdout 및 stderr로 보내도록 하려면 어떻게 해야 합니까?
이상한 점은 3행 끝의 주석 처리를 제거하면 /dev/null
stdout과 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 )