Strange line feed behavior with ping command

Hello,

While testing ruby to execute external commands, i’m having a strange
behavior with some commands.

To give an example, I have a simple script which is echoing an external
command result.

I observe different behavior

— 1st test : DIR command —

-code- (just a simple echo) :
IO.popen(“dir”) do |f|
while line = f.gets
puts line;
end
end

-result- same as a regular dir executed as a commandline in windows
console :
D:\test>d:\temp\ruby-1.9\bin\ruby.exe test_dir.rb
Le volume dans le lecteur D s’appelle DONNEES
Le numéro de série du volume est C083-B188

Répertoire de D:\test

21/08/2012 13:25 .
21/08/2012 13:25 …
21/08/2012 13:22 temp
21/08/2012 13:24 84 test_dir.rb
21/08/2012 13:25 95 test_ping.rb
2 fichier(s) 179 octets
3 Rép(s) 13 118 869 504 octets libres

OK it works !

— 2nd test : PING command —

When I try to echo a simple ping localhost with the same script :
-code-
IO.popen(“ping localhost”) do |f|
while line = f.gets
puts line;
end
end

-result- I have a different output with annoying added line feeds which
are not visible in a regular command line :
D:\test>d:\temp\ruby-1.9\bin\ruby.exe test_ping.rb

Envoi d’une requête ‘ping’ sur PC43343 [127.0.0.1] avec 32 octets de
données :

Réponse de 127.0.0.1 : octets=32 temps<1ms TTL=128

Réponse de 127.0.0.1 : octets=32 temps<1ms TTL=128

Réponse de 127.0.0.1 : octets=32 temps<1ms TTL=128

Réponse de 127.0.0.1 : octets=32 temps<1ms TTL=128

Statistiques Ping pour 127.0.0.1:

  Paquets : envoyés = 4, reçus = 4, perdus = 0 (perte 0%),

Durée approximative des boucles en millisecondes :

  Minimum = 0ms, Maximum = 0ms, Moyenne = 0ms

Whereas a regular command line is more compact :
D:\test>ping localhost

Envoi d’une requête ‘ping’ sur PC43343 [127.0.0.1] avec 32 octets de
données :

Réponse de 127.0.0.1 : octets=32 temps<1ms TTL=128
Réponse de 127.0.0.1 : octets=32 temps<1ms TTL=128
Réponse de 127.0.0.1 : octets=32 temps<1ms TTL=128
Réponse de 127.0.0.1 : octets=32 temps<1ms TTL=128

Statistiques Ping pour 127.0.0.1:
Paquets : envoyés = 4, reçus = 4, perdus = 0 (perte 0%),
Durée approximative des boucles en millisecondes :
Minimum = 0ms, Maximum = 0ms, Moyenne = 0ms

-analysis- :

I have indeed many successive “\n” linefeeds :
-code-
output = IO.popen(“ping localhost”).readlines()
print output
-result-
["\n", “\n”, “Envoi d’une requ\x88te ‘ping’ sur PC43343 [127.0.0.1]
avec 32 oct
ets de donn\x82es\xFF:\n”, “\n”, “\n”, “\n”, “R\x82ponse de
127.0.0.1\xFF: octet
s=32 temps<1ms TTL=128\n”, “\n”, “R\x82ponse de 127.0.0.1\xFF:
octets=32 temps<1
ms TTL=128\n”, “\n”, "R\x82ponse de 127.0.0.1\xFF: octets=32 temps<1ms
TTL=128\n
", “\n”, “R\x82ponse de 127.0.0.1\xFF: octets=32 temps<1ms TTL=128\n”,
“\n”, “\n
“, “\n”, “Statistiques Ping pour 127.0.0.1:\n”, “\n”, "
Paquets\xFF: envoy\x8
2s = 4, re\x87us = 4, perdus = 0 (perte 0%),\n”, “\n”, “Dur\x82e
approximative d
es boucles en millisecondes :\n”, “\n”, " Minimum = 0ms, Maximum =
0ms, Moyen
ne = 0ms\n”, “\n”]

-notes-
. i have the same behavior if i use puts or print to echo on stdout.
. i have the same behavior too if i use other apis like popen2 /
popen3 (i tried many things even trying to change encoding mode but with
no success)
. i’m using ruby 1.9 on window XP profesionnal french

If you have any idea to explain such a behavior and any suggested
solution, i would be grateful.
Note : as i’m evaluating ruby as a scripting tool to write some system
scripts which will manipulate lots of input / output of external
commands, I don’t want to manipulate full output or line by line to
delete \n which is not a clean solution in my opinion - so solution MUST
be simple and easy :slight_smile: ?

