我有以下脚本(行号仅供参考):
#!/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 行末尾的注释,尽管 stdout 和 stderr 重定向到/dev/null
! ,但一切正常。
我尝试了以下方法:
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
可能会抱怨缺少目录路径),否则它不会向屏幕写入任何内容。
第grep
3 行确实写入标准输出, 尽管。也许您想要-q
安静模式的标志。
我试图了解您实际上想要做什么,因为我认为它可能可以更简单地处理:
for item in atk/*
do
test -d "$item" && echo "${item/*\/}" | grep -Fvf atk/versions
done
顺便说一句,使用反引号进行命令插值不再被认为是良好的编码风格。您最好使用该$( ... )
构造。例如for version in $( ls ... awk )