Discussion:
user/5862: spaces in output of wc(1) cause sanity check problems
j***@hklocal.nodeless.net
2008-07-01 01:58:07 UTC
Permalink
Number: 5862
Category: user
Synopsis: spaces in output of wc(1) cause sanity check problems
Confidential: yes
Severity: non-critical
Priority: low
Responsible: bugs
State: open
Class: change-request
Submitter-Id: net
Arrival-Date: Tue Jul 01 02:10:01 GMT 2008
Originator: jared rr spiegel
Release: -current
net
System : OpenBSD 4.3
Details : OpenBSD 4.3-current (GENERIC.MP) #770: Thu Jun 26 23:32:01 MDT 2008
***@i386.openbsd.org:/usr/src/sys/arch/i386/compile/GENERIC.MP

Architecture: OpenBSD.i386
Machine : i386
the extra spaces in front of wc(1)'s output are troublesome when
trying to write scripts that will fail if they encounter non-numeric
characters in strings that are expected to be numeric:

$ number_of_inet_sysctls=$(sysctl -a | fgrep inet | wc -l)
$ echo $number_of_inet_sysctls
111
$ echo X${number_of_inet_sysctls}X
X 111X
$ set | sed -ne /number_of_inet_sysctls/l
number_of_inet_sysctls=' 111'\n$

this is a problem when trying to do sanity checks like:

----
case $number_of_inet_sysctls in
"" | *[0-9]*)
printf '$number_of_inet_sysctls: "%s" contains non-numeric characters\n' "$number_of_inet_sysctls"
exit 1
;;
esac

# if we're here in the code we know for sure the
# param is numeric so it is totally safe to use in
# ``[ $param -lt whatever ]'' constructs
<...>
----

performing the sanity check like that is favourable in many
situations that i encounter because it is a very fast/inexpensive
check and i have not found it to ever be unsafe or inaccurate.
assign the output of wc(1) to a parameter via command substitution
get rid of the spaces in front. i don't know precisely
if this is how the GNU guys do it, but afaict, they don't have spaces
in front of wc(1)'s output.

--- wc.c.orig Mon Jun 30 21:47:55 2008
+++ wc.c Mon Jun 30 21:50:13 2008
@@ -247,9 +247,9 @@
char result[FMT_SCALED_STRSIZE];

(void)fmt_scaled(v, result);
- (void)printf("%7s", result);
+ (void)printf("%s", result);
} else {
- (void)printf(" %7lld", v);
+ (void)printf("%lld", v);
}
}



