Problem with "echo ~ && sleep 0"

Ansible baby steps failure. Can’t even ‘-m ping’ ;-(
I’m a first time Ansible user and starting from the beginning.
The first real task from the Introduction to Ansible is a connectivity test.
After setting everything up the ping is bailing out on me with this generic error message:

    "msg": "MODULE FAILURE: No start of json char found\nSee stdout/stderr for the exact error",

After debugging I traced i down to

ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 monitor.lan "/bin/sh -c \\\\\'echo ~ && sleep 0\\\\\'"

That gives me a

/home/koos: 'echo: command not found

Changing this command to (notice the ‘ls’ at the end of the line)

ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 monitor.lan ls   
bin
tmp

makes it work. So the

/bin/sh -c \\\\\'echo ~ && sleep 0

seems to be the culprit.

I’m on openSUSE Leap 15.6 (both machines) with proper home directory, default shell = bash and ssh pubkey authentication. Ansible=15.6

How do I get to overcome level 1?

It may be helpful to tell us what Ansible command string you were running. Assuming that you are using the ping module, it should look like this:

➜  tmp ansible -i inventory -m ping serverb       
[WARNING]: Platform linux on host serverb is using the discovered Python interpreter at /usr/bin/python3.9, but future installation of another Python interpreter
could change the meaning of that path. See https://docs.ansible.com/ansible-core/2.17/reference_appendices/interpreter_discovery.html for more information.
serverb | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3.9"
    },
    "changed": false,
    "ping": "pong"
}

If you are invoking the command directly, something like this should be expected:

➜  tmp ansible -i inventory -m command -a 'uptime' serverb
[WARNING]: Platform linux on host serverb is using the discovered Python interpreter at /usr/bin/python3.9, but future installation of another Python interpreter
could change the meaning of that path. See https://docs.ansible.com/ansible-core/2.17/reference_appendices/interpreter_discovery.html for more information.
serverb | CHANGED | rc=0 >>
 18:15:02 up 10 days,  9:00,  1 user,  load average: 0.02, 0.02, 0.00

I ran the echo command to see if I can reproduce what you are getting, but I am not:

➜  tmp ansible -i inventory -m command -a 'echo hello' serverb 
[WARNING]: Platform linux on host serverb is using the discovered Python interpreter at /usr/bin/python3.9, but future installation of another Python interpreter
could change the meaning of that path. See https://docs.ansible.com/ansible-core/2.17/reference_appendices/interpreter_discovery.html for more information.
serverb | CHANGED | rc=0 >>
hello
1 Like

Apologies for the missing command. I’m running:

$ ansible -i inventory monitor.lan -m ping

The outcome is the same for root and non-root. I’ve tried it against other servers in my small home network. I’ve got the following node results:

  • Leap 15.4: OK
  • Leap 15.5: Fail
  • Leap 15.6: Fail
  • Leap 15.6: OK
  • Leap Micro 16.1: OK

I’m on a limb saying it’s a local openSUSE issue. I need to dig further. And I’ve got no idea yet where to look. But it’s good to know it could work :wink: Thanks for your help so far!

TL;DR
What OS are you logging into and as what user and what shell is that user configured with?

run grep $USER /etc/passwd

and the last item in the output should be your shell.

If the echo command is not found, you’re probably using a very limited shell on a system with very limited commands available or your PATH. Most shells will have echo as a builtin and most systems will also have /bin/echo as a command.

The user you are logging in with might have a high-security, limited shell for sftp access only or some other specific purpose shell. It could even be set to ‘/bin/true’ if the user is not intended for logins, but for running services only, like ‘www’.

1 Like

See earlier posts:

I’ve already increased the nodes tested against:

All users are regular users.
I did think of security settings. openSUSE is transitioning from AppArmor to SELinux, but if you install a default server/desktop, you’ll get the medium settings with lots of wiggle room. In fact the Leap 15.4 which works has AppArmor enabled. And the Leap Micro has SELinux enabled. So I’m doubting this is the root cause. But I’m not knowledgeable enough in that department to rule it out completely. I’m saying this as ‘echo’ is a shell built-in. I don’t know how that works security wise. May I should hack the command and try ‘/bin/echo’

Hmm… maybe I’m chasing a red herring with the ‘bash-sh-echo’ thing.
In the debug log of one of the failing nodes I’m seeing:

debug1: auto-mux: Trying existing master at \'/home/koos/.ansible/cp/e204b56f4e\'
debug2: fd 3 setting O_NONBLOCK
debug2: mux_client_hello_exchange: master version 4
debug3: mux_client_forwards: request forwardings: 0 local, 0 remote
debug3: mux_client_request_session: entering
debug3: mux_client_request_alive: entering
debug3: mux_client_request_alive: done pid = 10375
debug3: mux_client_request_session: session request sent
debug1: mux_client_request_session: master session id: 2
debug3: mux_client_read_packet_timeout: read header failed: Broken pipe
debug2: Received exit status from master 1
Shared connection to vmhost.lan closed.
')
<vmhost.lan> Failed to connect to the host via ssh: debug1: OpenSSH_10.0p2, OpenSSL 3.5.0 8 Apr 2025

Mind you, the earlier part of the log tells me it’s after a number of successful back-and-forths over the ssh channel!.
[https://stackoverflow.com/questions/7492872/git-push-hangs-after-a-few-pushes](Stackoverflow has a useful thread on this topic.)

Sorry, it’s a bit late. Super dumb question: Can you ssh into the target box without Ansible and run “echo foo”?

Super dumb question

Np. When it’s a bit late, dumb questions are forgiven :wink:

So the day before yesterday I tracked it down as a Python incompatibility between the Python version on the Ansible controller and the system wide Python version on the node.
[rant]
I hate it when there’s no obvious coverage of system requirements :frowning:
And also the incredible arcane error messages.
And the stupidity that an automation system is not able to figure out what the capabilities of a nod are.
[/rant]
I have it working now.

What was the difference that caused Ansible to fail?

The issue with the echo ~ && sleep 0 command in Ansible’s SSH connectivity test likely stems from a misconfigured shell environment or Python incompatibility on the target node. To resolve this, ensure the default shell on the target machine (monitor.lan) is correctly set to /bin/bash (verify with getent passwd ). Additionally, confirm that both the Ansible controller and the target node use compatible Python versions (e.g., Python 3.6+ for Ansible on openSUSE Leap 15.6). Update the Ansible configuration file (ansible.cfg) to specify the correct Python interpreter on the target with ansible_python_interpreter=/usr/bin/python3. Test connectivity with ansible all -m ping after making these changes.

The long version is that I’ve discoverd that Ansible tells you what it supports if you run
ansible-config list|grep -i python
On the drone node I had Python v3.6 from the distribution. I installed 3.11 along side. That solved everything on the controller node.

Thanks! See my other post for the final update.