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
How Convert Address in Elf to Physical Address
Configuring Tomat's Server.Xml File with Auto Generating Mod_Jk.Conf
Using Source to Include Part of a File in a Bash Script
How to Wget The More Recent File of a Directory
Alpine Linux: Pmap Output Not Showing Rss
How to Introspect Normal World from Secure World Using Trustzone
Pass File Input and Stdin to Gdb
How to Modify The Linux Kernel to Change The Version String That Uname Returns
Undefine Reference for Libraries, So How Could I Find The Right Path
Trying to Install Docker Gpg Key Recieving Error: Curl: Option '-' Is Unknown
PHPmyadmin Mcrypt Extension Is Missing
PHPmyadmin, Neginx Error.Log - Check Group Www-Data Has Read Access and Open_Basedir
How My Custom Module on Linux 3.2.28 Can Make a Call to Print_Cpu_Info