Redirection? (I do find some of the strangest things.)

(Apologies for any typos.)
Can someone help me with this one please.
I am writing a snippet that will come on here soon to work on OSX, Linux and CygWin but I hit this!

I hope this is lucid enough because I really do not understand what is going on.

Take these few lines:-

#!/bin/sh
# OR #!/usr/local/bin/dash
> /tmp/noise.raw
> /dev/null 2>&1 cat /tmp/noise.raw > /dev/dsp

And tested in ShellCheck gives this:-

$ shellcheck myscript
 
Line 3:
> /tmp/noise.raw
^-- SC2188: This redirection doesn't have a command. Move to its command (or use 'true' as no-op).

$ 

OK so I add a NOP:-

#!/bin/sh
# OR #!/usr/local/bin/dash
: > /tmp/noise.raw
> /dev/null 2>&1 cat /tmp/noise.raw > /dev/dsp

And tested in ShellCheck gives NO error:-

$ shellcheck myscript
No issues detected!

$ 

Why is a redirection to > /dev/null allowed to be a _direct_ redirection and yet : > /tmp/noise.raw requires a NOP?

Next question is this line, > /dev/null 2>&1 cat /tmp/noise.raw > /dev/dsp actually works to hide an OSX error, paraphrasing, 'I don't have permssion to access this' which is obvious as OSX does not have '/dev/dsp'.
This line also runs correctly on CygWin with > /dev/null 2>&1 at the start. So it looks like I have done something correct but don't know why?

TIA.

Barry.

Shellsheck SC2188 message is not reporting an invalid syntax but is merely a warning telling there is a potential bug. Adding a no-op command makes the intention clear but it is not required.

The line:

> /dev/null 2>&1 cat /tmp/noise.raw > /dev/dsp

discards the potential error messages and it has a command (cat) so Shellcheck doesn't report an error with it.

1 Like

Hmmm, quite some questions in one post. And, I can't comment for all thoses OSes nor all shells, nor on shellcheck . For bash on linux and FreeBSD,

  • You can have any number of redirections in a command line any place; they're evaluated left to right, and the last one will be effective. Check what >/tmp/1 cat file1 > /tmp/2 > /tmp/3 does.
  • In your line > /dev/null 2>&1 cat /tmp/noise.raw > /dev/dsp it might be interesting to check where the error msgs go. What be your first guess?
  • You don't need a command nor a NOP; >/tmp/1 will just open the file, empty it, and close it. This can be (and is) used to effectively create an empty file.
  • That shellcheck comment seems to be a warning, not an error. shells allow for that construct.
  • Your conclusion about non-existence of /dev/dsp from the permission error might be incorrect.

Hi RudiC...
Macbook Pro, OSX 10.12.2, default bash terminal.

Last login: Tue Jan 10 09:03:20 on ttys000
AMIGA:amiga~> > /dev/null 2>&1 cat /tmp/noise.raw > /dev/dsp
AMIGA:amiga~> cat /tmp/noise.raw > /dev/dsp > /dev/null 2>&1
-bash: /dev/dsp: Operation not permitted
AMIGA:amiga~> 
AMIGA:amiga~> 
AMIGA:amiga~> bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)
Copyright (C) 2007 Free Software Foundation, Inc.
AMIGA:amiga~> _

NOTE: '/tmp/noise.raw' does NOT exist and that the error must be trapped somewhere but the __system__ one is not trapped.
However jlliagre's post makes sense because I thought it might have generated a syntax error the way I have written it, but it didn't.

A couple of comments:

  • The error is still trapped (detected and reported), the message just happen not to be displayed on the terminal.

  • Should a shell syntax error had existed in your command line, it would still have been displayed on the terminal. Redirections are performed after the command is parsed, syntax errors are detected during the parsing.

1 Like

Did you check the exit code of the command in either case?

No. As it is unimportant; I just don't want it to show nor crash out when a relatively serious error occurs but to be ignored. These are three lines in the code to suit:-
1) \dev\dsp for CygWin, OSS and PulseAudio for Linux.
2) ALSA for Linux ALSA sound systems.
3) OSX 10.12.x or maybe earlier.
If any one fails just ignore and carry on to the next. One of them will work.

# CygWin /dev/dsp, Linux OSS or PulseAudio.
> /dev/null 2>&1 cat /tmp/noise.raw > /dev/dsp
# Linux ALSA.
aplay /tmp/noise.wav > /dev/null 2>&1
# Apple OSX 10.12.x and greater.
afplay /tmp/noise.wav > /dev/null 2>&1

As Apple OSX 10.7.x at least has 'afplay' by default on a virgin install then there should be no reason for the code to fail.
CygWin(64) has /dev/dsp in a default virgin install.
Linux is variable as it could have either ALSA, OSS or PulseAudio sound systems.