i am trying to source a shell script having functions. than trying to execute it like below.
source ~/abc.sh; abc arg1 arg2 arg3 arg4a
It works in unix shell. But when I am trying to execute same from inside python script it is giving error
def subprocess_cmd(command):
process = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
proc_stdout = process.communicate()[0].strip()
return proc_stdout
command = "bash -c source ~/abc.sh; abc arg1 arg2 arg3 arg4a"
out = subprocess_cmd(command)
print(out)
when i am executing above python code, it is giving below error.
~/abc.sh: line 0: source: filename argument required
source: usage: source filename [arguments]
/bin/sh: line 1: abc: command not found
CodePudding user response:
From Popen reference:
On POSIX with shell=True, the shell defaults to /bin/sh. If args is a string, the string specifies the command to execute through the shell. This means that the string must be formatted exactly as it would be when typed at the shell prompt. This includes, for example, quoting or backslash escaping filenames with spaces in them.
So what you're passing has to be passed as a single shell command.
When I run your single POSIX shell command in my shell:
$ bash -c source ~/abc.sh; abc arg1 arg2 arg3 arg4a
~/abc.sh: line 0: source: filename argument required
source: usage: source filename [arguments]
bash: abc: command not found
So there's nothing special about python here.
You get this error because this command amounts to:
- Original POSIX shell creates a new bash shell process
- New bash shell sources
abc.sh
- Command
abc
now available in the new bash shell - New bash shell terminates
- New bash shell sources
- Original POSIX shell tries to use command
abc
- Original POSIX shell terminates
What you want to do is:
- Original POSIX shell creates a new bash shell process
- New bash shell sources
abc.sh
- Command
abc
now available in the new bash shell - New bash shell tries to use command
abc
- New bash shell terminates
- New bash shell sources
- Original POSIX shell terminates
So you want the following 2 commands in the same shell:
source ~/abc.sh
abc arg1 arg2 arg3 arg4a
Namely:
bash -c 'source ~/abc.sh; abc arg1 arg2 arg3 arg4a'
(note where the single quotes are.)
In python:
def subprocess_cmd(command):
process = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
proc_stdout = process.communicate()[0].strip()
return proc_stdout
command = "bash -c 'source ~/abc.sh; abc arg1 arg2 arg3 arg4a'"
out = subprocess_cmd(command)
print(out)