An old thread but this tripped me up as well…
Seems that the command_shell component executes the command in different ways dependent on whether the command contains templates/variables. If templates are detected then the component executes the command by calling create_subprocess_exec() whereas without templates it uses create_subprocess_shell() instead. The difference is that the former doesn’t process the file redirection whereas the later does. If using templates then you can avoid having to create a stand-alone shell script by passing the desired command in quotes to /bin/bash -c as follows:
shell_command:
shell1: /bin/bash -c "echo '{{ states.calendar.google.attributes.message }}' > ~/.homeassistant/output.txt"