10

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?

d-cubed
  • 1,034
  • 5
  • 30
  • 58
Possa
  • 2,067
  • 7
  • 20
  • 22
  • you want the lines to be separated by new line ? – Shamis Shukoor Dec 20 '12 at 10:23
  • 1
    Do you mean you want to open a separate connection per line? – Fred Foo Dec 20 '12 at 10:30
  • Maybe the server has a different newline convention than Unix? If so, you need to convert the newlines to the codes the server expects. – Barmar Dec 20 '12 at 10:33
  • I want netcat to send the file divided by line, not in a unique file. But probably is the EoL, as @Barmar said. – Possa Dec 20 '12 at 10:36
  • 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. – Barmar Dec 20 '12 at 10:38
  • It's not and EoL problem...I must divide the line before send it to netcat: read line -> netcat; read line -> netcat .... – Possa Dec 20 '12 at 10:40

4 Answers4

14

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
anishsane
  • 20,270
  • 5
  • 40
  • 73
  • I did a little script that do the while loop, so I can pass filename and host as parameters. Thanks! – Possa Dec 20 '12 at 12:40
  • 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. – math2001 Dec 06 '20 at 07:09
14

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
Bruno Bronosky
  • 66,273
  • 12
  • 162
  • 149
  • 1
    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. – Bruno Bronosky May 01 '18 at 14:21
  • 1
    Have an upvote from me, I had the same problem (but wanted to send UDP), your slowcat idea is exactly what I needed. – Guntram Blohm Jul 03 '19 at 13:06
  • 1
    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. – var firstName Sep 18 '19 at 15:47
  • @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. – Bruno Bronosky Sep 19 '19 at 16:20
  • 1
    a thing of beauty, Internet stranger, thank you! – tony ennis Aug 18 '22 at 16:31
4

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
Jirka
  • 365
  • 2
  • 8
2

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

sed $'s/$/\r/' textfile | nc host port
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • 1
    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. – Chrstfer CB Mar 14 '23 at 16:01
  • 1
    This answer is 10 years old after all. – glenn jackman Mar 14 '23 at 16:12
  • 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. – Chrstfer CB Aug 05 '23 at 16:07