Init Script '/Dev/Tty: No Such Device or Address' Error on Redirect

init script '/dev/tty: No such device or address' error on redirect

Rather than writing to /dev/tty, how about simply swapping stdout and stderr?

yourcommand 3>&2 2>&1 1>&3 3>&-

This is the redirection equivalent of swapping the contents of two variables using a third temporary variable:

3>&2  # tmp = stderr 
2>&1 # stderr = stdout
1>&3 # stdout = tmp
3>&- # close(tmp)

How do i fix bash error - /dev/tty No such device or address

To fix the bash error, you can try this workaround :

tty=$(readlink /proc/$$/fd/2)
read ... < $tty

$tty contains the actual tty device name.

-su: /dev/tty: No such device or address

The manpage for su states that the executed command will have no controlling terminal. Any writes to /dev/tty will return the ENXIO error:

$ errno ENXIO
ENXIO 6 No such device or address

sudo does allocate a controlling terminal:

sudo -u someone /bin/bash -c "echo hello > /dev/tty"

There's no need for you to make a symbolic link to /dev/tty (/dev/stdout and /dev/stderr is enough) or use sudo if you use the USER directive in the Dockerfile or supervisor.

Error The input device is not a TTY

Remove the -it from your cli to make it non interactive and remove the TTY. If you don't need either, e.g. running your command inside of a Jenkins or cron script, you should do this.

Or you can change it to -i if you have input piped into the docker command that doesn't come from a TTY. If you have something like xyz | docker ... or docker ... <input in your command line, do this.

Or you can change it to -t if you want TTY support but don't have it available on the input device. Do this for apps that check for a TTY to enable color formatting of the output in your logs, or for when you later attach to the container with a proper terminal.

Or if you need an interactive terminal and aren't running in a terminal on Linux or MacOS, use a different command line interface. PowerShell is reported to include this support on Windows.


What is a TTY? It's a terminal interface that supports escape sequences, moving the cursor around, etc, that comes from the old days of dumb terminals attached to mainframes. Today it is provided by the Linux command terminals and ssh interfaces. See the wikipedia article for more details.

To see the difference of running a container with and without a TTY, run a container without one: docker run --rm -i ubuntu bash. From inside that container, install vim with apt-get update; apt-get install vim. Note the lack of a prompt. When running vim against a file, try to move the cursor around within the file.

Cross-platform method to detect whether /dev/tty is available & functional

After testing lots of promising but not quite perfect suggestions (see the other answers), I think I've found my own solution that does exactly fit my needs:

if sh -c ": >/dev/tty" >/dev/null 2>/dev/null; then
# /dev/tty is available and usable
else
# /dev/tty is not available
fi

To explain:

: >/dev/tty does nothing (using the : bash built-in) and outputs the nothing to /dev/tty, thereby checking that it exists & it's writable, but not actually producing any visible output. If this succeeds, we're good.

If we do that at the top level without a /dev/tty, bash itself produces a noisy error in our output, complaining about /dev/tty being unusable. This can't be redirected and silenced because it comes from bash itself, not the : command.

Wrapping that with sh -c "..." >/dev/null 2>/dev/null runs the test in a bash subshell, with stdout/stderr removed, and so silences all errors & warnings while still returning the overall exit code.

Suggestions for further improvements welcome. For reference, I'm testing this with setsid <command>, which seems to be a good simulation of the TTY-less environment I'm having trouble with.

Can not write to '/dev/tty' when build Docker images

I've fixed this problem: it turns out I didn't install command tar & perl before hand.
And the script wants to write error messages to /dev/tty.
The error information led me to the wrong way to solve this issue.

Thanks.

Pseudo-terminal will not be allocated because stdin is not a terminal

Try ssh -t -t(or ssh -tt for short) to force pseudo-tty allocation even if stdin isn't a terminal.

See also: Terminating SSH session executed by bash script

From ssh manpage:

-T      Disable pseudo-tty allocation.

-t Force pseudo-tty allocation. This can be used to execute arbitrary
screen-based programs on a remote machine, which can be very useful,
e.g. when implementing menu services. Multiple -t options force tty
allocation, even if ssh has no local tty.

What is special about /dev/tty?

The 'c' means it's a character device. tty is a special file representing the 'controlling terminal' for the current process.

Character Devices

Unix supports 'device files', which aren't really files at all, but file-like access points to hardware devices.
A 'character' device is one which is interfaced byte-by-byte (as opposed to buffered IO).

TTY

/dev/tty is a special file, representing the terminal for the current process. So, when you echo 1 > /dev/tty, your message ('1') will appear on your screen. Likewise, when you cat /dev/tty, your subsequent input gets duplicated (until you press Ctrl-C).

/dev/tty doesn't 'contain' anything as such, but you can read from it and write to it (for what it's worth). I can't think of a good use for it, but there are similar files which are very useful for simple IO operations (e.g. /dev/ttyS0 is normally your serial port)

This quote is from http://tldp.org/HOWTO/Text-Terminal-HOWTO-7.html#ss7.3 :

/dev/tty stands for the controlling terminal (if any) for the current
process. To find out which tty's are attached to which processes use
the "ps -a" command at the shell prompt (command line). Look at the
"tty" column. For the shell process you're in, /dev/tty is the
terminal you are now using. Type "tty" at the shell prompt to see what
it is (see manual pg. tty(1)). /dev/tty is something like a link to
the actually terminal device name with some additional features for
C-programmers: see the manual page tty(4).

Here is the man page: http://linux.die.net/man/4/tty



Related Topics



Leave a reply



Submit