Echo won't print to serial without cat observing it - bash

I've been trying to send commands to an ESP8266 using the terminal on OSX. I've been able to open the nodemcu interface using screen and send commands successfully, but when I try and send commands via echo (turning the on board LED on):
echo "gpio.mode(3,gpio.OUTPUT) gpio.write(3,gpio.LOW)" > /dev/cu.SLAB_USBtoUART
the command executes but nothing happens. However if I have a second terminal running:
cat /dev/cu.SLAB_USBtoUART
to read the console the echo command executes and the light turns on.
I've been able to run the command on ubuntu (changing the /dev/ path) and it worked without the second terminal. I've found using screen that any command executed via echo without the cat terminal being open just sends the first letter. I've also found the same problem using printf instead of echo.

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; }

How to run the "cat" command on the background inside the script

I have a USB LTE modem connected to my Raspberry and I need to read replies sent via serial line, generated by requests sent using the "echo" command.
Example:
cat /dev/ttyUSB0 &>> /ttyUSB0_logs &
echo "AT+csq" > /dev/ttyUSB0
echo "AT+cgreg=2" > /dev/ttyUSB0
echo "AT+cgreg?" > /dev/ttyUSB0
The problem is, although the "cat" command should run on the background and all output is directed to the file, script still freezes at this point. If I use the first command outside of the script, it works as I expect - it stores all output to the file ttyUSB0_logs on the background and I can use the received data for other operations. The question is - how can I integrate the first command to the script to get it work this way? Thanks a lot.
you want:
cat /dev/ttyUSB0 >> /ttyUSB0_logs &
if that doesn't work, you should double check what is actually freezing. you can put set -x at the top of the script to get tracing output.

Executing a command after the first command executed

I just recently installed beep on Ubuntu and finally managed to get it to work.
So I was able to hear the beeping sound after executing:
beep
Everything worked well, however, I was just wondering if it's possible to execute "beep" everytime I execute a command. Say for example:
cat /etc/passwd && beep
After reading /etc/passwd, it will be executing a beeping sound. I'd like to know if there's a way to execute beep after every command without having me to use "&& beep" always.
A clearer example:
ls && beep
ls -la && beep
cat /etc/passwd && beep
Notice the constant command "beep" followed by "&&" after every initial command.
You can set PROMPT_COMMAND=beep (try it first, then add to your ~/.bashrc if it doesn't drive you crazy). This will execute beep just before it displays the command prompt.
You could try altering your prompt:
PS1="$PS1"'\007'

Echoing 'at' command in terminal fails

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>

Resources