1

In the below example, why do "[ 1]" and "[20]" split fine, but "[10000]" does not?

It appears to be converting the 10000 to 1 and dropping the brackets?

#!/bin/bash

var="[ 1]"
vararray=($var)
echo "var=${var}"
echo "vararray[0]=${vararray[0]}"

var="[20]"
vararray=($var)
echo "var=${var}"
echo "vararray[0]=${vararray[0]}"

var="[10000]"
vararray=($var)
echo "var=${var}"
echo "vararray[0]=${vararray[0]}"

Results...

$ ./bashtest.sh
var=[ 1]
ararray[0]=[
var=[20]
vararray[0]=[20]
var=[10000]
vararray[0]=1 << what?
PeterT
  • 920
  • 8
  • 20
  • What filenames exist in the current directory? In particular, is there a file named `1`? If so, unquoted expansion of `[1]`, `[01]`, `[abc1]`, etc. will run a glob and come up with that filename. – Charles Duffy Feb 16 '23 at 00:55
  • 2
    Note -- particularly in light of the above -- that `array=( $anything )` is considered an antipattern for good reason. The safe ways to split a string into an array is with `read -a`, `readarray`, `mapfile`, etc. See [BashPitfalls #50](https://mywiki.wooledge.org/BashPitfalls#hosts.3D.28_.24.28aws_.2BICY.29_.29) – Charles Duffy Feb 16 '23 at 00:56
  • 1
    [Shellcheck](https://www.shellcheck.net/) identifies the cause of the problem. Follow the links in the report for more information about the problem, and how to fix it. Also see [When to wrap quotes around a shell variable?](https://stackoverflow.com/q/10067266/4154375) and the [When Should You Quote?](https://mywiki.wooledge.org/Quotes#When_Should_You_Quote.3F) section of [Quotes - Greg's Wiki](https://mywiki.wooledge.org/Quotes) – pjh Feb 16 '23 at 01:36

1 Answers1

4

Presume that you have a file named 1 in your current directory. (This often happens unintentionally, f/e if someone wants to run 2>&1 but runs 2>1 instead by mistake).

[20] does not glob to 1 -- it globs only to 2 or 0.

[ 1], when run with the default IFS value, is word-split into [ and 1], neither of which is a valid glob, so expanding it unquoted doesn't perform any globbing operation at all.

However, [10000] -- just like [01] -- will glob to either 0 or 1, if a file by any of those names exists. In your example scenario, you clearly had a file named 1 in your current working directory.


Don't use unquoted expansion to split strings into arrays.

Instead, use read -r -a vararray <<<"$var", optionally after explicitly setting IFS to contain only the characters you want to split on.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441