0

Just a simple terminal session:

$ # the file really exists $ [[ -e mydir/564df455-92e6-ac59-9b96-b3665f2aa3c7.vmem ]] $ echo $? 0 $ # not with globbing though $ [[ -e mydir/*.vmem ]] $ echo $? 1 

The wildcard * is supposed to represent any number of characters. Hm.

What am I missing?

Update

compgen works as expected:

$ compgen -G "mydir/*.vmem"; echo $? 0 

However, I'd like to find out why the original attempt doesn't work. I want to learn Bash, not just get it to work and pass on. I checked: noglob is not set.

Update 2

According to @Aaron, this should (and does) work with the original test:

$ files=( mydir/*.vem ) $ [[ ${#files[@]} -gt 0 ]]; echo $? 0 

This version is actually easier to write and understand in my script function (where the question came up). The whole script is for syncing vmware to a backup folder on a time machine volume.

Using compgen:

# get the status of a vm # argument: path to the vm # compgen exit code: 0 - path(s) found, 1 - nothing found function vm_status() { local vm_path="$1" local status=-1 [[ $status -lt 0 ]] && { compgen -G "$vm_path/*.vmem" > /dev/null; } || { status=0; } # vm is shut down: vm does not contain file with extension .vmem [[ $status -lt 0 ]] && { compgen -G "$vm_path/*.vmss" > /dev/null; } && { status=1; } # vm is suspended: vm contains file with extension .vmss [[ $status -lt 0 ]] && { compgen -G "$vm_path/*.vmem.lck" > /dev/null; } && { status=2; } # vm is running: vm contains folder name ending with .vmem.lck echo $status # should return 0, 1 or 2 } 

Having to throw out the compgen output isn't needed with [[:

# get the status of a vm # argument: path to the vm function vm_status() { shopt -s nullglob # prevents non-matching glob from reporting one file (the glob itself) local vm_path="$1" local status=-1 [[ $status -lt 0 ]] && { files=( "$vm_path"/*.vmem ); } && [[ ${#files[@]} -gt 0 ]] || { status=0; } # vm is shut down: vm does not contain file with extension .vmem [[ $status -lt 0 ]] && { files=( "$vm_path"/*.vmss ); } && [[ ${#files[@]} -gt 0 ]] && { status=1; } # vm is suspended: vm contains file with extension .vmss [[ $status -lt 0 ]] && { files=( "$vm_path"/*.vmem.lck ); } && [[ ${#files[@]} -gt 0 ]] && { status=2; } # vm is running: vm contains folder name ending with .vmem.lck echo $status # should return 0, 1 or 2 } 
7
  • 2
    +1 for using the above duplicate, the syntax you're trying to use would fail in a number of cases. I don't know why it returned a non-zero exit code without raising an error in your current context though, unless globbing itself is turned of (set -o noglob) Commented Feb 13, 2021 at 17:17
  • I suggest to replace [[ -e mydir/*.vmem ]] with compgen -G mydir/*.vmem. Commented Feb 13, 2021 at 17:21
  • 1
    @Cyrus I think you'd want quotes around the glob, otherwise bash is going to expand it rather than passing it to compgen as text. Might work anyway, I'm not sure how compgen deals with lack of argument / multiple arguments. Commented Feb 14, 2021 at 8:54
  • @Aaron I had realized that after a while; I'll edit my update. Commented Feb 14, 2021 at 19:38
  • 1
    Ok, this is a behaviour specific to parsing [[ expression ]] ; from its section in man bash : "Word splitting and pathname expansion are not performed on words between [[ and ]]". Pathname expansion is what resolves globs Commented Feb 18, 2021 at 9:26

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.