Closed baelish closed 7 years ago
Thanks @quantumew
This isn't the real problem.
#!/usr/bin/env bash
set -eu
set -E &> /dev/null
set -o pipefail &> /dev/null
array=(one two three)
testNoIfs=("${array[@]:1}")
set | grep ^testNoIfs=
echo "testNoIfs[@]:" "${testNoIfs[@]}"
echo "testNoIfs[*]:" "${testNoIfs[*]}"
set | grep ^IFS=
IFS= testIfsEmpty=("${array[@]:1}")
set | grep ^testIfsEmpty=
echo "testIfsEmpty[@]:" "${testIfsEmpty[@]}"
echo "testIfsEmpty[*]:" "${testIfsEmpty[*]}"
set | grep ^IFS=
IFS=" " testIfsSpace=("${array[@]:1}")
set | grep ^testIfsSpace=
echo "testIfsSpace[@]:" "${testIfsSpace[@]}"
echo "testIfsSpace[*]:" "${testIfsSpace[*]}"
set | grep ^IFS=
Results:
testNoIfs=([0]="two" [1]="three")
testNoIfs[@]: two three
testNoIfs[*]: two three
IFS=$' \t\n'
testIfsEmpty=([0]="two" [1]="three")
testIfsEmpty[@]: two three
testIfsEmpty[*]: twothree
IFS=
testIfsSpace=([0]="two" [1]="three")
testIfsSpace[@]: two three
testIfsSpace[*]: two three
IFS=' '
You can see that the IFS is being set. Because the line doesn't contain a command to run, the IFS setting is committed to the environment instead of being reverted. In addition to this bug being not fixed by the proposed solution you provided, it is also not fixed by the solution I provided earlier.
Right fix:
oldIfs=$IFS
IFS=
array=("${array[@]:1}")
IFS=$oldIfs
Disgusting, but necessary. I'll start work on the fixes.
Just had a thought, would it be less disgusting to do:
IFS= ARGS=("${ARGS[@]:1}") :
Just tested it and it seems to work just fine too:
>cat /tmp/test.sh
#!/usr/bin/env bash
ARGS=("$@")
IFS=$' .\t,\n'
echo ":$IFS:"
IFS= ARGS=("${ARGS[@]:1}") :
echo "Args: ${ARGS[@]}"
echo ":$IFS:"
~
Tyrion$>bash /tmp/test.sh blah blah blah
: . ,
:
Args: blah blah blah
: . ,
:
>
The array itself (ARGS
) was not changed. When you use ("${ARGS[@]:1}")
the first "blah" should have been removed.
Bother....