diff --git a/homeassistant/components/command_line/sensor.py b/homeassistant/components/command_line/sensor.py index f7ae21ab704..feb63e18443 100644 --- a/homeassistant/components/command_line/sensor.py +++ b/homeassistant/components/command_line/sensor.py @@ -3,7 +3,6 @@ from collections.abc import Mapping from datetime import timedelta import json import logging -import shlex import subprocess import voluptuous as vol @@ -171,7 +170,7 @@ class CommandSensorData: pass else: # Template used. Construct the string used in the shell - command = str(" ".join([prog] + shlex.split(rendered_args))) + command = f"{prog} {rendered_args}" try: _LOGGER.debug("Running command: %s", command) return_value = subprocess.check_output( diff --git a/tests/components/command_line/test_sensor.py b/tests/components/command_line/test_sensor.py index ff3110f8e20..9d7e46002f6 100644 --- a/tests/components/command_line/test_sensor.py +++ b/tests/components/command_line/test_sensor.py @@ -70,6 +70,23 @@ class TestCommandSensorSensor(unittest.TestCase): assert data.value == "Works" + def test_template_render_with_quote(self): + """Ensure command with templates and quotes get rendered properly.""" + self.hass.states.set("sensor.test_state", "Works 2") + with patch( + "homeassistant.components.command_line.sensor.subprocess.check_output", + return_value=b"Works\n", + ) as check_output: + data = command_line.CommandSensorData( + self.hass, 'echo "{{ states.sensor.test_state.state }}" "3 4"', 15, + ) + data.update() + + assert data.value == "Works" + check_output.assert_called_once_with( + 'echo "Works 2" "3 4"', shell=True, timeout=15 # nosec # shell by design + ) + def test_bad_command(self): """Test bad command.""" data = command_line.CommandSensorData(self.hass, "asdfasdf", 15)