0

I need to call bash from python script and store result in the variable (the output is one number).

I need

output = subprocess.call('command', shell=True)

with command replaced by output from my bash one-liner which looks like this:

cat file.sam | grep -v "@" | grep "gi|519666810|ref|NM_001278619.1|"  | perl -lane '$l = 0; $F[5] =~ s/(\d+)[MX=DN]/$l+=$1/eg; print $l' | awk '{ sum+=$1} END {print sum}'

I know that simple commands work just fine:

    output = subprocess.check_output("echo 122;", shell=True)

My problem is that instead of 122 I need value from my bash one-liner. And it would be perfect if I didn't need to reformat it and could use it just as is.

Here are my attempts:

    output = subprocess.check_output("cat file.sam | grep -v "@" | grep "gi|519666810|ref|NM_001278619.1|"  | perl -lane '$l = 0; $F[5] =~ s/(\d+)[MX=DN]/$l+=$1/eg; print $l' | awk '{ sum+=$1} END {print sum}'
    ", shell=True)

      File "script.py", line 9
        output = subprocess.check_output("cat file.sam | grep -v "@" | grep "gi|519666810|ref|NM_001278619.1|"  | perl -lane '$l = 0; $F[5] =~ s/(\d+)[MX=DN]/$l+=$1/eg; print $l' | awk '{ sum+=$1} END {print sum}'
                                                                  ^
    SyntaxError: invalid syntax

Attempt two:

    output = subprocess.check_output("cat file.sam | grep -v \"@\" | grep \"gi|519666810|ref|NM_001278619.1|\"  | perl -lane '$l = 0; $F[5] =~ s/(\d+)[MX=DN]/$l+=$1/eg; print $l' | awk '{ sum+=$1} END {print sum}'
", shell=True)

  File "script.py", line 9

    output = subprocess.check_output("cat file.sam | grep -v \"@\" | grep \"gi|519666810|ref|NM_001278619.1|\"  | perl -lane '$l = 0; $F[5] =~ s/(\d+)[MX=DN]/$l+=$1/eg; print $l' | awk '{ sum+=$1} END {print sum}'
                                                                                                                                                                                                                    ^
SyntaxError: EOL while scanning string literal
8
  • 2
    I don't understand what your question is. Does it work for echo 122? What happens when you replace that with your actual command? Commented Mar 5, 2014 at 20:07
  • 2
    You need to break the bash command pipe down to individual commands for subprocess and then create the pipe with subprocess. But seriously, why not do this in python instead of messing with bash? Commented Mar 5, 2014 at 20:09
  • 2
    Here's something that might help you. Commented Mar 5, 2014 at 20:11
  • @Blorgbeard I edited my question to make it more clear, thanks Commented Mar 5, 2014 at 20:14
  • 1
    You missed a closing ") on your final attempt. Commented Mar 5, 2014 at 20:22

1 Answer 1

1

Thanks for help! Finally, this works:

command = "cat file.sam | grep -v \"@\" | grep \"gi|519666810|ref|NM_001278619.1|\"  | perl -lane '$l = 0; $F[5] =~ s/(\d+)[MX=DN]/$l+=$1/eg; print $l' | awk '{ sum+=$1} END {print sum}'";
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None, shell=True)
#Launch the shell command:
output = process.communicate()[0];
Sign up to request clarification or add additional context in comments.

1 Comment

I realize that this code is terse, but using subprocess with shell=True is bad practice -- it's very much the equivalent of using eval in bash, with all the same attendant security and correctness concerns. The Right Thing, long though it may be, is to specify the argv for each pipeline element in a separate Popen object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.