Echoing 'at' command in terminal fails - bash

The following should print "hello" (or some reminder) on my Linux command line at 9:00 AM today:
$ at 9:00AM
warning: commands will be executed using /bin/sh
at> echo "hello"
at> <EOT>
However, at the specified time, nothing happens.
I have an empty etc/at.deny and no /etc/at.allow file, so there shouldn't be any problems with permissions to use the command. Also, writing a file at 9:00 AM works:
$ at 9:00AM
at> echo "hello" > /home/mart/hello.txt
at> <EOT>
$ cat /home/mart/hello.txt
hello
All jobs are shown as scheduled, I just can't get any output to the terminal window (I'm on Crunchbang Linux with Terminator). Why? Do I need to somehow specify the window for that output?
Thanks for any help!

at runs commands from a daemon (atd), which doesn't have access to your terminal. Thus, output from the script isn't going to appear in your terminal (unless you pipe to the right tty in your command).
Instead, it does as man at says:
The user will be mailed standard error and standard output from his commands, if any.
You may be able to access these reports using mail if your machine is suitably configured.
If you want to have at write to your terminal, you can try piping the output to write, which writes a message to a user's TTY, or to wall if you want to write to every terminal connected to the system.

Okay, nneonneo's explanations led me to using wall, which sends a message to all users. So setting oneself reminders in a terminal window can be done like this:
$ at 9:00AM
warning: commands will be executed using /bin/sh
at> echo "hello" | wall
at> <EOT>

Related

Why does "(echo <Payload> && cat) | nc <link> <port>" creates a persistent connection?

I began with playing ctfs challenges, and I encountered a problem where I needed to send an exploit into a binary and then interact with the spawned shell.
I found a solution to this problem which looks something like this:
(echo -ne "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\xbe\xba\xfe\xca" && cat) | nc pwnable.kr 9000
Meaning:
without the "cat" sub-command, I couldn't interact with the shell, but with it, i now able to send commands into the spawned shell and get the returned output to my console stdout.
What exactly happens there? this command line confuses me
If you just type in cat at the command line, you'll be able to see that this command simply copies stdin to stdout one line at a time. It will carry on doing this until you either quit with Ctrl-C or send an EOF with Ctrl-D.
In this example you're running cat immediately after successfully printing the payload (the concatenator && tells the shell to run the second command only if the first command has an exit code of zero; i.e., no error). As a result, the remote terminal won't see an EOF until you terminate it as described above. When this is piped to nc, everything you type in is sent via cat to the remote server, and everything it sends back appears on your stdout.
So yes, in effect you end up with an interactive shell. You can get pretty much the same effect on your own machine by running cat | sh.

Why isn't this command returning to shell after &?

