echo -ne "ATZ\r\n" > /dev/ttyUSB0
echo -ne "AT+CMGF=1\r\n" > /dev/ttyUSB0
echo -ne "AT+CMGS=\"888XXXXXXX\"\rhello\x1a\n" > /dev/ttyUSB0
Since CMS ERROR-96 is for mandatory information missing.
No, you cannot send AT commands in this way. Start by reading the V.250 (all of chapter 5) and 27.005 specifications (the AT+CMGS command), links are in the tag info page. Those documents will teach you a lot with regards to AT command handling, syntax and behaviour.
The worst mistake is to send AT command lines without waiting for the final result code. In the same way you would not write a HTTP client that totally ignores responses from the HTTP server, you should not send AT commands and totally ignore responses from the modem.
And for the AT+CMGS command you have to wait with sending the sms payload data until after you have received the "\r\n> " prefix (see the first part of this answer for details).
Other things, AT command lines should be terminated with \r only and not \r\n. Opening and closing the modem device over and over again like multiple shell command redirects will cause might be an issue. That totally depends on the specific modem, and there is no guarantee that this will work reliably.
To address these last points I wrote the atinout program to make sending AT command from the command line simple and reliable. The first two AT commands can be sent as
$ echo ATZ | atinout - /dev/ttyUSB0 -
ATZ
OK
$ echo AT+CMGF=1 | atinout - /dev/ttyUSB0 -
AT+CMGF=1
OK
$
or alternatively
$ echo ATZ > commands.txt
$ echo AT+CMGF=1 >> commands.txt
$ atinout commands.txt /dev/ttyUSB0 output.txt
but for AT+CMGS I guess you have to use expect for the time being (in the future atinout will have a companion program specifically for sending AT+CMGS).
Related
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.
Line by line works but in script it does not.
I tried everything i could think of.
This does not work in bash 2.05
{ sleep 1; echo "helo localhost"; sleep 1; echo "mail from: test#maillinux.net"; sleep 1; echo "rcpt to: user#actualdomain.org"; sleep 1; echo "data"; sleep 1; echo "subject: test"; echo; echo "some text" ;echo "."; echo "quit"; } | telnet mailserver.actualdomain.org 25
but if you do line by line
telnet mailserver.actualdomain.org 25
220...
helo localhost
250...ok
mail from: test#maillinux.net
250..ok
rcpt to: user#actualdomain.org
250...ok
data
354 Start mail input; end with <CRLF>.<CRLF>
subject: test
some text
.
quit
then it works and i get mail.
the script works in newer bash 4.4 but i need it to work in 2.05.
seems to me that it does not do echo "." et the end and does not finish mail...and therefore does not send it.
but why???
I expect it to send mail but it does not
This is probably a difference in the version of telnet, not the version of bash.
One common problem when using network tools in a pipeline like this is how they handle EOFs on stdin. What you need is behavior like this:
Your input is written to telnet's stdin
...while this is happening, telnet starts sending that input to the remote server...
Telnet's stdin is given an EOF (end-of-file). Some broken versions of telnet exit immediately at this point.
...telnet keeps sending everything it read from its stdin over to the remote server.
...telnet finishes sending everything it read to the remote server, and then closes the sending side of the socket (via a FIN packet)
...the server keeps sending content to the client until it's sent any responses that need to be done, and then the server closes its own side by sending another FIN
telnet prints everything it got prior to getting a FIN from the server. Completion of this step is when a correctly-written telnet actually exits.
As noted above, many versions of telnet that actually exist were written assuming they would be used by humans, not scripts. Instead of sending buffered content over the wire on receiving an EOF, and waiting to receive any responses from the server before shutting down the receive side, they just quit immediately the moment an EOF is seen.
You can work around it by adding a delay at the end.
It's an ugly hack, and better replaced with using tools that know how to shut down a socket correctly, but the cheap-and-dirty approach looks something like this:
{ ...; echo "."; echo "quit"; sleep 2; } | telnet mailserver.actualdomain.org 25
For new development, consider using a built-to-purpose tool like socat, or one of the many implementations of netcat.
socat's documented behavior explicitly makes it wait to finish sending content it received on its stdin, and printing responses it received over the socket, before exiting; insofar as it has a timeout on how long it waits for responses from the server, that timeout can be explicitly configured.
Agree with Charles, this must be a different version of telnet. And a few thoughts,
You can simply use expect and send commands to automate the telnet command,
#!/user/bin/expect
spawn telnet localhost 25 <<EOF
hello localhost
mail from: local#localhost
rcpet to: user#localhost
data
Some data
.
EOF
Or,
create a text file with the mail commands and use netcat (if the telnet doesn't support for stream input)
cat mailCmd.txt | nc localhost 25
The best and reliable way is to use a utility like socat or sendmail
sendmail user#localhost < "Emailcontent.txt"
In bash how can I issue a command to a running process I just started?
For example;
# Start Bluez gatttool then Connect to bluetooth device
gatttool -b $MAC -I
connect # send 'connect' to the gatttool process?
Currently my shell script doesn't get to the connect line because the gatttool process is running.
If you simply want to send the string "connect\n" to the process, you can use a standard pipe:
echo "connect" | gatttool -b $MAC -I
If you want to engage in a more complex "conversation" with the gatttool process, take a look at the expect (1) and chat (8) tool, which allow you to send a sequence of strings, and wait for certain responses.
If you'd prefer a slightly "lighter" way of piping you could use a heredoc such as in:
gatttool -b $MAC -I <<EOF
connect
(...)
EOF
Everything contained between the two EOF tags will be piped to the command's input. I believe this will not allow you to interact with the command whilst between the EOF tags so, as mentioned in the previous answer, you might want to consider using expect if you need to act upon the commands' output before sending something back to it.
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.
I have the following scenario:
I use netcat to connect to a host running telnet server on port 23, I log in using provided username and password, issue some commands, after which I need to do fairly complex analysis of the provided output. Naturally, expect comes to mind, with a script like this:
spawn nc host 23
send "user\r"
send "pass\r"
send "command\r"
expect EOF
then, it is executed with expect example.scr >output.log, so the output file can be parsed. The parser is 150+ lines of bash code that executes under 2 seconds, and makes a decision what command should be executed next. Thus, it replaces "command" with "command2", and executes the expect script again, like this:
sed -i '/send "command\r"/send "command2\r"/' example.scr
expect example.scr >output.log
Obviously, it is not needed to re-establish telnet connection and perform log in process all over again, just to issue a single telnet command after 2 seconds of processing. A conclusion can be made, that telnet session should be kept alive as a background process, so one could freely talk to it at any given time. Naturally, using named pipes comes to mind:
mkfifo in
mkfifo output.log
cat in | nc host 23 >output.log &
echo -e "user\npass\ncommand\n" >in
cat output.log
After the file is written to, EOF causes the named pipe to close, thus terminating the telnet session. I was thinking what kind of eternal process could be piped to netcat so it can be used as telnet relay to host. I came up with a very silly idea, but it works:
nc -k -l 666 | nc host 23 >output.log &
echo -e "user\npass\ncommand\n" | nc localhost 666
cat output.log
The netcat server is started with k(eep alive), listening on port 666, and any data stream is redirected to the netcat telnet client connected to the host, while the entire conversation is dumped to output.log. One can now echo telnet commands to nc localhost 666, and read the result from output.log.
One should keep in mind that the expect script can be easily modified to accommodate SSH and even serial console connection, just by spawning ssh or socat instead of netcat. I never liked expect because it forces a use of another scripting language within bash, requires tcl libraries, and needs to be compiled for the embedded platforms, while netcat is a part of busybox and readily available everywhere.
So, the question is - could this be done in a simpler way? I'd put my bet on having some sort of link between console and TCP socket. Any suggestions are appreciated.
How about using like a file descriptor?
exec 3<>/dev/tcp/host/port
while true; do
echo -e "user\npass\ncommand" >&3
read_response_generate_next_command <&3 >&3
# if no more commands, break;
done
exec 3>&-