Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > gnu.bash.bug > #16382
| From | beluro@web.de |
|---|---|
| Newsgroups | gnu.bash.bug |
| Subject | hash -l with empty hash table prints to stdout |
| Date | 2020-06-15 22:47 +0200 |
| Message-ID | <mailman.1946.1592255765.2541.bug-bash@gnu.org> (permalink) |
| References | <20200615204717.GB28118@jar> |
Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -g -O2 -fdebug-prefix-map=/build/bash-2bxm7h/bash-5.0=. -fstack-protector-strong -Wformat -Werror=format-security -Wall -Wno-parentheses -Wno-format-security
uname output: Linux XXX 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2+deb10u1 (2020-06-07) x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu
Bash Version: 5.0
Patch Level: 3
Release Status: release
Description:
(I used `bashbug' from my distributor's pre-compiled package, but,
looking at the current bash source code, I strongly believe this
bug still exists, and you can completely ignore the "Configuration
Information" section above.)
`hash -l' is supposed to generate output that is reusable as input
(`help hash' says so, at least). In case the hash table is empty, a
string not re-usable as input is output to stdout. The exit code
indicates success in this case. The string being output is locale-
dependant (and therefore is hard to filter out in a work-around).
$ hash -r
$ hash -l
hash: hash table empty
$ echo $?
0
$ hash -l > /dev/null # no output, the message is printed to stdout
$ hash -l 2> /dev/null # the message is not printed to stderr
hash: hash table empty
A work-around bash function to save the current hash table (in a re-
usable format) would need to do something along these lines:
saved_hash_table() {
local hash_table="$( LANG=C hash -l )"
# Let's hope, the string for an empty hash table never changes...
[[ "$hash_table" =~ "hash table empty"$ ]] && hash_table=
printf %s "$hash_table"
}
Repeat-By:
$ LANG=C bash
$ hash -r
$ $( hash -l ) # should always succeed, I think
bash: hash:: command not found
$ echo $?
127
Even weirder after creating an actual script named "hash:" (note
trailing colon):
$ cat /usr/local/bin/hash:
#!/bin/sh
echo do harm
$ hash -r
$ $( hash -l )
do harm
Fix:
I've never looked at the bash sources before, but the conundrum
appears to be in line 138 in "bash-5.0/builtins/hash.def":
printf (_("%s: hash table empty\n"), this_command_name);
A bash script should be able to get a really re-usable output from
`hash -l', at least if the return code of `hash' indicates success.
So, either of the following changes should be applied:
1. (preferable, in my opinion) Output the message about the empty hash
table to stderr instead of stdout, that is, change the afore-mentioned
line to
fprintf (stderr, _("%s: hash table empty\n"), this_command_name);
Saving the hash table in a script would be something along
saved_hash_table="$( hash -l 2> /dev/null )" || handle_error
(not sure if any errors (needed to be handled in some cases) can
happen at all here).
2. Don't output anything (or a single newline-character only) in case
the hash table is empty. Saving the hash table would be simply:
saved_hash_table="$( hash -l )" || handle_error
with the draw-back of less informative output for interactive users.
3. Consider an empty hash table an error so at least something along
the following would work:
saved_hash_table="$( hash -l )" || saved_hash_table=
This possibly makes other errors hard to detect, though
`$saved_hash_table' would result in a loss of efficiency only, not in
malfunctioning software (or a security risk, my "do harm"-example is a
little lame, I confess, I currently don't quite see a real-life
exploitable security bug here), so ignoring a possible error (whatever
this should be) is probably a minor thing.
Back to gnu.bash.bug | Previous | Next | Find similar
hash -l with empty hash table prints to stdout beluro@web.de - 2020-06-15 22:47 +0200
csiph-web