Usage of nc -q with milliseconds - bash

NC -q option
I control my receiver over LAN using this command:
printf '$CMD\r\n' | nc 192.168.1.106 23
Receiver send response to command but netcat is already closed. If i use command:
printf '$CMD\r\n' | nc 192.168.1.106 23 -q 1
i get correct response, but 1 second lasts like forever. Tried some tricks like 0.1 or 100ms but i get error for invalid timer.
How can i force nc to wait for response or force it to wait small amount of time?

man is your friend:
$ man nc
«Options taking a time assume seconds. Append 'ms' for milliseconds,
's' for seconds, 'm' for minutes, or 'h' for hours (e.g. 500ms).»
edit: for nc 7.12

Related

Check for login activities of last 10 minutes (Actual time) in auth.log file?

I have a cronjob that executes a bash file every 10 min. The bash file contains a Curl command that sends me a sms if var/log/auth.log file contains any lines with "Accepted password for". (obviously the if condition is true every time).
Now i want to add another if condition that checks for string "Accepted password for" ONLY FOR LAST 10 MIN of time.
My problem is, the log file contains the time info like this:
Sep 5 13:49:07 localhost sshd[565]: Server listening on 0.0.0.0 port 22.
Nov 28 21:39:25 soft-server sshd[11946]: Accepted password for myusername from 10.0.2.2 port 13494 ssh2
How can I compare current time with above format and write an IF statement?
Currently i'm doing this:
if [ grep -q "Accepted password for" var/log/auth.log] && (check timing for last 10 min)
then
curl 'www.example.com/send-a-text'
fi
Thank you in advance.
The best way to compare times is to convert them to seconds from epoch, that way you can just treat them as integers. Here's an example:
#! /bin/bash
# time in seconds from epoch 10 minutes ago is the limit
limit="$(date -d '10 minutes ago' +%s)"
# read matches from the file starting from the end up to the limit
while read -r logrow; do
# cut out the timestamp from the logrow
timestamp="$(cut -d ' ' -f 1,2,3 <<<"$logrow")"
# convert timestamp to seconds from epoch
from_epoch="$(date -d "$timestamp" +%s)"
# if the line was newer than 10 minutes ago, send a message
if (( from_epoch > limit )); then
# send the logrow
curl "www.example.com/send-a-text?logrow=${logrow}"
else
# after reaching the limit, stop the loop
break
fi
done < <(tac /var/log/auth.log | grep "Accepted")

How to add something after a line grep found?

I would like to see whenever the ping to a specific server goes down.
So at the moment I have something like this: ping 8.8.8.8 | grep time=11 && date
This pings google and prints every line that has a ping of 11.x that is just for testing so that I have some output that is not there all the time but often enough that I can test this. And then I have && date that I thought would print the date when grep finds the string.. But it does not. So my question now Is how can I get it so that in every line that grep spits out I can append the current timestamp. Or what would be even better is to have it as a prefix in front of every line that grep spits out. Is this possible with one command? Or do I need a simple shell script?
Thanks in advance. I hope I get an answer soon. :)
Also merry x-mas to everyone!
See if it works for you:
ping 8.8.8.8 | while read line; do echo "$(date): $line"; done | grep time=13
You can also turn the setup around to check when a remote host becomes available by using while ! ping ... Example, in case your path to 8.8.8.8 goes down:
declare -i cnt=0; while ! ping -c 1 8.8.8.8; do ((cnt++)); echo "test '$cnt' - network down on $(date)"; sleep 60; done
Which will check once per-minute if the host 8.8.8.8 is available and report, for example:
test '10' - network down on Sat Dec 26 16:38:48 CST 2015
The script will terminate on its own once the network path is established.

Another parsing bash script output to variables

