### Summary

When I try to install a role that contains files with `$` in their names (such as Java class names), it fails because we don't allow `$` in the file names because file names could get evaluated via `os.path.expandvars`.

See https://github.com/ansible/galaxy/issues/271 for the original context

The error message is "Not a directory" (errno 20).

### Issue Type

Bug Report

### Component Name

role

### Ansible Version

```console
$ ansible --version
ansible [core 2.14.5]
  config file = /Users/atsalolikhin/.ansible.cfg
  configured module search path = ['/Users/atsalolikhin/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/atsalolikhin/py-3.9.13/lib/python3.9/site-packages/ansible
  ansible collection location = /Users/atsalolikhin/.ansible/collections:/usr/share/ansible/collections
  executable location = /Users/atsalolikhin/py-3.9.13/bin/ansible
  python version = 3.9.13 (main, Jul 20 2022, 17:45:35) [Clang 13.0.0 (clang-1300.0.29.3)] (/Users/atsalolikhin/py-3.9.13/bin/python3.9)
  jinja version = 3.0.3
  libyaml = True
```


### Configuration

 N/A
 


### OS / Environment

N/A

### Steps to Reproduce


Add this to your `requirements.yaml`:

```yaml
- src: https://gitlab.com/atsaloli/ansible-galaxy-issue-271.git
  version: main
  scm: git
```

and then try to install roles, with e.g., `ansible-galaxy install -r requirements.yml`

### Expected Results

I expected the role to be installed.

### Actual Results

```console
The role install failed.


$ ansible-galaxy install -r requirements.yml --force
Starting galaxy role install process
- extracting ansible-galaxy-issue-271 to /home/atsaloli/.ansible/roles/ansible-galaxy-issue-271
[WARNING]: - ansible-galaxy-issue-271 was NOT installed successfully: Could not update files in /home/atsaloli/.ansible/roles/ansible-galaxy-issue-271:
[Errno 20] Not a directory: '/home/atsaloli/.ansible/roles/ansible-galaxy-issue-271/files/udf/CMC_VWAP.class'
ERROR! - you can use --ignore-errors to skip failed roles and finish processing the list.
$
```
```


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct
loose_versions = [LooseVersion(a.get('name', None)) for a in role_versions]
                        try:
                            loose_versions.sort()
                        except TypeError:
                            raise AnsibleError(
                                'Unable to compare role versions (%s) to determine the most recent version due to incompatible version formats. '
                                'Please contact the role author to resolve versioning conflicts, or specify an explicit role version to '
                                'install.' % ', '.join([v.vstring for v in loose_versions])
                            )
                        self.version = to_text(loose_versions[-1])
                    elif role_data.get('github_branch', None):
                        self.version = role_data['github_branch']
                    else:
                        self.version = 'master'
                elif self.version != 'master':
                    if role_versions and to_text(self.version) not in [a.get('name', None) for a in role_versions]:
                        raise AnsibleError("- the specified version (%s) of %s was not found in the list of available versions (%s)." % (self.version,
                                                                                                                                         self.name,
                                                                                                                                         role_versions))
                
                for role_version in role_versions:
                    if role_version['name'] == self.version and 'source' in role_version:
                        self.src = role_version['source']
                    if role_version['name'] == self.version and 'download_url' in role_version:
                        self.download_url = role_version['download_url']
                tmp_file = self.fetch(role_data)
        else:
            raise AnsibleError("No valid role data found")
        if tmp_file:
            display.debug("installing from %s" % tmp_file)