Opened 14 years ago

Closed 14 years ago

#2646 closed defect (wontfix)

scripts should use printf instead of echo

Reported by: tito_puentes Owned by: lfs-book@…
Priority: low Milestone: 6.7
Component: Bootscripts Version: SVN
Severity: minor Keywords: echo printf POSIX
Cc:

Description

  1. POSIX doesn't define flags for echo, making the /bin/sh shebang misleading. This is notorious when using ksh or dash as /bin/sh.
  1. Forking to /bin/echo (assuming that the shell's builtin doesn't have the requirements, and that the binary is there in the first place) for every boot message is expensive and unnecesary.
  1. init.d/functions is now simplified and marginally faster since it does not need to determine echo's functionality every time that it is sourced.

Attachments (1)

lfs-bootscripts-20100124-no_echo-0.1.patch (6.2 KB ) - added by tito_puentes 14 years ago.
use printf instead of echo

Download all attachments as: .zip

Change History (11)

by tito_puentes, 14 years ago

use printf instead of echo

comment:1 by bdubbs@…, 14 years ago

Priority: normallow
Severity: majorminor

I don't think this is necessary. We never use echo with flags. We do used ECHO which is defined as /bin/echo which is defined in the functions.

The 'expensive' part is pretty much a non-starter. On a slow machine, how expensive is it (in microseconds)?

I don't know of any distros that don't use echo, but I only checked RH and Ubuntu.

Recommend closing as works for me, but I'll leave it open for other comments.

in reply to:  1 ; comment:2 by tito_puentes, 14 years ago

Replying to bdubbs@…:

I don't think this is necessary. We never use echo with flags. We do used ECHO which is defined as /bin/echo which is defined in the functions.

I don't think you've looked at the patch, nor at the lfs script themselves.

You use echo -ne, and not sparingly.

The 'expensive' part is pretty much a non-starter. On a slow machine, how expensive is it (in microseconds)?

Test it yourself?

time for i in $(seq 1 1000); do echo str >/dev/null; done

real 0m0.119s user 0m0.123s sys 0m0.000s

time for i in $(seq 1 1000); do /bin/echo str >/dev/null; done

real 0m2.403s user 0m0.000s sys 0m0.540s

I don't know of any distros that don't use echo, but I only checked RH and Ubuntu.

Recommend closing as works for me, but I'll leave it open for other comments.

  1. Even if it didn't add portability bonuses, it makes the functions less complicated and removes a potential dep on a binary.
  1. Ubuntu either uses the binary or doesn't use flags, because they use dash by default.
  1. Archlinux uses printf instead of echo.

in reply to:  2 ; comment:3 by bdubbs@…, 14 years ago

Replying to tito_puentes:

I don't think you've looked at the patch, nor at the lfs script themselves.

Yes I did for LFS, but not BLFS.

You use echo -ne, and not sparingly.

Only in the contrib directory.

time for i in $(seq 1 1000); do echo str >/dev/null; done

But echo is not called 1000 times in the bootscripts and never outside of 'functions' with an option. The overhead for the actual number calls are negligible. I'd like to see some opinions from others.

in reply to:  3 ; comment:4 by DJ Lucas, 14 years ago

Replying to bdubbs@…:

Replying to tito_puentes:

I don't think you've looked at the patch, nor at the lfs script themselves.

Yes I did for LFS, but not BLFS.

You use echo -ne, and not sparingly.

Only in the contrib directory.