I know this has been asked before, and I have looked at the previous posts, but can't seem to get what I am trying to do working.
I know it's really basic, so I'm hoping this will be easy for most people on SO.
I want to create a simple bash script that pings an address, and then inserts the ping output into a csv file (or rather, into a file, separated with commas).
The ping command would be
ping -D google.com
and the output looks like
PING google.com (74.125.239.103) 56(84) bytes of data.
[1393992465.052723] 64 bytes from nuq05s01-in-f7.1e100.net (74.125.239.103): icmp_req=1 ttl=55 time=2.66 ms
I want to insert epoch time, ttl, and time into a file, separated by commas.
If it's easy enough, then it wouldn't hurt to convert to the epoch time to a date also, but this can be my next step in this simple project.
I figured out the command to convert epoch time to human format is
date -d #[epoch_time]
Side trivia - why do I need the #?
ping -D google.com | sed -n -e 2p -e 2q |
while read epoch b64 bytes from host ip icmp ttl time ms
do
date=$(date -d #$(sed 's/[][]//g' <<< "$epoch"))
ttl=$(sed 's/ttl=//' <<< "$ttl")
time=$(sed 's/time=//' <<< "$time")
echo "$date,$ttl,$time"
done >> file.csv
Clearly, you can extend the number of lines you analyze by adjusting the first sed command. You can probably do the editing within the loop with ${var/x/y} notation, but I don't think of doing that until I'm writing up at the end because I've spent longer working with shells where that wasn't an option than I have with bash. Are you sure you don't want the host or IP address information?
In the cold light of morning, there's an easy way to improve the code:
ping -D google.com | sed -n -e 2p -e 2q |
while read epoch b64 bytes from host ip icmp ttl time ms
do
epoch=${epoch#[}
epoch=${epoch%]}
date=$(date -d #${epoch})
echo "$date,${ttl#ttl=},${time#time=}"
done >> file.csv
It's a matter of choice whether you create the date variable or simply embed the $(date -d #${epoch}) directly in the echo argument.

Mac ping but only display avg ms

What I want is to ping a server but only want the avg time to be returned, I think grep or something like that would help but a google search doesn't return much useful.
This is to go into a geektool script that will display a servers ping for me to see if its up.
Needs to be a script / command that will work in terminal as I need to pull it over to python as well.
Thanks
Somehow on my system ping command doesn't output round-trip but rtt.
So this one is going to work better:
ping -q -c 5 google.com | tail -n 1 | cut -f 5 -d '/'
-q makes it less verbose because we don't need much of the output anyway. tail simply returns the last line of the output
How about something like:
ping -c 5 google.com | grep "round-trip" | cut -f 5 -d "/"

Send text file, line by line, with netcat

I'm trying to send a file, line by line, with the following commands:
nc host port < textfile
cat textfile | nc host port
I've tried with tail and head, but with the same result: the entire file is sent as a unique line.
The server is listening with a specific daemon to receive data log information.
I'd like to send and receive the lines one by one, not the whole file in a single shot.
How can I do that?
Do you HAVE TO use netcat?
cat textfile > /dev/tcp/HOST/PORT
can also serve your purpose, at least with bash.
I'de like to send, and receive, one by one the lines, not all the file in a single shot.
Try
while read x; do echo "$x" | nc host port; done < textfile
OP was unclear on whether they needed a new connection for each line. But based on the OP's comment here, I think their need is different than mine. However, Google sends people with my need here so here is where I will place this alternative.
I have a need to send a file line by line over a single connection. Basically, it's a "slow" cat. (This will be a common need for many "conversational" protocols.)
If I try to cat an email message to nc I get an error because the server can't have a "conversation" with me.
$ cat email_msg.txt | nc localhost 25
554 SMTP synchronization error
Now if I insert a slowcat into the pipe, I get the email.
$ function slowcat(){ while read; do sleep .05; echo "$REPLY"; done; }
$ cat email_msg.txt | slowcat | nc localhost 25
220 et3 ESMTP Exim 4.89 Fri, 27 Oct 2017 06:18:14 +0000
250 et3 Hello localhost [::1]
250 OK
250 Accepted
354 Enter message, ending with "." on a line by itself
250 OK id=1e7xyA-0000m6-VR
221 et3 closing connection
The email_msg.txt looks like this:
$ cat email_msg.txt
HELO localhost
MAIL FROM:<system#example.com>
RCPT TO:<bbronosky#example.com>
DATA
From: [IES] <system#example.com>
To: <bbronosky#example.com>
Date: Fri, 27 Oct 2017 06:14:11 +0000
Subject: Test Message
Hi there! This is supposed to be a real email...
Have a good day!
-- System
.
QUIT
Use stdbuf -oL to adjust standard output stream buffering. If MODE is 'L' the corresponding stream will be line buffered:
stdbuf -oL cat textfile | nc host port
Just guessing here, but you probably CR-NL end of lines:
sed $'s/$/\r/' textfile | nc host port

Resources