Send and read serial commands from terminal - shell

I have a very limited list of software that I can install on an (IOT edge) device. I have minicom and chat commands (in addition to standard commands like echo and cat), and need to write to a serial device a command and read the response.
The device in question is a modem, and I need to run AT commands on it. If using minicom and setting up the menu etc. I can run these commands normally, and get the output. The problem is that I have around a thousand of these devices, so setup and data logging needs to be automated.
So within these parameters is there a way to run minicom and capture the output without any interactive elements? I have tried
minicom -S scriptfile -C outfile
where scriptfile (for now) contains following:
sleep 1
send "AT"
This seems to ignore the sleep command, and outfile is created, but is left empty. Also what would I need to add to the command that it wouldn't open a session or interactive element?

Related

Sending a command in the windows command prompt that terminates after a certain time

I am using a batch script to create a short functional test for technicians at my work which would normally require them to send several commands back-to-back themselves.
There is a command that brings up an image on the test device, but the command hangs until you press ctr+c. When doing everything manual that's fine but I don't want the technicians to do that during the script because they might accidentally exit out of the whole thing.
Is there a way to make it so the script can stop that command and move on the next line in the script? Something like a timeout on the command? Or a key press that just stops the command but doesn't close the script?
Code sample:
echo "Booting Device..."
adb start device
timeout 40
adb shell load_image yosimite.png
timeout 5

Redirect xterm to a background for a headless machine

I have a application that launches xterm and dumps uart logs. I am able to see it launch and dump the logs in the GUI. However, Using a remote session I want the xterm output to be running as a background process somewhere so that I can switch back and forth within a single terminal.
Using GUI
Using remote terminal (SSH)
$ xterm
xterm: Xt error: Can't open display: :0
I tried to do something like, but failed to work -
alias xterm="/bin/bash -c"
I don't want to have X forwarding and launch a window on my local machine as well.
If you just need the logs, you most likely don't need an X server or xterm.
You can simply run the target command itself. From your screenshot it looks like the command might be telnet 127.0.0.1 <port_number>. You can find it from the script that your application launches, or with ps -ef when it's running. If it's an UART, then you can also use minicom or socat to connect directly to serial port without any extra programs. This way, you don't even need telnet.
You can combine this command with either screen or tmux so that it's running in the background and you can switch to it from any terminal or console. Just run screen with no arguments, then run the command on virtual screen. Detach with CTRL-a d, and your command will continue to run in the background ready for you to reconnect to it at any time with screen -r.
Moreover, screen can also connect to serial port directly so you get two for the price of one.
The thing with xterm is that it will not write the logs anywhere except in the graphics buffer, and even there it will be only as flashing pixels which is not suitable for any processing. If you insist on going that way, you have several options:
Change the script that application runs (might not be possible depending on your situation)
Replace /usr/bin/xterm with your dummy script that just runs bash instead of xterm, and redirects the output to a file (ugly, but you could probably avoid breaking other applications by changing PATH and putting it somewhere else). In your script, you can use bash's redirection features such as >, or pipe output to tee.
Start a VNC server in the background and set the DISPLAY environment variable when you run your application to the number of virtual screen. In this case, any windows from application will open on VNC virtual screen and you can connect to it as you please.
Use xvfb as a dummy X server and combine it with xterm logging, etc.
Solution 1: Fake xterm on X11-less systems
You can also create a wrapper script that replaces xterm with another function. Test this out on a laptop with X11:
$ function xterm {
echo "hello $#"
}
$ xterm world 1
hello world 1
$ export -f xterm
$ /bin/xterm # opens a new xterm session
$ xterm world 2 # commands executed in second terminal
hello world 2
This means that you've replaced the command xterm for a function in all of the child processes.
Now, if you already know that your script will work in a terminal without xterm, you could create a function that accepts all of the parameters and executes it. No need for complicated screen stuff or replacing /usr/bin/xterm.
Solution 2: Dump UART data for the winz
If you want to save all of the uart data into a file, this is easily fixed by creating a screen session and a log file. Below the command will create a session named myscreensessionname that listens on the serial connection /dev/ttyUSB0 and writes its data to /home/$USER/myscreensessionname.log.
$ screen -dmS myscreensessionname -L -Logfile /home/$USER \
/myscreensessionname.log /dev/ttyUSB0 115200
Note that if you're going to use multiple screen sessions, you might want to use serial ids instead of /dev/ttyUSB0. You can identify the connections with udevadmin as follows.
$ udevadm info --name=/dev/ttyUSB0 | grep 'by-id'
S: serial/by-id/usb-FTDI_TTL232R-3V3_FTBDBIQ7-if00-port0
E: DEVLINKS=/dev/serial/by-id/usb-FTDI_TTL232R-3V3_FTBDBIQ7-if00-port0 /dev/serial/by-path/pci-0000:00:14.0-usb-0:4.4.4.1:1.0-port0
Here, instead of /dev/ttyUSB0, I would make use of /dev/serial/by-id/usb-FTDI_TTL232R-3V3_FTBDBIQ7-if00-port0.
EDIT:
You can attach the screen session with the following command. Once in the screen session, press crtl+a, and press d to detach.
$ screen -Dr myscreensessionname
To view all of your screen sessions:
$ screen -list
There is a screen on:
2382.myscreensessionname (04/02/2021 10:32:07 PM) (Attached)
1 Socket in /run/screen/S-user.

