You can close stderr as in:
ls /blah 2>&-
While that will work in most cases, it may cause problems as poorly written applications may end up opening a new file which would automatically get 2
as the file descriptor and could end up writing error messages where you wouldn't want them to.
That also means that any write to stderr done by the application would return with an error (EBADF) which may affect their behavior.
As pipes are allowed, you could provide with a command that discards all its input. Here, using grep -v '^'
(but you could use tail -n 0
or sed d
or a script called discard
that does cat > /dev/null
):
{ ls /blah 2>&1 >&3 | grep -v '^'; } 3>&1
Alternatively, you could have whatever starts that restricted shell start it with the fd 3 (for instance) redirected to /dev/null
(rbash 3> /dev/null
), so you can then do within the restricted shell:
ls /blah 2>&3
Which is allowed:
$ rbash -c 'ls /blah 2>&3' 3> /dev/null
$
You can check whether redirection to /dev/null
is allowed/works or not with:
if true 2>&- > /dev/null; then
echo allowed
fi
You can check whether the shell is restricted or not with:
case $- in
(*r*) echo restricted
esac
From bash's point of view, the two produce the same effect.
Either one will successfully write to the pipe if you have something reading from it, and since the pipe is a special device (rather than a file), its length will not change (as a regular file would, if you used the >>
append operator). The pipe does not remember what you have written to it, after forwarding the data to the reader, so >
and >>
look the same.
Further reading:
Best Answer
With zsh and with the
mult_ios
option on (on by default), in:The
1> /dev/null | cat
is seen as a multiple redirection ofecho
's stdout.So
echo
's stdout is now redirected to both/dev/null
and a pipe tocat
(as if usingtee
).To cancel that multiple redirection, you can do:
That is, closing stdout (cancelling the piping) before redirecting to
/dev/null
Or use a command group or subshell like:
That way,
echo
's stdout is only redirected explicitly once (the pipe redirection is applied to the group/subshell and inherited byecho
).Or you can disable
multios
altogether:Alternatively, you could use process substitution instead of a pipe:
Beware however that when job control is off (like in scripts), the
cat
process will be running asynchronously (as if started with&
).