thx by advance

On Tue, Aug 21, 2012 at 1:56 PM, Antoine P. [email protected]
wrote:

When I try to echo a simple ping localhost with the same script :
I have a different output with annoying added line feeds which
are not visible in a regular command line :

This likely has to do with Windows programs using \r\n as line
termination. Executing the Windows ping.exe:

irb(main):001:0> x=IO.popen [‘/cygdrive/c/Windows/system32/ping’,
www.google.de’], ‘r’ do |io| io.read end
=> “\r\nPinging www-cctld.l.google.com [173.194.69.94] with 32 bytes
of data:\r\nReply from 173.194.69.94: bytes=32 time=39ms
TTL=43\r\nReply from 173.194.69.94: bytes=32 time=38ms TTL=43\r\nReply
from 173.194.69.94: bytes=32 time=38ms TTL=43\r\nReply from
173.194.69.94: bytes=32 time=40ms TTL=43\r\n\r\nPing statistics for
173.194.69.94:\r\n Packets: Sent = 4, Received = 4, Lost = 0 (0%
loss),\r\nApproximate round trip times in milli-seconds:\r\n
Minimum = 38ms, Maximum = 40ms, Average = 38ms\r\n”
irb(main):002:0> x.each_line.to_a
=> [“\r\n”, “Pinging www-cctld.l.google.com [173.194.69.94] with 32
bytes of data:\r\n”, “Reply from 173.194.69.94: bytes=32 time=39ms
TTL=43\r\n”, “Reply from 173.194.69.94: bytes=32 time=38ms
TTL=43\r\n”, “Reply from 173.194.69.94: bytes=32 time=38ms
TTL=43\r\n”, “Reply from 173.194.69.94: bytes=32 time=40ms
TTL=43\r\n”, “\r\n”, “Ping statistics for 173.194.69.94:\r\n”, "
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),\r\n",
“Approximate round trip times in milli-seconds:\r\n”, " Minimum =
38ms, Maximum = 40ms, Average = 38ms\r\n"]
irb(main):003:0> x.each_line(“\r\n”).to_a
=> [“\r\n”, “Pinging www-cctld.l.google.com [173.194.69.94] with 32
bytes of data:\r\n”, “Reply from 173.194.69.94: bytes=32 time=39ms
TTL=43\r\n”, “Reply from 173.194.69.94: bytes=32 time=38ms
TTL=43\r\n”, “Reply from 173.194.69.94: bytes=32 time=38ms
TTL=43\r\n”, “Reply from 173.194.69.94: bytes=32 time=40ms
TTL=43\r\n”, “\r\n”, “Ping statistics for 173.194.69.94:\r\n”, "
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),\r\n",
“Approximate round trip times in milli-seconds:\r\n”, " Minimum =
38ms, Maximum = 40ms, Average = 38ms\r\n"]
irb(main):004:0> x.each_line(“\n”).to_a
=> [“\r\n”, “Pinging www-cctld.l.google.com [173.194.69.94] with 32
bytes of data:\r\n”, “Reply from 173.194.69.94: bytes=32 time=39ms
TTL=43\r\n”, “Reply from 173.194.69.94: bytes=32 time=38ms
TTL=43\r\n”, “Reply from 173.194.69.94: bytes=32 time=38ms
TTL=43\r\n”, “Reply from 173.194.69.94: bytes=32 time=40ms
TTL=43\r\n”, “\r\n”, “Ping statistics for 173.194.69.94:\r\n”, "
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),\r\n",
“Approximate round trip times in milli-seconds:\r\n”, " Minimum =
38ms, Maximum = 40ms, Average = 38ms\r\n"]
irb(main):005:0> x=IO.popen [‘/cygdrive/c/Windows/system32/ping’,
www.google.de’], ‘r’ do |io| io.each {|l| p l} end
“\r\n”
“Pinging www-cctld.l.google.com [173.194.69.94] with 32 bytes of
data:\r\n”
“Reply from 173.194.69.94: bytes=32 time=40ms TTL=43\r\n”
“Reply from 173.194.69.94: bytes=32 time=40ms TTL=43\r\n”
“Reply from 173.194.69.94: bytes=32 time=40ms TTL=43\r\n”
“Reply from 173.194.69.94: bytes=32 time=39ms TTL=43\r\n”
“\r\n”
“Ping statistics for 173.194.69.94:\r\n”
" Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),\r\n"
“Approximate round trip times in milli-seconds:\r\n”
" Minimum = 39ms, Maximum = 40ms, Average = 39ms\r\n"
=> #IO:(closed)

Note, this is with 1.9 installed from sources.

Kind regards

robert