Problem passing parameters to shell_command

So I know this has been talked about a bunch on other threads but nothing mentioned in those seem to be helping me. I’m trying to setup a shell_command for the first time and I can’t seem to get it to accept any parameters. The command does work without parameters though so I’m not sure what is going on.

I’ve defined the shell_command in my configuration.yaml file like this:

shell_command:
  show_toast_command: node C:\path\to\node\script\showToast.js {{ entity_id }}

I’ve then tried to run the command through the web UI under Developer Tools -> Services and provided the following Service Data (YAML):

entity_id: "foobar"

This then produces the following error in the logs:

2020-04-09 12:36:38 ERROR (MainThread) [homeassistant.components.shell_command] Error running command: `node C:\path\to\node\script\showToast.js {{ entity_id }}`, return code: 1
NoneType: None

So if I replace {{ entity_id }} with just a hard coded value and don’t provide any service data the service call works. It only errors as soon as I add that parameter. I have tried wrapping the whole command in single quotes too and that doesn’t seem to change anything.

Any ideas what could be wrong? I’m guessing it is something super simple but I can’t quite figure it out.

Try this (typically options that include templates need to be enclosed in quotes)

shell_command:
  show_toast_command: "node C:\path\to\node\script\showToast.js {{ entity_id }}"

With double quotes my configuration wouldn’t load. I have tried single quotes likes this:

shell_command:
  show_toast_command: 'node C:\path\to\node\script\showToast.js {{ entity_id }}'

This didn’t change anything. I get the same error.

where that {{ entity_id }} comes from? do you use lovelace_gen?

Ok, well either use a different key name or provide a real entity_id from your system. Also keep the single quotes.

Haven’t heard of lovelace_gen before. Quite new to everything here. Looks like it provides UI for generating configurations. I am handwriting my configuration.

I was just trying to use the Developer Tools and providting entity_id myself.

I’ve changed entity_id to now message.

This is what my full configuration looks like now:
configuration.yaml of my command:

shell_command:
  show_toast_command: 'node C:\path\to\node\script\showToast.js {{ message }}'

My actual automation is a webhook. This is what that looks like:

    
- id: show_toast
  alias: Show Toast
  trigger:
  - platform: webhook
    webhook_id: show_toast
  action:
  - service: shell_command.show_toast_command
    data_template:
      message: 'test'

I’ve hard-coded the message right now to just validate things are working. It would eventually be populated by data from the webhook.

Even running this (including triggering the webhook) this is what the logs look like:

2020-04-10 08:58:27 INFO (MainThread) [homeassistant.components.automation] Executing Show Toast
2020-04-10 08:58:27 INFO (MainThread) [homeassistant.components.automation] Show Toast: Running script
2020-04-10 08:58:27 INFO (MainThread) [homeassistant.components.automation] Show Toast: Executing step call service
2020-04-10 08:58:27 ERROR (MainThread) [homeassistant.components.shell_command] Error running command: `node C:\path\to\node\script\showToast.js {{ message }}`, return code: 1
NoneType: None

The service call you’re using should not have a data_template. Try just data:. The only other suggestion I have would be to put the message in an input_text and try {{states(“input_text.example”)}} instead of {{ message }}

It maybe that shell_command does not send along the data. The example in the documentation actually directly references the state of another entity

the only parameter shell_command supports is alias
but the main issue is your command is executed as-is and there is no attempt to parse a template…

UPDATE: I created a simple shell_command

shell_command:
  show_toast_command: 'ls -l {{ dir }}'

and when after setting log level of shell_command to debug

logger.set_level
homeassistant.components.shell_command: debug

I call it from Developer tools → Services with dir: '/' or dir: /config/ it works as expected (apart from always showing unexpanded template ls -l {{ dir }})

My command always return 0 and yours returns 1 (error).
If I pass an invalid argument though, it returns 1 and the error is exactly as yours.
So my advice is to run in console that node C:\path\to\node\script\showToast.js with a proper parameter and see if it works.

Thanks a ton! This is what helped me figure out the problem! This let me finally see what what actually being executed. Darn Windows! It seems when using parameters that the \ in my path were actually escaping characters and thus getting trimmed out. Escaping the \ characters did the trick. So my shell_command now looks like this:

shell_command:
  show_toast_command: 'node C:\\path\\to\\node\\script\\showToast.js {{ message }}'

Thanks for all the help everyone!

1 Like

Hurray!
I suspected it has something to do with Windows :wink:
Could you try this, just to get more insight?

show_toast_command: >
  node C:/path/to/node/script/showToast.js {{ message }}

Thanks for publishing the working code. Could you mark a solution post (you should have a Solution checkbox next to each post) so your topic appears as Solved and future readers could easily find the solution?

That did indeed also work. Thanks again!

that’s great so use forward slashes as you won’t need escape anything :wink:

I’m looking to set up a shell_command to run CATT, that I can pass player and video IDs through to as service data. Have struggled to find concrete steps from start to finish, but this thread seems like the closest thing. Based on the information here, I would have though this is the expected config:

configuration.yaml:

shell_command:
  cast_test_youtube_2: 'catt -d {{ player }} cast {{ video | urlencode }}'

Developer Tools > Services
Service:
shell_command.cast_test_youtube_2

Service Data:
player: "192.168.0.29"
video: "https://www.youtube.com/watch?v=W1ilCy6XrmI"

When I call the service, the HA logs show that the template doesn’t expand:

[homeassistant.components.shell_command] Stderr of command: `catt -d {{ player }} cast {{ video | urlencode }}`, return code: 1:
b'Error: The chosen file does not exist.\n

Trying to a better idea of what was going wrong, I also made some commands to echo into a test file:

shell_command:
  service_data_test_1: 'echo "hello world" >> /config/www/test.txt'
  service_data_test_2: 'echo {{ message }} >> /config/www/test.txt'

Calling Test 1 works as expected, but doesn’t produce any output in the logs. Test 2 gives a debug message:

[homeassistant.components.shell_command] Stdout of command: `echo {{ message }} >> /config/www/test.txt`, return code: 0:
b'test >> /config/www/test.txt\n

At this stage I feel like I’ve tried a million variants of double- single- and no-quotes in various positions in the command and service data. I can’t understand where this is going wrong, so any help would be appreciated :slight_smile:

1 Like