Search code examples
bashshellvariable-assignmentglobcommand-substitution

How to create a variable with error going to /dev/null


I am not able to redirect an expected error to &>/dev/null in the following simple code.

xml=`ls ./XML_30fps/*.xml ./XML_24fps/*xml`

The expected error is due to the fact that one of the folders could be empty and so the error would be "No such file or directory." I don't want this error to show up to the users.

I could resolve this by breaking down this line of code but I was wondering if there was a simple way to redirect to null with a single line of code in such case. Neither of these work:

xml=`ls ./XML_30fps/*.xml ./XML_24fps/*xml` &>/dev/null
xml=`ls ./XML_30fps/*.xml ./XML_24fps/*xml &>dev/null`

This link How to avoid printing an error in the console in a BASH script when executing a command? kind of touch upon this but it is not as clear as my question and the answer given here.


Solution

  • How about substituting your command with an alternative that doesn't write to stderr, e.g.

    xml=()
    if [ -d XML_24fps ]; then
      xml+=($(find XML_24fps -maxdepth 1 -type f -name '*.xml'))
    fi
    if [ -d XML_30fps ]; then
      xml+=($(find XML_30fps -maxdepth 1 -type f -name '*.xml'))
    fi
    echo ${xml[@]}
    

    In the above, we're using find to locate all *.xml files in a subfolder. We put a guard condition so that we do not run find on folders that do not exist.

    By noting that XML_24fps and XML_30fps are very similar with the difference being just the 24 and 30 we can refactor the above with a {24,30} expansion as follows:

    xml=()
    for d in XML_{24,30}fps
    do
      if [ -d $d ]; then
        xml+=($(find $d -maxdepth 1 -type f -name '*.xml'))
      fi
    done
    echo ${xml[@]}