In Ubuntu 14.04, I created the following bash script:
flock -nx "$1" xdg-open "$1" &
The idea is to lock the file specified in $1 (flock), then open it in my usual editor (xdg-open), and finally return to prompt, so I can open other files in sequence (&).
However, the & isn't working as expected. I need to press Enter to make the shell prompt appear again. In simpler constructs, such as
gedit test.txt &
it works as it should, returning the prompt immediately. I think it has to do with the existence of two commands in the first line. What am I doing wrong, please?
EDIT
The prompt is actually there, but it is somehow "hidden". If I issue the command
sudo ./edit error.php
it replies with
Warning: unknown mime-type for "error.php" -- using "application/octet-stream"
Error: no "view" mailcap rules found for type "application/octet-stream"
Opening "error.php" with Geany (application/x-php)
__
The errors above are not related to the question. But instead of __ I see nothing. I know the prompt is there because I can issue other commands, like ls, and they work. But the question remains: WHY the prompt is hidden? And how can I make it show normally?
Why isn't this command returning to shell after &?
It is.
You're running a command in the background. The shell prints a new prompt as soon as the command is launched, without waiting for it to finish.
According to your latest comment, the background command is printing some message to your screen. A simple example of the same thing:
$ echo hello &
$ hello
The cursor is left at the beginning of the line after the $ hello.
As far as the shell is concerned, it's printed a prompt and is waiting a new command. It doesn't know or care that a background process has messed up your display.
One solution is to redirect the command's output to somewhere other than your screen, either to a file or to /dev/null. If it's an error message, you'll probably have to redirect both stdout and `stderr.
flock -nx "$1" xdg-open "$1" >/dev/null 2>&1 &
(This assumes you don't care about the content of the message.)
Another option, pointed out in a comment by alvits, is to sleep for a second or so after executing the command, so the message appears followed by the next shell prompt. The sleep command is executed in the foreground, delaying the printing of the next prompt. A simple example:
$ echo hello & sleep 1
hello
[1] + Done echo hello
$
or for your example:
flock -nx "$1" xdg-open "$1" & sleep 1
This assumes that the error message is printed in the first second. That's probably a valid assumption for you example, but it might not be in general.
I don't think the command is doing what you think it does.
Have you tried to run it twice to see if the lock cannot be obtained the second time.
Well, if you do it, you will see that it doesn't fail because xdg-open is forking to exec the editor. Also if it fails you expect some indication.
You should use something like this
flock -nx "$1" -c "gedit '$1' &" || { echo "ERROR"; exit 1; }

Repeating Bash Task using At

I am running ubuntu 13.10 and want to write a bash script that will execute a given task at non-pre-determined time intervals. My understanding of this is that cronjobs require me to know when the task will be performed again. Thus, I was recommended to use "at."
I'm having a bit of trouble using "at." Based on some experimentation, I've found that
echo "hello" | at now + 1 minutes
will run in my terminal (with and without quotes). Running "atq" results in my computer telling me that the command is in the queue. However, I never see the results of the command. I assume that I'm doing something wrong, but the manpages don't seem to be telling me anything useful.
Thanks in advance for any help.
Besides the fact that commands are run without a terminal (output and input is probably redirected to /dev/null), your command would also not run since what you're passing to at is not echo hello but just hello. Unless hello is really an existing command, it won't run. What you want probably is:
echo "echo hello" | at now + 1 minutes
If you want to know if your command is really running, try redirecting the output to a file:
echo "echo hello > /var/tmp/hello.out" | at now + 1 minutes
Check the file later.

bash show output only during runtime

I am trying to write a script that displays its output to the terminal only while it's running, much like the 'less' or 'ssh' commands.
When I launch said script, it would take over the whole terminal, print what it needs to print, and then when I exit the script, I would return to my terminal where the only record that my script has run will be the line that shows the command itself. When I scroll up, I don't want to see what my script output.
[snoopdougg#machine /home/snoopdougg/logs]$ ls
alog.log blog.log clog.log myScript.sh
[snoopdougg#machine /home/snoopdougg/logs]$ whoami
snoopdougg
[snoopdougg#machine /home/snoopdougg/logs]$ ./myScript.sh
[snoopdougg#machine /home/snoopdougg/logs]$
(Like nothing ever happened... but myScript.sh would have print things to the terminal while it was running).
How can I do this?
You're talking about the alternate screen, which you can access with a pair of terminal attributes, smcup and rmcup. Put this in a script and run it for a small demo:
tput smcup
echo hello
sleep 5
tput rmcup
Use screen:
screen ./myScript.sh

How to Quit TFTP script

I have a tftp script here that when run it just hangs and brings me to a blank line (which tells me it's hanging). I can quit the script by Ctrl+C...
#!/bin/bash
hostname=$1;
filename=$2;
tftp <</dev/null
mode binary
get $hostname:$filename
quit
I have also tried to add EOF at the end of the script, but that doesn't work either.
Here is my command line...
$ ./tftpShell.sh host1 myFileName >/home/aayerd200/tftpoutput.txt 2>/home/aayerd200/tftperror.log
So when I run the script, it just leaves me on a blank line. However, it does actually do the work it should with get, I do get the file I want.
Of course host1 and myFileName are actual fields that I replaced here for security.
How can I stop this script? I believe it is just tftp hanging upon $ ps -u aayerd200, or when run by php $ ps -u daemon
You have /dev/null as a here document "delimiter" Try some random set of characters like EOF that have no meaning to the shell. And terminate the here doc
tftp <<-EOF
mode binary
get $hostname:$filename
quit
EOF
Okay so I just made this a background process by appending & to the end of the command. Then I ran $ echo $! for the PID. Then I ran $ kill PID.
That was my solution to this, for now at least.

Resources