OpenBSD 4.3-current (GENERIC.MP) #770: Thu Jun 26 23:32:01 MDT 2008
***@i386.openbsd.org:/usr/src/sys/arch/i386/compile/GENERIC.MP
cpu0: AMD Athlon(tm) MP 2800+ ("AuthenticAMD" 686-class, 512KB L2 cache) 2.14 GHz
cpu0: FPU,V86,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE
real mem = 1072721920 (1023MB)
avail mem = 1029021696 (981MB)
mainbus0 at root
bios0 at mainbus0: AT/286+ BIOS, date 08/05/03, BIOS32 rev. 0 @ 0xfd6b0, SMBIOS rev. 2.3 @ 0xf0710 (31 entries)
bios0: vendor Phoenix Technologies Ltd. version "(null)" date 08/05/2003
bios0: Unknown Unknown
acpi0 at bios0: rev 0
acpi0: tables DSDT FACP APIC
acpi0: wakeup devices PCI0(S5) OP2P(S5) USB0(S1)
acpitimer0 at acpi0: 3579545 Hz, 24 bits
acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
cpu0 at mainbus0: apid 1 (boot processor)
cpu0: apic clock running at 266MHz
cpu1 at mainbus0: apid 0 (application processor)
cpu1: AMD Athlon(tm) MP 2800+ ("AuthenticAMD" 686-class, 512KB L2 cache) 2.14 GHz
cpu1: FPU,V86,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE
ioapic0 at mainbus0: apid 2 pa 0xfec00000, version 11, 24 pins
acpiprt0 at acpi0: bus 0 (PCI0)
acpiprt1 at acpi0: bus 1 (AGP_)
acpiprt2 at acpi0: bus 2 (OP2P)
acpicpu0 at acpi0
acpicpu1 at acpi0
acpibtn0 at acpi0: PWRB
bios0: ROM list: 0xc0000/0x10000 0xd0000/0x800 0xe0000/0x4000!
pci0 at mainbus0 bus 0: configuration mode 1 (no bios)
pchb0 at pci0 dev 0 function 0 "AMD 762 PCI" rev 0x20
ppb0 at pci0 dev 1 function 0 "AMD 762 PCI-PCI" rev 0x00
pci1 at ppb0 bus 1
vga1 at pci1 dev 5 function 0 "NVIDIA Riva TNT2 Ultra" rev 0x11
wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
wsdisplay0: screen 1-5 added (80x25, vt100 emulation)
agp0 at vga1: aperture at 0xf0000000, size 0x8000000
pcib0 at pci0 dev 7 function 0 "AMD 768 ISA" rev 0x05
pciide0 at pci0 dev 7 function 1 "AMD 768 IDE" rev 0x04: DMA, channel 0 configured to compatibility, channel 1 configured to compatibility
wd0 at pciide0 channel 0 drive 0: <WDC WD1600JB-00GVA0>
wd0: 16-sector PIO, LBA48, 152627MB, 312581808 sectors
wd1 at pciide0 channel 0 drive 1: <Maxtor 7Y250P0>
wd1: 16-sector PIO, LBA48, 239372MB, 490234752 sectors
wd0(pciide0:0:0): using PIO mode 4, Ultra-DMA mode 5
wd1(pciide0:0:1): using PIO mode 4, Ultra-DMA mode 5
wd2 at pciide0 channel 1 drive 0: <Maxtor 7H500R0>
wd2: 64-sector PIO, LBA48, 476940MB, 976773168 sectors
wd3 at pciide0 channel 1 drive 1: <Maxtor 7L300R0>
wd3: 16-sector PIO, LBA48, 286188MB, 586114704 sectors
wd2(pciide0:1:0): using PIO mode 4, Ultra-DMA mode 5
wd3(pciide0:1:1): using PIO mode 4, Ultra-DMA mode 5
amdpm0 at pci0 dev 7 function 3 "AMD 768 Power" rev 0x03
em0 at pci0 dev 8 function 0 "Intel PRO/1000 (82542)" rev 0x03: apic 2 int 20 (irq 5), address 00:03:47:08:f9:1b
em1 at pci0 dev 9 function 0 "Intel PRO/1000T (82543GC)" rev 0x02: apic 2 int 21 (irq 9), address 00:03:47:df:75:ee
ppb1 at pci0 dev 16 function 0 "AMD 768 PCI-PCI" rev 0x05
pci2 at ppb1 bus 2
ohci0 at pci2 dev 0 function 0 "AMD 768 USB" rev 0x07: apic 2 int 19 (irq 10), version 1.0, legacy support
eap0 at pci2 dev 6 function 0 "Ensoniq CT5880" rev 0x02: apic 2 int 18 (irq 11)
ac97: codec id 0x83847608 (SigmaTel STAC9708/11)
ac97: codec features 18 bit DAC, 18 bit ADC, SigmaTel 3D
audio0 at eap0
midi0 at eap0: <AudioPCI MIDI UART>
xl0 at pci2 dev 8 function 0 "3Com 3c905C 100Base-TX" rev 0x78: apic 2 int 19 (irq 10), address 00:e0:81:28:d2:c7
exphy0 at xl0 phy 24: 3Com internal media interface
usb0 at ohci0: USB revision 1.0
uhub0 at usb0 "AMD OHCI root hub" rev 1.00/1.00 addr 1
isa0 at pcib0
isadma0 at isa0
com0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo
com1 at isa0 port 0x2f8/8 irq 3: ns16550a, 16 byte fifo
pckbc0 at isa0 port 0x60/5
pckbd0 at pckbc0 (kbd slot)
pckbc0: using irq 1 for kbd slot
wskbd0 at pckbd0: console keyboard, using wsdisplay0
pmsi0 at pckbc0 (aux slot)
pckbc0: using irq 12 for aux slot
wsmouse0 at pmsi0 mux 0
pcppi0 at isa0 port 0x61
midi1 at pcppi0: <PC speaker>
spkr0 at pcppi0
lpt0 at isa0 port 0x378/4 irq 7
wbsio0 at isa0 port 0x2e/2: W83627HF rev 0x17
lm1 at wbsio0 port 0xc00/8: W83627HF
npx0 at isa0 port 0xf0/16: reported by CPUID; using exception 16
fdc0 at isa0 port 0x3f0/6 irq 6 drq 2
mtrr: Pentium Pro MTRR support
softraid0 at root
root on wd0a swap on wd0b dump on wd0b
in6_ifloop_request: DELETE operation failed for fe80:0006::0200:5eff:fe00:0115 (errno=3)
in6_ifloop_request: DELETE operation failed for fe80:0006::0200:5eff:fe00:0115 (errno=3)
in6_ifloop_request: DELETE operation failed for fe80:0006::0200:5eff:fe00:0115 (errno=3)
in6_ifloop_request: DELETE operation failed for fe80:0006::0200:5eff:fe00:0115 (errno=3)
in6_ifloop_request: DELETE operation failed for fe80:0006::0200:5eff:fe00:0115 (errno=3)
in6_ifloop_request: DELETE operation failed for fe80:0006::0200:5eff:fe00:0115 (errno=3)
in6_ifloop_request: DELETE operation failed for fe80:0007::0200:5eff:fe00:0116 (errno=3)
in6_ifloop_request: DELETE operation failed for fe80:0006::0200:5eff:fe00:0115 (errno=3)
in6_ifloop_request: DELETE operation failed for fe80:0007::0200:5eff:fe00:0116 (errno=3)
in6_ifloop_request: DELETE operation failed for fe80:0007::0200:5eff:fe00:0116 (errno=3)
in6_ifloop_request: DELETE operation failed for fe80:0007::0200:5eff:fe00:0116 (errno=3)
in6_ifloop_request: DELETE operation failed for fe80:0007::0200:5eff:fe00:0116 (errno=3)
in6_ifloop_request: DELETE operation failed for fe80:0007::0200:5eff:fe00:0116 (errno=3)
Otto Moerbeek
2008-07-02 14:35:01 UTC
Permalink
The following reply was made to PR user/5862; it has been noted by GNATS.

