Send text file, line by line, with netcat
Asked Answered
P

4

11

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?

Protozoon answered 20/12, 2012 at 10:14 Comment(6)
you want the lines to be separated by new line ?Ellora
Do you mean you want to open a separate connection per line?Isleana
Maybe the server has a different newline convention than Unix? If so, you need to convert the newlines to the codes the server expects.Schmooze
I want netcat to send the file divided by line, not in a unique file. But probably is the EoL, as @Schmooze said.Protozoon
TCP is a byte stream transport, it doesn't provide a way for the application to see the chunks that were transmitted. It can merge and split lines arbitrarily.Schmooze
It's not and EoL problem...I must divide the line before send it to netcat: read line -> netcat; read line -> netcat ....Protozoon
G
15

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
Goodwife answered 20/12, 2012 at 11:31 Comment(2)
I did a little script that do the while loop, so I can pass filename and host as parameters. Thanks!Protozoon
the first cat textfile > /dev/tcp/HOST/PORT is super cool. From the man bash, these type of files are either actually handled by the os, or bash emulates them.Cushitic
H
16

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:<[email protected]>
RCPT TO:<[email protected]>
DATA
From: [IES] <[email protected]>
To: <[email protected]>
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
Heliocentric answered 27/10, 2017 at 6:33 Comment(5)
I just got a downvote with no comment. Am I spreading misinformation? Surely not. Leave some feedback if you feel strongly enough to bury an answer.Heliocentric
Have an upvote from me, I had the same problem (but wanted to send UDP), your slowcat idea is exactly what I needed.Offal
Worked for what I needed; I wanted to send an HTTP request that was stored in a file. Just catting it to the netcat socket wouldn't work, i would get no response. This works flawlessly for me.Jambeau
@varfirstName yes, there are many protocols that are "conversational" and many implementations of those don't handle when they don't get a chance to speak. This is useful for all of those.Heliocentric
a thing of beauty, Internet stranger, thank you!Reception
G
15

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
Goodwife answered 20/12, 2012 at 11:31 Comment(2)
I did a little script that do the while loop, so I can pass filename and host as parameters. Thanks!Protozoon
the first cat textfile > /dev/tcp/HOST/PORT is super cool. From the man bash, these type of files are either actually handled by the os, or bash emulates them.Cushitic
C
5

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
Composure answered 8/3, 2016 at 2:6 Comment(0)
C
2

Just guessing here, but you probably CR-NL end of lines:

sed $'s/$/\r/' textfile | nc host port
Creodont answered 20/12, 2012 at 15:5 Comment(3)
Too many edits pending so i'll just say that depending on which nc OP and glenn here are using, they may not need sed at all. There's an option in one of the netcats (or maybe both, I only have the one handy), -c to force crlf line endings.Devaughn
This answer is 10 years old after all.Creodont
of course, but as a low-rep user i thought it might be better to say that I knew I should've just suggested the edit, but couldnt. There are plenty of old but occasionally updated answers. Not that this is quite so popular, but i like netcat so i wanted to give it some love.Devaughn

© 2022 - 2024 — McMap. All rights reserved.