Home > Software design >  python 3: How to source a bash script and run it in same shell
python 3: How to source a bash script and run it in same shell

Time:06-04

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
  • 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
  • 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)
  • Related