No, we used '-e -n' everywhere. LFS installs coreutils, /bin/echo is always available and is checked every time functions is sourced. AFAICT, the stty sane bit can go, so we could put a lighter weight test case in each bootscript and source functions at each runlevel change to eliminate that, but on my system with ~30 bootscripts, this amounts to at most 15ms difference, (I'm guestimating here, with caching, the check never takes more than 0ms after the first invocation, which takes 1ms, so assuming the worst that every check takes 0.000499 seconds, 15ms). Going forward, printf is cleaner IMO, but is it a builtin on all shells? I didn't check, if not, then it's no different than echo in this case. If so, it'd make sense to use it going forward I suppose, but no sense in modifying current boot scripts for it. When I get free time again, maybe I'll do it in contrib just to see how it looks and feels in practice.

comment:5 by Matthew Burgess, 14 years ago

printf' is generally preferred to echo' for portability reasons. See http://www.gnu.org/software/hello/manual/autoconf/Limitations-of-Builtins.html#echo for the various portability issues around using `echo'.

In a default LFS install, bash provides both printf' and echo' as shell builtins so if we remove the '/bin/' prefix from our calls to echo then there's no speed difference at all between the two.

From a quick google, bash provides both printf and echo as builtins, as does zsh. csh, dash, ksh & tcsh all offer echo, but not printf.

I've got a preference for portability over speed here; the slowdown caused by not using a shell builtin is probably going to be less noticeable than the portability issues if someone does decide to use a shell other than Bash.

in reply to:  5 comment:6 by bon, 14 years ago

Replying to matthew@…:

printf' is generally preferred to echo' for portability reasons. See http://www.gnu.org/software/hello/manual/autoconf/Limitations-of-Builtins.html#echo for the various portability issues around using `echo'.

In a default LFS install, bash provides both printf' and echo' as shell builtins so if we remove the '/bin/' prefix from our calls to echo then there's no speed difference at all between the two.

From a quick google, bash provides both printf and echo as builtins, as does zsh. csh, dash, ksh & tcsh all offer echo, but not printf.

$ dash -c 'type printf' printf is a shell builtin

tcsh can't even read the script to begin with

I've got a preference for portability over speed here; the slowdown caused by not using a shell builtin is probably going to be less noticeable than the portability issues if someone does decide to use a shell other than Bash.

in reply to:  4 ; comment:7 by bon, 14 years ago

AFAICT, the stty sane bit can go, so we could put a lighter weight test case in each bootscript and source functions at each runlevel change to eliminate that

<snip>

are you saying you're going to source them once per runlevel?

then you'd have to export the functions, and export -f is a bashism

not to mention that exporting that many vars to begin with is bound to cause conflicts

comment:8 by bon, 14 years ago

well, freebsd sources them once per init change/direct call: http://www.freebsd.org/cgi/cvsweb.cgi/src/etc/rc.subr but don't have to pretend they conform to LSB ;)

and if you're checking out bsd stuff, please, try to run a bourne-compatible script with csh/tcsh. it wont work...

in reply to:  5 comment:9 by bdubbs@…, 14 years ago

Replying to matthew@…:

In a default LFS install, bash provides both printf' and echo' as shell builtins so if we remove the '/bin/' prefix from our calls to echo then there's no speed difference at all between the two.

We do that now. We only use /bin/echo if the test for arguments fails. For the default LFS install, the arguments do not fail and the builtin is used.

From a quick google, bash provides both printf and echo as builtins, as does zsh. csh, dash, ksh & tcsh all offer echo, but not printf.

Of course csh and tcsh are not compatible with our scripts in general, even though they do supply an echo builtin. If anyone changes the default /bin/sh->bash link in an LFS system to *anyhting* else, I'd think it would be up to that user to check the bootscripts.

I've got a preference for portability over speed here; the slowdown caused by not using a shell builtin is probably going to be less noticeable than the portability issues if someone does decide to use a shell other than Bash.

The portability issue is covered now. The speed of the scripts is not a noticeable issue. Recommend closing as wontfix.

in reply to:  7 comment:10 by DJ Lucas, 14 years ago

Resolution: wontfix
Status: newclosed

Replying to bon:

AFAICT, the stty sane bit can go, so we could put a lighter weight test case in each bootscript and source functions at each runlevel change to eliminate that

<snip>

are you saying you're going to source them once per runlevel?

then you'd have to export the functions, and export -f is a bashism

not to mention that exporting that many vars to begin with is bound to cause conflicts

You are correct, we cannot do the above and continue to use /bin/sh for the schebang. At any rate, as pointed out previously, the suggestion to use printf still does not account for all cases.

While I agree that printf could be both cleaner and simplify the scripts a bit, while also making the assumption that printf is consistent across all implementations, I have to agree with the others and close as wontfix as there is currently no portability issue.

When comparing apples to apples, we are discussing an estimated 3 second time deduction on even the oldest supported hardware (i486 running at 33MHz) in exchange for several hours worth of work (when you include the time required to test). The amount of work required is just far too much for such a minimal gain on scripts that I personally hope to see removed in the near future. Going forward, however, printf will be preferable for scripts using /bin/sh.

Note: See TracTickets for help on using tickets.