Pass command from scheduled script to program running in xterm window

I have a game server running in an xterm window.
Once daily I'd like to send a warning message to any players followed after a delay by the stop command to the program inside the xterm window from a script running on a schedule. This causes the cleanup and save functions to run automatically.
Once the program shuts down I can bring it back up easily but I don't know how to send the warning and stop commands first.
Typed directly into xterm the commands are:
broadcast Reboot in 2 minutes
(followed by a 2 minute wait and then simply):
stop
no / or other characters required.
Any help?
Do you also need to type something from the xterm itself (from time to time) or do you want your server to be fully driven from external commands?
Is your program line-oriented? You may first try something like:
mkfifo /tmp/f
tail -f /tmp/f | myprogram
and then try to send commands to your program (from another xterm) with
echo "mycommand" > /tmp/f
You may also consider using netcat for turning your program to a server:
Turn simple C program into server using netcat
http://lifehacker.com/202271/roll-your-own-servers-with-netcat
http://nc110.sourceforge.net/
Then you could write a shell script for sending the required commands to your "server".
If you know a little about C programming; I remember having once hacked the script program (which was very easy to do: code is short) in order to launch another program but to read commands from a FIFO file (then again a shell script would be easy to write for driving your program).
Something you might try is running your program inside a screen session.
You can then send commands to the session from cron that will be just
as if you typed them.
In your xterm, before launching the program do:
screen -S myscreen bash
(or you can even replace bash by your program). Then from your cron
screen -S myscreen -X stuff 'broadcast Reboot in 2 minutes\n'
sleep 120
screen -S myscreen -X stuff 'stop\n'
will enter that text. You can exit the session using screen -S myscreen -X quit
or by typing ctrl-a \.
screen is intended to be transparent. To easily see you are inside screen, you can
configure a permanent status bar at the bottom of your xterm:
echo 'hardstatus alwayslastline' >~/.screenrc
Now when you run screen you should see a reverse video bottom line. Depending
on your OS it may be empty.

read output from /dev/ttyUSB0

I am newbie in Linux, sorry if the question sounds too easy.
I have some communication with the board.
what i do first is:
enable the usb and gsm driver and cat "/dev/ttyUSB0 &"
afterwards, I send some AT commands and automatically get replies like "OK" and so on.
What I want is to able to READ this output using bash scripts, or any other possible ways
Thx
You can use screen command to read and write to the GSM. for eg. execute the command sudo screen /dev/ttyUSB0 , it will open a new screen their you can send data and see received data.

Buffered pipe in bash

I'm running a Bukkit (Minecraft) server on a Linux machine and I want to have the server gracefully shut down using the server's stop command and the computer suspend at a certain time using pm-suspend from the command line. Here's what I've got:
me#comp~/dir$ perl -e 'sleep [time]; print "stop\\n";' | ./server && sudo pm-suspend
(I've edited by /etc/sudoers so I don't have to enter my password when I suspend.)
The thing is, while the perl -e is sleeping, the server is expecting a constant stream of bytes, (That's my guess. I could be misunderstanding something.) so it prints out all of the nothings it receives, taking up precious resources:
me#comp~/dir$ ...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>...
Is there any such thing as a buffered pipe? If not, are there any ways to send delayed input to a script?
You may want to have a look at Bukkit's wiki, which recommends an init script for permanently running servers.
This init script uses rather unconventional approach to communicate with running server. The server is started in screen session, then all commands are send to the server console via screen, e.g.
screen -p 0 -S $SCREEN -X eval 'stuff \"stop\"\015'
See https://github.com/Ahtenus/minecraft-init/blob/master/minecraft
This approach suggest that bukkit may be expecting standard input to be attached to a terminal, thus requiring screen wrapper (which is itself terminal emulator) for unattended runs.

Resources