Why does this not print anything?
bash -c '(while echo "not printing" ; do sleep 1; done) > "$(tty)" & sleep 10'
Even though this, for example, does:
bash -c '(while echo "is printing" ; do sleep 1; done) > "$(tty)" && true'
Let's take your first command, and run it in a temporary directory:
mkdir eg1 # Create temporary directory
cd eg1 # ...and change to it
ls # No output (obviously, no files)
bash -c '(while echo "not printing" ; do sleep 1; done) > "$(tty)" & sleep 10'
But now take a look in the directory:
ls -l
-rw-r--r--+ 1 roaima roaima 1040 Jun 6 23:05 not a tty
What has happened here is that the tty
command reports the terminal device such as /dev/pty0
when it's executed with a terminal attached, and the message not a tty
otherwise. When it's run in the background (&
) as a subshell (( … )
) there is no terminal device, so output is redirected to what happens to be a file called not a tty
.
Now in the second case everything is very similar except that the subshell is not being executed in the background:
bash -c '(while echo "is printing" ; do sleep 1; done) > "$(tty)" && true'
In this instance tty
is running in the foreground and can return the device name of the current terminal, so you see the output on your screen.
Notice that the &&
is a logical connector such that the second command will only run if the first returns a "successful" (0-valued) exit status. Do not confuse it with &
, which instructs the preceding command to run independently in the background:
# Run the ( ... ) in the background concurrently with the foreground process
( sleep 1; echo background ) & echo foreground; wait
[1] 32301
foreground
background
[1]+ Done ( sleep 1; echo background )
# Run the ( ... ) and then if it's successful execute the next statement
( sleep 1; echo background ) && echo foreground; wait
background
foreground
Depending on what you want to achieve you might want to consider using /dev/tty
, or even not redirecting the output at all.