#16 Always execute commands and prelude in subshell
Opened by sorlov. Modified
sorlov/python-pytest-multihost prelude-in-subshell  into  master

Download 16.patch

Before the fix the prelude was executed in main shell and commands were
executed in nested shell only when they were passed as a string, not as a
list. There are two problems with this approach:
1. We can invoke run_command with argument ['false', ';', 'true'] which
is equivalent to 'false ; true' but the former will fail and later will
succeed which is confusing.
2. There are installations (particularly Cygwin) which have
/etc/bash.bash_logout containing invocation of "/usr/bin/clear".
This file is executed when user logs out. When run_command() send
"exit" command to remote shell, "clear" returns exit code 1 complaining
about TERM variable not being defined, which is normal for non-interactive
sessions. Without "set -e" option this is handled correctly and shell
returns result code of last executed user command. But with "set -e" shell
terminates prematurely and when user command succeeded we receive exit
status 1.

Executing "set -e" and user commands inside subshell solves both problems.

Can you add a test?

Note that running ['false', ';', 'true'] should not be equivalent to running 'false ; true'.
The former should run false with the arguments ';' and 'true' (which the false command will ignore); the ; should not be interpreted as a special character.
The latter should run the Bash command false ; true, where ; is interpreted as a command separator.

rebased onto 4a1158ca76de252f13b03ab6db2bb28901862416

About issue 1 -- I was wrong, now there is no difference in executing "false; true" or ['false', ';', 'true'], they both fail.

I have reworded the commit message to mention only problem with bash_logout script.

About the test - I do not see how I can test the fix without modifying /etc/bash.bash_logout or ~/.bash_logout which I guess is a bad idea...

Side note:
I agree that ['false', ';', 'true'] is not a proper way of using the function, but the way it is written now, there is no difference with "false ; true" besides spawning a subshell.

About the test - I do not see how I can test the fix without modifying /etc/bash.bash_logout or ~/.bash_logout which I guess is a bad idea...

It's not: set HOME to a temporary directory, and then modify $HOME/.bash_logout. You can even set $HOME from within the shell.

I agree that ['false', ';', 'true'] is not a proper way of using the function, but the way it is written now, there is no difference with "false ; true" besides spawning a subshell.

I suspect that might be right; the current implementation isn't ideal

rebased onto 867a5db84652074d406353f1c10145fe0d58a71b

rebased onto 5afbe576ac00494fa1df056b08de959543941f59

Thanks for idea about setting HOME variable.
I have added the test, it is passing with fix applied and expectedly failing with current version. Surprisingly it fails only with paramiko and passing with openssh.

Metadata