diff --git a/homeassistant/components/shell_command.py b/homeassistant/components/shell_command.py index ca33666d1f377..10a6c350b7c89 100644 --- a/homeassistant/components/shell_command.py +++ b/homeassistant/components/shell_command.py @@ -68,8 +68,9 @@ def async_service_handler(service: ServiceCall) -> None: cmd, loop=hass.loop, stdin=None, - stdout=asyncio.subprocess.DEVNULL, - stderr=asyncio.subprocess.DEVNULL) + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + ) else: # Template used. Break into list and use create_subprocess_exec # (which uses shell=False) for security @@ -80,12 +81,19 @@ def async_service_handler(service: ServiceCall) -> None: *shlexed_cmd, loop=hass.loop, stdin=None, - stdout=asyncio.subprocess.DEVNULL, - stderr=asyncio.subprocess.DEVNULL) + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + ) process = yield from create_process - yield from process.communicate() - + stdout_data, stderr_data = yield from process.communicate() + + if stdout_data: + _LOGGER.debug("Stdout of command: `%s`, return code: %s:\n%s", + cmd, process.returncode, stdout_data) + if stderr_data: + _LOGGER.debug("Stderr of command: `%s`, return code: %s:\n%s", + cmd, process.returncode, stderr_data) if process.returncode != 0: _LOGGER.exception("Error running command: `%s`, return code: %s", cmd, process.returncode) diff --git a/tests/components/test_shell_command.py b/tests/components/test_shell_command.py index 6f993732c38e8..6aae786e042d4 100644 --- a/tests/components/test_shell_command.py +++ b/tests/components/test_shell_command.py @@ -149,3 +149,41 @@ def test_subprocess_error(self, mock_error, mock_call): self.assertEqual(1, mock_call.call_count) self.assertEqual(1, mock_error.call_count) self.assertFalse(os.path.isfile(path)) + + @patch('homeassistant.components.shell_command._LOGGER.debug') + def test_stdout_captured(self, mock_output): + """Test subprocess that has stdout.""" + test_phrase = "I have output" + self.assertTrue( + setup_component(self.hass, shell_command.DOMAIN, { + shell_command.DOMAIN: { + 'test_service': "echo {}".format(test_phrase) + } + })) + + self.hass.services.call('shell_command', 'test_service', + blocking=True) + + self.hass.block_till_done() + self.assertEqual(1, mock_output.call_count) + self.assertEqual(test_phrase.encode() + b'\n', + mock_output.call_args_list[0][0][-1]) + + @patch('homeassistant.components.shell_command._LOGGER.debug') + def test_stderr_captured(self, mock_output): + """Test subprocess that has stderr.""" + test_phrase = "I have error" + self.assertTrue( + setup_component(self.hass, shell_command.DOMAIN, { + shell_command.DOMAIN: { + 'test_service': ">&2 echo {}".format(test_phrase) + } + })) + + self.hass.services.call('shell_command', 'test_service', + blocking=True) + + self.hass.block_till_done() + self.assertEqual(1, mock_output.call_count) + self.assertEqual(test_phrase.encode() + b'\n', + mock_output.call_args_list[0][0][-1])