From: Otto Moerbeek <***@drijf.net>
To: ***@hklocal.nodeless.net
Cc: ***@openbsd.org, ***@ub3rgeek.net
Subject: Re: user/5862: spaces in output of wc(1) cause sanity check problems
Date: Wed, 2 Jul 2008 16:14:07 +0200
Post by j***@hklocal.nodeless.net
Number: 5862
Category: user
Synopsis: spaces in output of wc(1) cause sanity check problems
get rid of the spaces in front. i don't know precisely
if this is how the GNU guys do it, but afaict, they don't have spaces
in front of wc(1)'s output.
--- wc.c.orig Mon Jun 30 21:47:55 2008
+++ wc.c Mon Jun 30 21:50:13 2008
@@ -247,9 +247,9 @@
char result[FMT_SCALED_STRSIZE];
(void)fmt_scaled(v, result);
- (void)printf("%7s", result);
+ (void)printf("%s", result);
} else {
- (void)printf(" %7lld", v);
+ (void)printf("%lld", v);
}
}
I do not like to change this. It destroys neat multi-file output, and
it has been like this for ages. Even V7 Unix had it like this. BTW,
with a similar bug as you introduce in your diff, cookie for anyone
spotting the problem.

-Otto
Pierre Riteau
2008-07-02 15:03:42 UTC
Permalink
Post by Otto Moerbeek
The following reply was made to PR user/5862; it has been noted by GNATS.
Subject: Re: user/5862: spaces in output of wc(1) cause sanity check problems
Date: Wed, 2 Jul 2008 16:14:07 +0200
Post by j***@hklocal.nodeless.net
Number: 5862
Category: user
Synopsis: spaces in output of wc(1) cause sanity check problems
get rid of the spaces in front. i don't know precisely
if this is how the GNU guys do it, but afaict, they don't have spaces
in front of wc(1)'s output.
--- wc.c.orig Mon Jun 30 21:47:55 2008
+++ wc.c Mon Jun 30 21:50:13 2008
@@ -247,9 +247,9 @@
char result[FMT_SCALED_STRSIZE];
(void)fmt_scaled(v, result);
- (void)printf("%7s", result);
+ (void)printf("%s", result);
} else {
- (void)printf(" %7lld", v);
+ (void)printf("%lld", v);
}
}
I do not like to change this. It destroys neat multi-file output, and
it has been like this for ages. Even V7 Unix had it like this. BTW,
with a similar bug as you introduce in your diff, cookie for anyone
spotting the problem.
-Otto
With this diff there is no space between multiple values, e.g. when
using wc -cl or wc without flags.
--
Pierre Riteau
Otto Moerbeek
2008-07-02 15:13:31 UTC
Permalink
Post by Pierre Riteau
Post by Otto Moerbeek
Post by j***@hklocal.nodeless.net
--- wc.c.orig Mon Jun 30 21:47:55 2008
+++ wc.c Mon Jun 30 21:50:13 2008
@@ -247,9 +247,9 @@
char result[FMT_SCALED_STRSIZE];
(void)fmt_scaled(v, result);
- (void)printf("%7s", result);
+ (void)printf("%s", result);
} else {
- (void)printf(" %7lld", v);
+ (void)printf("%lld", v);
}
}
I do not like to change this. It destroys neat multi-file output, and
it has been like this for ages. Even V7 Unix had it like this. BTW,
with a similar bug as you introduce in your diff, cookie for anyone
spotting the problem.
-Otto
With this diff there is no space between multiple values, e.g. when
using wc -cl or wc without flags.
yep, though the V7 bug is more subtle. Check
http://minnie.tuhs.org/UnixTree/V7/usr/src/cmd/wc.c.html for an extra
cookie.

