Shell_command for PushingBox containing template fails with "return code: 3"

Hi,

for notification purposes I use this:

shell_command:
  notify_pushingbox_backup_warning: curl "http://api.pushingbox.com/pushingbox?devid=vXXXXXXXXXXXXXXX&last-backup={{ as_timestamp(state_attr('sensor.samba_backup', 'last_backup')) | timestamp_custom('%d.%m.%Y um %H:%M Uhr') }}"

This gives
2022-08-20 03:39:00 ERROR (MainThread) [homeassistant.components.shell_command] Error running command: curl “http://api.pushingbox.com/pushingbox?devid=vC51327A95EA1382&last-backup={{ as_timestamp(state_attr(‘sensor.samba_backup’, ‘last_backup’)) | timestamp_custom(’%d.%m.%Y um %H:%M Uhr’) }}”, return code: 3 in HA log file.

I use others like that as well where they usually only pass simple sensor states using `{{ states(‘sensor.sensor’) }}. This one uses a template.

That exact template works just fine

  • checking the templates in the dev section
  • using a notification service
    e. g. {{ as_timestamp(state_attr("sensor.samba_backup", "last_backup")) | timestamp_custom("%d.%m.%Y um %H:%M Uhr") }} gives 19.08.2022 um 02:39 Uhr.

So I suspect the shell_command having an issue with that template.

  • Are there known limitations with such templates inside a shell command?
  • What does the return code: 3 mean? Is it from HA or PushingBox?

Do shell commands maybe only offer limited templating?
Really no idea where to continue looking.

What about this from Shell Command - Home Assistant :

The commands can be dynamic, using templates to insert values for arguments. When using templates, shell_command runs in a more secure environment which doesn’t allow any shell helpers like automatically expanding the home dir ~ or using pipe symbols to run multiple commands. Similarly, only content after the first space can be generated by a template.

So is it maybe the pipe in my shell command which doesn’t work? Or does this part of the documentation only refer to the alias?

No idea? That’s a rare occurence around here, specially after more than two weeks :smiley: Seems like I (finally) found some special interest topic no one else can contribute something? :slight_smile:

The return code you’re getting is from Curl, not from HA. Return Code 3 means you’ve got a malformed URL in your request. In your case, you’ve got several spaces which are probably the cause of the error. If you want to use spaces you’ll need to encode them for URL: %20. However, you’ll also need to escape the % or your script will fail when it tries to resolve the variable 20.

Probably \%20, but I don’t have anything handy with which to test.

How to escape %?

An endless try and error is a bit annoying as those shell commands are only reloaded when HA is restarted… not dev section reload available :frowning_face:

I thought about running a script or creating an entity which contains the string I’d pass as argument to the curl so it is kind of “pre-generated” which works just fine as I’m using the same for many other similar shell_commands.

Anyway I’d like to avoid that extra complexity and just adapt the shell_command itself.

Unfortunately only extra output in HA log is NoneType: None which helps me none :smile:

Currently out of original
{{ as_timestamp(state_attr('sensor.samba_backup', 'last_backup')) | timestamp_custom('%d.%m.%Y um %H:%M Uhr') }}

I made
{{ as_timestamp(state_attr('sensor.samba_backup', 'last_backup')) | timestamp_custom('\%d.\%m.\%Y%20um%20\%H:\%M%20Uhr') }}

Not tested yet because of… no restart yet.

Update: tested now after HA restart. The shell command is working now with

shell_command:
  notify_pushingbox_backup_warning: curl "http://api.pushingbox.com/pushingbox?devid=vXXXXXXXXXXXXXX&last-backup={{ as_timestamp(state_attr('sensor.samba_backup', 'last_backup')) | timestamp_custom('\%d.\%m.\%Y%20um%20\%H:\%M%20Uhr') }}"

BUT the message contains just $last-backup instead of the actual content from between {{ ... }}.

Also that template without any exclusion attemps (so using {{ as_timestamp(state_attr('sensor.samba_backup', 'last_backup')) | timestamp_custom('%d.%m.%Y um %H:%M Uhr') }}) renders just fine in dev-tools template section, giving for example 09.04.2023 um 02:29 Uhr.

I am very sure that the escaping attempts made to the template make the shell_command to work, but the template to fail (using the template WITH escaping attempts in dev-tools template section it renders as nothing - no output).

How to fix this?


Edit: Enough struggle and wasted time with this annoying crap. Created a template sensor rendering the desired output and passing that sensor as parameter to the shell command which always worked fine for many other similar shell commands too.

If someone ever finds a way to template above stuff within a working shell_command (for PushingBox/similar curl based services), feel free to enlighten the rest of the world.

Update 2: Partied too early. Now even with

shell_command:
    notify_pushingbox_backup_warning: curl "http://api.pushingbox.com/pushingbox?devid=vXXXXXXXXXXXX&last-backup={{ states('sensor.samba_backup_last_backup_nice') }}"

the initial error

Logger: homeassistant.components.shell_command
Source: /usr/src/homeassistant/homeassistant/components/shell_command/__init__.py:115
Integration: Shell Command (documentation, issues)
First occurred: 19:43:08 (1 occurrences)
Last logged: 19:43:08

Error running command: `curl "http://api.pushingbox.com/pushingbox?devid=vXXXXXXXXXXXXX&last-backup={{ states('sensor.samba_backup_last_backup_nice') }}"`, return code: 3
NoneType: None

is back. It’s not the syntax, it’s very likely (still) the blank spaces in e. g. 09.04.2023 um 02:29 Uhr.

It seems to be just IMPOSSIBLE to find a solution for this. Argh…


@robbiecrash any idea? Your first (and only) post was quite helpful so far :+1:

First of all I’d need to be able to send the curl command from a command line because with the need for restarting HA on every change (shell_commands still not hot-reloadable, this really sucks!) it’s impossible to efficiently test escaping syntax.
If I try e. g. in the Visual Code addon, I get

curl: (3) nested brace in URL position 74:
http://api.pushingbox.com/pushingbox?devid=vC51327A95EA1382&last-backup={{ states('sensor.samba_backup_last_backup_nice') }}
                                                                         ^

Still unsolved.

Anyone with a solution pointing input on this? Still gives me a headache :frowning: