at some time from now do something (and maybe also show result in console)

The correct at usage is at <timespec>, where <timespec> is the time specification. You can also use the -f option to specify the file containing the commands to execute. If -f and no redirection is used, at will read the commands to execute from the stdin (standard input).

In your example, to execute "some command" (I chose "some command" to be "echo hi" in the example below) one minute right after you hit enter (now), the intended <timespec> to be used is now + 1 minute. So, in order to obtain the result you want with a one-liner solution, please use the command below:

echo 'echo hi' | at now + 1 minute

This is supposed (and will do) to run the echo hi command after one minute. The problem here is that the echo hi command will be executed by the at command in a dummy tty and the output will be sent to the user's mail box (if it is correctly configured - which requires a more extensive explanation on how to configure a mail box in a unix machine and is not part of the scope of this question). The bottomline is that you won't be able to directly see the result of echo hi in the same terminal you issued the command. The easiest alternative is you redirect it to "some file", for example:

echo 'echo hi > /tmp/at.out' | at now + 1 minute

In the above example, "some file" is /tmp/at.out and the expected result is that the file at.out under /tmp is created after one minute and contais the text 'hi'.

In addition to the now + 1 minute example above, many other time specifications can be used, even some complex ones. The at command is smart enough to interpret pretty human readable ones like the examples below:

now + 1 day, 13:25, mid‐night, noon, ...

Please refer to at's man page for more about the possible time specifications as the possible variations are pretty extensive and may include dates, relative or absolute times, etc..


Run the sleep in a subshell:

(sleep 60; echo -e '\nhi')  &

Note: on Linux you can give the argument to sleep in seconds or with a suffix s/m/h/d (for seconds, minutes, hours, days). On BSD the argument has to be in seconds


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.