2

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

#!/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

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)

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

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

12345
aaaaa
67890
ccccc
09876
fffff

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

output should be the following:

bbbbb
ddddd
eeeee
ggggg

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
    do
        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?

2

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/*
do
    test -d "$item" && echo "${item/*\/}" | grep -Fvf atk/versions
done

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. – linuxbox099 Feb 22 '17 at 18:32
  • @linuxbox099 if this answer solved your problem please use the tick mark to accept it – roaima Feb 23 '17 at 13:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.