How can I close a netcat connection after a certain character is returned in the response?
Create a bash script called client.sh:
#!/bin/bashcat someFilewhile read FOO; do echo $FOO >&3 if [[ $FOO =~ `printf ".*\x00\x1c.*"` ]]; then break fidone
Then invoke netcat from your main script like so:
3>&1 nc -c ./client.sh somehost 1234
(You'll need bash version 3 for the regexp matching).
This assumes that the server is sending data in lines - if not you'll have to tweak client.sh so that it reads and echoes a character at a time.
How about this?
Client side:
awk -v RS=$'\x1c' 'NR==1;{exit 0;}' < /dev/tcp/host-ip/port
Testing:
# server side test scriptwhile true; do ascii -hd; done | { netcat -l 12345; echo closed...;}# Generate 'some' data for testing & pipe to netcat.# After netcat connection closes, echo will print 'closed...'# Client side:awk -v RS=J 'NR==1; {exit;}' < /dev/tcp/localhost/12345# Changed end character to 'J' for testing.# Didn't wish to write a server side script to generate 0x1C.
Client side produces:
0 NUL 16 DLE 32 48 0 64 @ 80 P 96 ` 112 p 1 SOH 17 DC1 33 ! 49 1 65 A 81 Q 97 a 113 q 2 STX 18 DC2 34 " 50 2 66 B 82 R 98 b 114 r 3 ETX 19 DC3 35 # 51 3 67 C 83 S 99 c 115 s 4 EOT 20 DC4 36 $ 52 4 68 D 84 T 100 d 116 t 5 ENQ 21 NAK 37 % 53 5 69 E 85 U 101 e 117 u 6 ACK 22 SYN 38 & 54 6 70 F 86 V 102 f 118 v 7 BEL 23 ETB 39 ' 55 7 71 G 87 W 103 g 119 w 8 BS 24 CAN 40 ( 56 8 72 H 88 X 104 h 120 x 9 HT 25 EM 41 ) 57 9 73 I 89 Y 105 i 121 y 10 LF 26 SUB 42 * 58 : 74
After 'J' appears, server side closes & prints 'closed...', ensuring that the connection has indeed closed.
Try:
(cat somefile; sleep $timeout) | nc somehost 1234 | sed -e '{s/\x01.*//;T skip;q;:skip}'
This requires GNU sed.
How it works:
{ s/\x01.*//; # search for \x01, if we find it, kill it and the rest of the line T skip; # goto label skip if the last s/// failed q; # quit, printing current pattern buffer :skip # label skip}
Note that this assumes there'll be a newline after \x01 - sed won't see it otherwise, as sed operates line-by-line.