-Otto
Paul de Weerd
2008-07-03 23:05:02 UTC
Permalink
The following reply was made to PR user/5862; it has been noted by GNATS.

From: Paul de Weerd <***@weirdnet.nl>
To: ***@hklocal.nodeless.net
Cc: ***@openbsd.org, ***@ub3rgeek.net
Subject: Re: user/5862: spaces in output of wc(1) cause sanity check problems
Date: Fri, 4 Jul 2008 00:47:58 +0200

On Mon, Jun 30, 2008 at 09:58:07PM -0400, ***@hklocal.nodeless.net wrote:
| >Number: 5862
| >Category: user
| >Synopsis: spaces in output of wc(1) cause sanity check problems
| >Confidential: yes
| >Severity: non-critical
| >Priority: low
| >Responsible: bugs
| >State: open
| >Quarter:
| >Keywords:
| >Date-Required:
| >Class: change-request
| >Submitter-Id: net
| >Arrival-Date: Tue Jul 01 02:10:01 GMT 2008
| >Closed-Date:
| >Last-Modified:
| >Originator: jared rr spiegel
| >Release: -current
| >Organization:
| net
| >Environment:
|
| System : OpenBSD 4.3
| Details : OpenBSD 4.3-current (GENERIC.MP) #770: Thu Jun 26 23:32:01 MDT 2008
| ***@i386.openbsd.org:/usr/src/sys/arch/i386/compile/GENERIC.MP
|
| Architecture: OpenBSD.i386
| Machine : i386
| >Description:
|
| the extra spaces in front of wc(1)'s output are troublesome when
| trying to write scripts that will fail if they encounter non-numeric
| characters in strings that are expected to be numeric:
|
| $ number_of_inet_sysctls=$(sysctl -a | fgrep inet | wc -l)
| $ echo $number_of_inet_sysctls
| 111
| $ echo X${number_of_inet_sysctls}X
| X 111X
| $ set | sed -ne /number_of_inet_sysctls/l
| number_of_inet_sysctls=' 111'\n$

May I suggest using $(()) ?

$ number_of_inet_sysctls=$(($(sysctl -a | fgrep inet | wc -l)))
$ echo $number_of_inet_sysctls
107
$ echo X${number_of_inet_sysctls}X
X107X
$ set | sed -ne /number_of_inet_sysctls/l
number_of_inet_sysctls=107\n$

Seems like a UNIXy "workaround" to your problem to me.

Cheers,

Paul 'WEiRD' de Weerd

--
++++++++[<++++++++++>-]<+++++++.>+++[<------>-]<.>+++[<+
+++++++++++>-]<.>++[<------------>-]<+.--------------.[-]
http://www.weirdnet.nl/
jared rr spiegel
2008-07-04 19:45:01 UTC
Permalink
The following reply was made to PR user/5862; it has been noted by GNATS.

From: jared rr spiegel <***@hklocal.nodeless.net>
To: Paul de Weerd <***@weirdnet.nl>
Cc: ***@hklocal.nodeless.net, ***@openbsd.org, ***@ub3rgeek.net
Subject: Re: user/5862: spaces in output of wc(1) cause sanity check problems
Date: Fri, 4 Jul 2008 15:28:58 -0401
Post by Paul de Weerd
|
| the extra spaces in front of wc(1)'s output are troublesome when
| trying to write scripts that will fail if they encounter non-numeric
May I suggest using $(()) ?
i just throw a 'tr -d '[:space:]' in the pipeline, but the arithmetic
substitution one might work out too (it's quite likely lighter-weight).
Loading...