Are shell_command service calls blocking or non-blocking?

I know the answer for scripts, but not shell commands… I couldn’t find anything on this.

I was going to say blocking based on this:

https://www.home-assistant.io/integrations/shell_command/#execution

But that has confused me even more. What sensor?

Has this documentation perhaps been confused with the command line sensor?

1 Like

Copy and paste error I would guess. Definitely a bug if you want to submit it or PR a fix

1 Like

Will do.

EDIT: It looks like Frenk added that on purpose. https://github.com/home-assistant/home-assistant.io/pull/21065

I’ve asked in the Discord documentation channel.

1 Like

Just to clarify, you’re asking if the script waits for the shell command to complete before proceeding to the next step right? If so then yes it does.

At least to the best of its knowledge. I mean if you tried to use a command like this:

curl localhost:9200/do_something/async &

And tell it to run something async then idk what would happen. Maybe HA lets that do its thing async, maybe it kills all the child processes at a certain point. It lets python manage actually running the command so I don’t think its even up to HA exactly what happens here. Scripts can get complicated.

But if you run a normal script that does not try to create child processes then yes HA will wait for for it to complete before continuing on with its next task in the script or automation or whatever.

2 Likes

Thanks @tom_l and @CentralCommand.

The fact that you get a return code is indeed the hint.

I agree with the point on child processes: if you spawn forks and disown them or create daemon processes, then all bets would be off. I was thinking about “simple” (single process, foreground) executions.

My tests show that the shall_command service call is blocking but has a timeout (not documented) of 10 seconds.

alias: Workshop - Capture clip when cat detected
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.garage_motion_detector_occupancy
    to: "on"
    from: "off"
condition:
action:
  - service: light.turn_on
    data: {}
    target:
      entity_id: light.workshop_cam_flash
  - service: shell_command.workshop_esp32cam_mp4_script
    data: {}
  - service: light.turn_off
    data: {}
    target:
      entity_id: light.workshop_cam_flash
  - service: notify.telegram_pierre
    data_template:
      message: Miaou
      data:
        video:
          timeout: 180
          file: /config/www/cam_record/camera.workshop_cam.mp4
    enabled: false
mode: single

I wanted a sequencial suite of actions:

  1. Turn on flash
  2. Launch script with a shell_command to create a 10 sec mp4 from a esp32-cam
  3. Turn off flash
  4. Send mp4 to Telegram

What I get is:
12:39:04 Turn on flash
12:39:04 Script is started (seen timestamp in his log)
12:39.14 Turn off flash
12:39:14 Notification sent with an incomplete mp4 file (as the script is still running)
12:39:18 Script ended (seen timestamp in his log)

Looking at the trace of the automation, I see a “limit: 10”:

Executed: July 22, 2023 at 12:39:04
Result:
params:
  domain: shell_command
  service: workshop_esp32cam_mp4_script
  service_data: {}
  target: {}
running_script: false
limit: 10

I fully understand Home Assistant needs to set a limit to avoid pending script although, it would be good to be able to set this value (they could still hardcode a maximum value) or at least document it.

My test also shows that the script is not killed after the 10 sec timeout which defeats the reason why there would be a timeout.

I worked around it by enabling a folder watcher on the video folder and set yet another automation to send the video when the file watcher event “closed” fired for the video file.