1

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.

Robin
  • 339
  • 1
  • 9
  • @MaximilianBallard I don't see how this answer my question, but thank you. I am trying to create one variable by listing two folders. If one of the folder is empty, it will give a error. I am trying to get a one-liner that reroutes the error to /dev/null. – Robin Jan 30 '23 at 02:57
  • 1
    So redirecting error like `xml=\`ls ./XML_30fps/*.xml ./XML_24fps/*xml 2>/dev/null\`` doesn't work? – Maximilian Ballard Jan 30 '23 at 03:01
  • 3
    `&>/dev/null` will redirect `stdout` AND `stderror` to `/dev/null` so you are assigning `xml` to nothing. – Maximilian Ballard Jan 30 '23 at 03:03
  • @MaximilianBallard Good point! Yes 2>/dev/null works. I didn't see this in the links above. Thank you very much. – Robin Jan 30 '23 at 03:07
  • @MaximilianBallard Could you post your answer with the details above so that I can accept your answer, since it helped me. – Robin Jan 30 '23 at 04:11
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/251484/discussion-between-maximilian-ballard-and-robin). – Maximilian Ballard Jan 30 '23 at 04:16
  • If the link I sent in my first comment solved your problem then the question is a duplicate and will probably be removed or closed, etc. Also generally its not good form to answer duplicates. – Maximilian Ballard Jan 30 '23 at 04:22

2 Answers2

1

Redirect it within the subshell:

xml=`exec 2>/dev/null; ls ./XML_30fps/*.xml ./XML_24fps/*xml`

Or

xml=$(exec 2>/dev/null; ls ./XML_30fps/*.xml ./XML_24fps/*xml)
konsolebox
  • 72,135
  • 12
  • 99
  • 105
  • Thank you. How do you compare your answer with that of Maximilian xml=`ls ./XML_30fps/*.xml ./XML_24fps/*xml 2>/dev/null` ? Is yours better for some reason? I am not sure why would I need to redirect within the subshell. I would appreciate if you could elaborate. – Robin Jan 30 '23 at 03:42
  • 1
    @Robin Mine will also capture errors coming from the subshell but it's not necessarily better. – konsolebox Jan 30 '23 at 03:47
0

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[@]}
Stephen Quan
  • 21,481
  • 4
  • 88
  • 75