### Summary

ansible-core 2.14.3 and 2.14.5 work flawlessly.

ansible-core 2.15.0 does not — the [command](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/command_module.html) and [shell](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/shell_module.html) modules never return in situations like those described here:

- iiab/iiab#3588

This has been confirmed on both Debian 11 (x86_64 VM) and 64-bit Raspberry Pi OS (Raspberry Pi 400).

Here's an example of ansible 2.15.0 freezing — as a result of the `./start_asterisk start` command (which works perfectly at the command-line, but no longer with ansible 2.15.0) never returning:

![image](https://github.com/ansible/ansible/assets/2458907/f8a0d89b-f038-4730-93d1-f6a0771fc9d7)

### Issue Type

Bug Report

### Component Name

command, shell

### Ansible Version

```console
$ ansible --version    # BAD VERSION

ansible [core 2.15.0]
  config file = /opt/iiab/iiab/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/ansible/lib/python3.9/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.9.2 (default, Feb 28 2021, 17:03:44) [GCC 10.2.1 20210110] (/usr/local/ansible/bin/python3)
  jinja version = 3.1.2
  libyaml = True

$ ansible --version    # GOOD VERSION

ansible [core 2.14.5]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/ansible/lib/python3.9/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.9.2 (default, Feb 28 2021, 17:03:44) [GCC 10.2.1 20210110] (/usr/local/ansible/bin/python3)
  jinja version = 3.1.2
  libyaml = True

$ ansible --version    # GOOD VERSION

ansible [core 2.14.3]
  config file = /opt/iiab/iiab/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/ansible/lib/python3.9/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.9.2 (default, Feb 28 2021, 17:03:44) [GCC 10.2.1 20210110] (/usr/local/ansible/bin/python3)
  jinja version = 3.1.2
  libyaml = True
```


### Configuration

```console
$ ansible-config dump --only-changed -t all

CONFIG_FILE() = /opt/iiab/iiab/ansible.cfg
INTERPRETER_PYTHON(/opt/iiab/iiab/ansible.cfg) = /usr/bin/python3

$ cat /opt/iiab/iiab/ansible.cfg

[defaults]
interpreter_python=/usr/bin/python3
```


### OS / Environment

This has been confirmed on both Debian 11 (x86_64 VM) and 64-bit Raspberry Pi OS (Raspberry Pi 400).

### Steps to Reproduce

Install Asterisk and then FreePBX onto Debian 11 as follows:

- https://github.com/iiab/iiab/blob/master/roles/pbx/tasks/asterisk.yml
- https://github.com/iiab/iiab/blob/master/roles/pbx/tasks/freepbx.yml

CLARIF: PHP 7.4 is required, so newer OS's will not work here.

### Expected Results

Running the exact same command at the prompt (Linux command-line) works.

Ansible should not freeze (the command or shell module never complete with 2.15.0 — unlike with 2.14.x).

### Actual Results

Unfortunately there's no error message, as ansible-core 2.15.0 freezes.

Whereas 2.14.3 and 2.14.5 work perfectly.

Please see details at:

- iiab/iiab#3588


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct
:kw before_communicate_callback: This function will be called
            after ``Popen`` object will be created
            but before communicating to the process.
            (``Popen`` object will be passed to callback as a first argument)
        :kw ignore_invalid_cwd: This flag indicates whether an invalid ``cwd``
            (non-existent or not a directory) should be ignored or should raise
            an exception.
        :kw handle_exceptions: This flag indicates whether an exception will
            be handled inline and issue a failed_json or if the caller should
            handle it.
        :returns: A 3-tuple of return code (integer), stdout (native string),
            and stderr (native string).  On python2, stdout and stderr are both
            byte strings.  On python3, stdout and stderr are text strings converted
            according to the encoding and errors parameters.  If you want byte
            strings on python3, use encoding=None to turn decoding to text off.
        '''
        
        self._clean = None
        if not isinstance(args, (list, binary_type, text_type)):
            msg = "Argument 'args' to run_command must be list or string"
            self.fail_json(rc=257, cmd=args, msg=msg)
        shell = False
        if use_unsafe_shell:
            
            if isinstance(args, list):
                args = b" ".join([to_bytes(shlex_quote(x), errors='surrogate_or_strict') for x in args])
            else:
                args = to_bytes(args, errors='surrogate_or_strict')
            
            if executable: