Skip to content

Commit

Permalink
Merge pull request #1502 from ltalirz/issue_1079_bash_login_shell
Browse files Browse the repository at this point in the history
Issue 1079 bash login shell
  • Loading branch information
ltalirz authored May 11, 2018
2 parents d3ebdf1 + 33ec4fb commit 07c83bc
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 17 deletions.
2 changes: 1 addition & 1 deletion .travis-data/code-setup-input.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ simple script that doubles a number and sleeps for a given number of seconds
False
simpleplugins.templatereplacer
torquessh
/usr/local/bin/doubler.sh
/usr/local/bin/d"o'ub ler.sh


4 changes: 2 additions & 2 deletions .travis-data/torquessh-doubler/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ MAINTAINER AiiDA Team <info@aiida.net>
# Use baseimage-docker's init system.
CMD ["/sbin/my_init"]

# Install required packages
COPY doubler.sh /usr/local/bin/


# Use messed-up filename to test quoting robustness
RUN mv /usr/local/bin/doubler.sh /usr/local/bin/d\"o\'ub\ ler.sh
5 changes: 5 additions & 0 deletions .travis-data/torquessh-doubler/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,8 @@
This folder contains an example of an extension of the torquessh-base image,
where we add a very basic script to double a number.
This is meant to be a very lightweight 'code' to test daemon functionality.

# Notes

Inside the docker image, we use a filename including single quotes, double
quotes and spaces in order to test the robustness of AiiDA's escaping routines.
20 changes: 14 additions & 6 deletions aiida/transport/plugins/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -704,21 +704,29 @@ def isfile(self, path):

def _exec_command_internal(self, command):
"""
Executes the specified command, first changing directory to the
current working directory as returned by self.getcwd().
Does not wait for the calculation to finish.
Executes the specified command in bash login shell.
Before the command is executed, changes directory to the current
working directory as returned by self.getcwd().
For a higher-level exec_command that automatically waits for the
job to finish, use exec_command_wait.
For executing commands and waiting for them to finish, use
exec_command_wait.
Otherwise, to end the process, use the proc.wait() method.
:param command: the command to execute
:param command: the command to execute. The command is assumed to be
already escaped using :py:func:`aiida.common.utils.escape_for_bash`.
:return: a tuple with (stdin, stdout, stderr, proc),
where stdin, stdout and stderr behave as file-like objects,
proc is the process object as returned by the
subprocess.Popen() class.
"""
from aiida.common.utils import escape_for_bash

# Note: The outer shell will eat one level of escaping, while
# 'bash -l -c ...' will eat another. Thus, we need to escape again.
command = 'bash -l -c ' + escape_for_bash(command)

proc = subprocess.Popen(command, shell=True, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
cwd=self.getcwd())
Expand Down
19 changes: 11 additions & 8 deletions aiida/transport/plugins/ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -1290,15 +1290,16 @@ def isfile(self,path):

def _exec_command_internal(self,command,combine_stderr=False,bufsize=-1):
"""
Executes the specified command, first changing directory to the
current working directory are returned by
self.getcwd().
Does not wait for the calculation to finish.
Executes the specified command in bash login shell.
Before the command is executed, changes directory to the current
working directory as returned by self.getcwd().
For a higher-level _exec_command_internal that automatically waits for the
job to finish, use exec_command_wait.
For executing commands and waiting for them to finish, use
exec_command_wait.
:param command: the command to execute
:param command: the command to execute. The command is assumed to be
already escaped using :py:func:`aiida.common.utils.escape_for_bash`.
:param combine_stderr: (default False) if True, combine stdout and
stderr on the same buffer (i.e., stdout).
Note: If combine_stderr is True, stderr will always be empty.
Expand All @@ -1324,7 +1325,9 @@ def _exec_command_internal(self,command,combine_stderr=False,bufsize=-1):
self.logger.debug("Command to be executed: {}".format(
command_to_execute))

channel.exec_command(command_to_execute)
# Note: The default shell will eat one level of escaping, while
# 'bash -l -c ...' will eat another. Thus, we need to escape again.
channel.exec_command('bash -l -c ' + escape_for_bash(command_to_execute))

stdin = channel.makefile('wb',bufsize)
stdout = channel.makefile('rb',bufsize)
Expand Down

0 comments on commit 07c83bc

Please sign in to comment.