Bash Redirect to /Dev/Stdout: Not a Directory

bash redirect to /dev/stdout: Not a directory

Good morning, user1999165, :)

I suspect it's related to the underlying filesystem. On the same machine, try:

(echo "hi" > /dev/stdout) > /tmp/test.txt

/tmp/ should be linux native (ext3 or something) filesystem

Redirect to stdout in bash

Basic solution:

#!/bin/bash
LOG=/dev/null

# uncomment next line for debugging (logging)
# LOG=/tmp/some_file

{
some_command
echo "blah"
} | tee 1>$LOG 2>&1

More evolved:

#!/bin/bash

ENABLE_LOG=0 # 1 to log standard & error outputs
LOG=/tmp/some_file

{
some_command
echo "blah"
} | if (( $ENABLE_LOG ))
then
tee 1>$LOG 2>&1
fi

More elegant solution from DevSolar's idea:

#!/bin/bash

# uncomment next line for debugging (logging)
# exec 1> >(tee /tmp/some_file) 2>&1

some_command
echo "blah"

Bash redirect and append to non-existent file/directory

Using install :

command | install -D /dev/stdin nonexistent/file.log

or use

mkdir nonexistent

first.

Consistency of bash redirection to the same file

If you open the descriptors separately, they're totally independent streams. If they're pointing to the same file, they'll each keep track of the file offset independently. So the first time you write to one stream it will write to the beginning of the file, and the first time you write to the other it will also write to the beginning of the file, overwriting what the previous write did. This will keep happening, with writes to each stream overwriting the other.

What you can do is first empty each file, then open them both in append mode:

> $myStdout
> $myStderr
redirect 1>> $myStdout 2>> $myStderr

By appending, each write will first seek to the end of the file, so it will go after whatever the previous write did, rather than overwriting it.

However, there may be another issue. If the program uses stdio, it buffers stdout by default, but not stderr. So unless the program flushes the stdout buffer before printing error messages, they're likely to get interspersed in random places in the output, not neatly on their own lines.

Where do I direct the output?

>& is a variant on the > pipeline operation. While > redirects output into a named file (or the device's representation in the filesystem, such as /dev/console), >& redirects the output to one of the standard output streams. The most commonly used exaples are stream 1 (stdout) and stream 2 (stderr). Note that these are the same numbers you can use in front of the > or >& operators to say which stream's output you want to redirect.

echo "hello" >&1 is redundant; you're redirecting stdout to stdout.
(echo "hello" 1>&1 would mean the same thing, of course.)

A more interesting example: echo "hello" 2>&1 redirects the echo command's error output from stderr to stdout, combining them into a single stream. This one is often useful if you want to run all the output through a single pipe rather than having them treated separately. echo "hello" 2>&1 | tee log, for example, captures a copy of both normal output and error messages into a single log file.

BroSlow points out that, in version 4 and later of the bash shell, |& can be used as a shorthand for combining the streams, equivalent to 2>&1. Good to know. (I still move between shells too frequently to have started using that one.)

Is it possible to redirect stdout to a non-stderr stream inside a shell script?

For completeness, based on tripleee's comment, what I actually wanted was the following:

#!/bin/bash

echo "Send me to standard out"
echo "Send me to standard err" >&2

if ! (printf '' 1>&3) 2>&-; then
# File descriptor 3 is not open
# Option 1: Redirect fd3 to stdout.
exec 3>&1
# Option 2: Redirect fd3 to /dev/null.
# exec 3>/dev/null
fi

# No error here.
echo "Send me to stream 3" >&3

With this modification, a parent process can redirect 3 when it desires to do so, and otherwise have it as part of stdout.

$ ./Play.sh
Send me to standard out
Send me to standard err
Send me to stream 3

$ ./Play.sh 3> /dev/null
Send me to standard out
Send me to standard err



Related Topics



Leave a reply



Submit