Opened 15 years ago
Closed 15 years ago
#2646 closed defect (wontfix)
scripts should use printf instead of echo
Reported by: | tito_puentes | Owned by: | |
---|---|---|---|
Priority: | low | Milestone: | 6.7 |
Component: | Bootscripts | Version: | SVN |
Severity: | minor | Keywords: | echo printf POSIX |
Cc: |
Description
- POSIX doesn't define flags for echo, making the /bin/sh shebang misleading. This is notorious when using ksh or dash as /bin/sh.
- 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.
- 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)
Change History (11)
by , 15 years ago
Attachment: | lfs-bootscripts-20100124-no_echo-0.1.patch added |
---|
follow-up: 2 comment:1 by , 15 years ago
Priority: | normal → low |
---|---|
Severity: | major → minor |
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.
follow-up: 3 comment:2 by , 15 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.
- Even if it didn't add portability bonuses, it makes the functions less complicated and removes a potential dep on a binary.
- Ubuntu either uses the binary or doesn't use flags, because they use dash by default.
- Archlinux uses printf instead of echo.
follow-up: 4 comment:3 by , 15 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.
follow-up: 7 comment:4 by , 15 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.
follow-ups: 6 9 comment:5 by , 15 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.
comment:6 by , 15 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.
follow-up: 10 comment:7 by , 15 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 , 15 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...
comment:9 by , 15 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.
comment:10 by , 15 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
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.
use printf instead of echo