3

I ran the following code block (an at timeout to uninstall PHPmyadmin). It should be scheduled to run 2 horus ahead, but I ran it in a timeout of 2 minutes, just to test it:

bash /dev/fd/50 50<< PMA_UNINSTALL | at 'now + 2 minutes'

apt-get purge phpmyadmin -y
PMA_UNINSTALL

The at utility seems to prevent me from using Bash freely, unless I do CTRL+C. At also prompts the following warning, which is normal, and hardcoded in the Utility's source code. When I do CTRL+C the warning vanish and I can use Bash regularly again.

commands will be executed using /bin/sh

I don't say that it's the warning that prevents me from using Bash regularly as long it appears. I know the warning is just stdout and something else might prevent me from creating stdin.

What prevents me from creating stdin piping the above code block with at and how could I reach a state when I could execute commands piped with at, but use Bash freely right afterwards without interrupting at to work ?

muru
  • 207,228

2 Answers2

4

It took me some time to see your real problem - you want to directly send a command to at instead of providing command(s) afterwards as i assumed.

There is no need for a complicated scheme, just type

echo 'apt-get purge phpmyadmin -y' | at 'now + 2 minutes'

When you do it this way at does not expect any input afterwards and you get back to the command line immediately.


(keeping my original answer here)

Issuing at gives you the possibility to list commands to execute. You have to tell at that you are done:

Press CTRL + D (This is also known as End Of Transmisssion)

guntbert
  • 13,475
3

TL;DR: Those commands don't seem to do what you probably intend.

If you're trying to make at execute apt-get purge phpmyadmin -y from bash in 2 minutes, then your code will not do what you want it to do.

The command on the left of the pipe (|) has your here document as its standard input. That command does not even run until the shell has read your complete here document.

From 3.6.6 Here Documents in the Bash Reference Manual:

This type of redirection instructs the shell to read input from the current source until a line containing only word (with no trailing blanks) is seen. All of the lines read up to that point are then used as the standard input (or file descriptor n if n is specified) for a command.

A command with a here document is, in effect, just a single command that must be fully read by the shell before it is executed. In your code, the shell reads input until PMA_UNINSTALL appears on a line by itself. Once that has happened, the shell then uses the content of the here document as file descriptor 50 for the command bash /dev/fd/50.

That command does not even start a new instance of bash until the here document has been fully read. When bash does run, it runs this command:

apt-get purge phpmyadmin -y

Since the whole left side of the pipe including the here document has its standard output piped to at, the input at gets is the output of bash, which is the output of apt-get purge phpmyadmin -y. at then attempts to interpret that output--not your apt-get command, but its output--as a list of commands to execute in /bin/sh.

So this is almost certainly not what you mean to do.

I'm not sure why you don't get a shell prompt back right after entering that code. When I run it on a test machine, I get a shell prompt back in a couple of seconds. If you want to debug this, you can try running apt-get purge phpmyadmin -y interactively in bash. The way your code is written, that command runs completely before at returns to the shell (and before at can schedule anything). It would probably not be useful to debug this particular code further, though.

Eliah Kagan
  • 119,640