Skip to content

Commit 44ef6e8

Browse files
author
Seamus Connor
committed
Review feedback
1. `unset` -> `unset -v` 2. Forced a dynamic unset by calling unset from a child scope. Added a test.
1 parent 4985bb3 commit 44ef6e8

File tree

5 files changed

+42
-9
lines changed

5 files changed

+42
-9
lines changed

bash_completion

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,22 @@ dequote()
149149
eval printf %s "$1" 2>/dev/null
150150
}
151151

152+
# Unset the given variables across a scope boundary. Useful for unshadowing
153+
# global scoped variables. Note that simply calling unset on a local variable
154+
# will not unshadow the global variable. Rather, the result will be a local
155+
# variable in an unset state.
156+
# Usage: local IFS=$'|'; _comp_unlocal IFS
157+
# Param: $* Variable names to be unset
158+
_comp_unlocal()
159+
{
160+
local reset=$([[ ${BASH_VERSINFO[0]} -eq 5 ]] && {
161+
shopt -p localvar_unset
162+
shopt -u localvar_unset
163+
})
164+
unset -v "$@"
165+
$reset
166+
}
167+
152168
# Assign variable one scope above the caller
153169
# Usage: local "$1" && _upvar $1 "value(s)"
154170
# Param: $1 Variable name to assign value to
@@ -726,7 +742,7 @@ _comp_delimited()
726742
# Do not remove the last from existing if it's not followed by the
727743
# delimiter so we get space appended.
728744
[[ ! $cur || $cur == *"$delimiter" ]] || unset -v "existing[${#existing[@]}-1]"
729-
unset IFS
745+
_comp_unlocal IFS
730746
if ((${#COMPREPLY[@]})); then
731747
for x in ${existing+"${existing[@]}"}; do
732748
for i in "${!COMPREPLY[@]}"; do
@@ -1259,7 +1275,7 @@ else
12591275
local -a psout=($({
12601276
command ps ax -o command= || command ps ax -o comm=
12611277
} 2>/dev/null))
1262-
unset IFS
1278+
_comp_unlocal IFS
12631279
for line in "${psout[@]}"; do
12641280
if ((i == -1)); then
12651281
# First line, see if it has COMMAND column header. For
@@ -1816,7 +1832,7 @@ _known_hosts_real()
18161832
# spaces in their name work (watch out for ~ expansion
18171833
# breakage! Alioth#311595)
18181834
tmpkh=($(awk 'sub("^[ \t]*([Gg][Ll][Oo][Bb][Aa][Ll]|[Uu][Ss][Ee][Rr])[Kk][Nn][Oo][Ww][Nn][Hh][Oo][Ss][Tt][Ss][Ff][Ii][Ll][Ee][ \t=]+", "") { print $0 }' "${config[@]}" | sort -u))
1819-
unset IFS
1835+
_comp_unlocal IFS
18201836
fi
18211837
if ((${#tmpkh[@]} != 0)); then
18221838
local j
@@ -1872,7 +1888,7 @@ _known_hosts_real()
18721888
# Add host to candidates
18731889
COMPREPLY+=($host)
18741890
done
1875-
unset IFS
1891+
_comp_unlocal IFS
18761892
done <"$i"
18771893
done
18781894
((${#COMPREPLY[@]})) &&
@@ -2352,7 +2368,7 @@ __load_completion()
23522368
for dir in ${XDG_DATA_DIRS:-/usr/local/share:/usr/share}; do
23532369
dirs+=($dir/bash-completion/completions)
23542370
done
2355-
unset IFS
2371+
_comp_unlocal IFS
23562372
23572373
if [[ $BASH_SOURCE == */* ]]; then
23582374
dirs+=("${BASH_SOURCE%/*}/completions")

completions/7z

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ _7z()
5151
compopt -o filenames
5252
local IFS=$'\n'
5353
COMPREPLY=($(compgen -d -P${cur:0:2} -S/ -- "${cur:2}"))
54-
unset IFS
54+
_comp_unlocal
5555
$reset
5656
compopt -o nospace
5757
return

completions/_umount.linux

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,15 @@ _linux_fstab()
5555
__linux_fstab_unescape fs_label
5656
local IFS=$'\0'
5757
COMPREPLY+=("$fs_label")
58-
unset IFS
58+
_comp_unlocal
5959
fi
6060
else
6161
__linux_fstab_unescape fs_spec
6262
__linux_fstab_unescape fs_file
6363
local IFS=$'\0'
6464
[[ $fs_spec == */* ]] && COMPREPLY+=("$fs_spec")
6565
[[ $fs_file == */* ]] && COMPREPLY+=("$fs_file")
66-
unset IFS
66+
_comp_unlocal
6767
fi
6868
done
6969

completions/svcadm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ _smf_complete_fmri()
4646
# number of components
4747
local IFS="/"
4848
set -- $fmri
49-
unset IFS
49+
_comp_unlocal
5050
case $# in
5151
1) fmri_part_list=" $1" ;;
5252
2) fmri_part_list=" $2 $1/$2" ;;

test/t/test_bash.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,24 @@
11
import pytest
2+
import sys
23

4+
from conftest import assert_bash_exec
35

46
class TestBash:
57
@pytest.mark.complete("bash --", require_cmd=True)
68
def test_1(self, completion):
79
assert completion
10+
11+
def test_comp_unlocal(self, bash):
12+
# bash.logfile = sys.stderr
13+
cmd = ( 'foo() { '
14+
'local VAR=inner; '
15+
'_comp_unlocal VAR; '
16+
'echo $VAR; '
17+
'}; '
18+
'VAR=outer; foo; unset VAR foo; '
19+
)
20+
res = assert_bash_exec(bash, cmd, want_output=True).strip()
21+
assert res == "outer"
22+
23+
# assert_bash_exec(bash, '[[ $(shopt -p localvar_unset || true) != "shopt -u localvar_unset"]]')
24+
# assert_bash_exec(bash, 'shopt -u localvar_unset || true')

0 commit comments

Comments
 (0)