I have the following script (line numbering is for reference):


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

if I run it as is, line 1 will send the following to the screen:(I really don't want this, would like stdout/stderr to go to /dev/null, but more on this later)

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

line 2 will look for $version in a "versions" file that contains the following:


if $version is not found in the "versions" file then print $versions to stdout.

output should be the following:


how do I get line 1 to send its output to /dev/null and then have line 3 send its output back to stdout and stderr?

strangely enough, if I uncomment the end of line 3, everything works fine in spite of the redirection of stdout and stderr to /dev/null!

I tried the following:

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

not only did it suppress the output that I didn't want to see from line 1, but also the output from line 3 that I did want to see even after modifying the code as such:

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

again, why does line 3 without the comment work when I'm explicitly asking to send all output to /dev/null?

1 Answer 1


On line 1 the command in backticks sends its stdout to the for... loop. It writes nothing to the screen unless there's an error from one of the commands (for example, ls might complain about the directory path being missing).

The grep on line 3 does write to stdout, though. Perhaps you want the -q flag for quiet mode.

I'm trying to understand what you're actually trying to do, because I think it can probably be handled much more simply:

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

As an aside, using backticks for command interpolation is no longer considered good coding style. You would be better using the $( ... ) construct. Such as for version in $( ls ... awk )

  • thanks roaima, that pointed me in the right direction and revealed what this script is actually doing. Commented Feb 22, 2017 at 18:32
  • @linuxbox099 if this answer solved your problem please use the tick mark to accept it Commented Feb 23, 2017 at 13:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .