The "hi" stream is printed in my prompt (in the stdin
) and not in my stdout
No, it's not "printed in your stdin
".
If you pressed return, it wouldn't try to run hi
as a command. It's just that the backgrounded echo
printed hi
while the cursor was after your prompt.
Perhaps you want to print a leading newline, like (sleep 1m && echo -e '\nhi' &)
. (Adjust as necessary for the echo
in your shell. Or use printf
for portability.)
I put the &
inside the subshell to "disown" the background job, so you also avoid the "noise" of [1]+ Done
. With &&
between the commands, &
applies to the whole compound-command chain, so it returns to the shell prompt right away instead of waiting for sleep
to exit like you'd get with (sleep 1; echo ... &)
Here's what happens (with 1 second delay):
peter@volta:~$ (sleep 1 && echo -e '\nhi' &)
peter@volta:~$
hi
# cursor is at the start of this empty line.
Bash doesn't know that echo
printed something, so it doesn't know it needs to re-print its prompt or clean up the screen. You can do that manually with control-L
.
You could write a shell function that gets bash to re-print its prompt after echo
finishes. Just doing echo "$PS1"
won't reproduce any already-typed characters. kill -WINCH $$
on my system gets bash to re-print its prompt line without clearing the screen, leaving hi
on a line by itself before the prompt. SIGWINCH is sent automatically when the WINdow size CHanges, and bash's response to it happens to do what we want.
It might work with other shells, but I'm not attempting to make this 100% portable / POSIX. (Unfortunately, this only works on bash4.4, not bash4.3, or depends on some setting I'm unaware of)
# bash4.4
peter@volta:~$ (sleep 2 && echo -e '\nhi' && kill -WINCH $$ &)
peter@volta:~$ ljlksjksajflasdf dfas # typed in 2 seconds
hi
peter@volta:~$ ljlksjksajflasdf dfas # reprinted by Bash because of `kill -WINCH`
You could easily wrap this up in a shell function that takes a sleep arg and a message.
bash 4.3 doesn't re-print its prompt after SIGWINCH, so this doesn't work there. I have shopt -s checkwinsize
enabled on both systems, but it only works on the Bash 4.4 system (Arch Linux).
If it doesn't work, you could try (sleep 2 && echo -e '\nhi' && echo "$PS1" &)
, which "works" if the command line is empty. (It also ignores the possibility that PROMPT_COMMAND
is set.)
There's no really clean way to get terminal output to mix with whatever you might be doing on your terminal later, when the timer fires. If you're in the middle of scrolling something in less
, you could easily miss it.
If you're looking for something with interactive results, I suggest playing an audio file. e.g. with a command-line player like mpv
(nice fork of MPlayer2). Or pick a video file so a new window opens.
(sleep 1 && mpv /f/share/music/.../foo.ogg </dev/null &>/dev/null &)
You might want to have your echo
open a new xterm / konsole / gnome-terminal. Use an option that keeps the terminal open after the command exits.