-1
# list=(`echo ".*"`)
# for item in ${list[@]}; do echo "$item"; done;
.
..
.DS_Store
.git
.gitignore
.tox
.toxrc

In the code above, I tried to write a string with .* into an array in bash, but after doing that, the ".*" will be converted to a full file/dir list in current dir. How can I stop bash from doing that?

LCB
  • 101

3 Answers3

3
list=(`echo ".*"`)

In the above, you have no quotes around the command substitution, so the resulting output is subject to word splitting and globbing.

for item in ${list[@]}; do echo "$item"; done;

Also, here, you have no quotes around ${list[@]}, so again, it's subject to word splitting and globbing. (This will matter if you add quotes to the assignment, or if any matching filenames contain whitespace or glob characters...)

If you just want the literal string .*, use list=(".*") and for item in "${list[@]}"; .... If you want to use the command substitution, put quotes around it, i.e. "$(somecmd)".

See also:

ilkkachu
  • 138,973
2

The echo … part in the backticks yields the (unquoted) string .*, which is subsequently expanded by BASH. If you don't want the ".*" to be expanded to a list of files, just use list=(".*"). However, I fail to see what the subsequent iteration over such an array would be good for.

TooTea
  • 2,388
  • 11
  • 15
  • This isn't quite accurate. It's not the echo ... which is performing the expansion. It's when going from the backticks to the array. The backticks output is unquoted (which you can't quote without causing other issues, though $() would work), thus it gets expanded before populating the array. However your solution is accurate (remove the backticks and echo entirely). – phemmer Jun 13 '18 at 12:21
  • You're right, the result of the backticks gets expanded. I got confused by the entirely useless echo there. – TooTea Jun 13 '18 at 13:26
2

From man bash, under options for set :

-f      Disable pathname expansion.

So issue

set -f

to disable globbing, and then

set +f

to re-enable normal globbing behavior.


Slightly longer relevant excerpt from the man page:

Pathname Expansion

After word splitting, unless the -f option has been set, bash scans each word for the characters *, ?, and [. If one of these characters appears, then the word is regarded as a pattern, and replaced with an alphabetically sorted list of file names matching the pattern.

user4556274
  • 8,995
  • 2
  • 33
  • 37
  • 3
    This is not a good solution. The right way to address the issue is to use proper declaration so that the shell doesn't want to expand it. E.G. list=(".*"), as in TooTea's answer. The echo and backticks are useless. – phemmer Jun 13 '18 at 12:24
  • @Patrick, I agree this is not a solution, as I am not clear on what the OP really wants to accomplish (XY). However it does answer the question in the title. Also, list=(".*") will also be expanded by bash if globbing is not disabled (apart from the echo subshell being useless). – user4556274 Jun 13 '18 at 13:03
  • 2
    "Also, list=(".*") will also be expanded by bash" -- This is incorrect. It will not. – phemmer Jun 13 '18 at 13:37