'/bin/sh: -c: line 0: syntax error near unexpected token `('

arg2 = f'cat <(grep \'#\' temp2.vcf) <(sort <(grep -v \'#\' temp2.vcf) | sortBed -i - | uniq ) > out.vcf'
print(arg2)
try:
    subprocess.call(arg2,shell=True)
except Exception as error:
    print(f'{error}')

While I'm running this I get the following error:

/bin/sh: -c: line 0: syntax error near unexpected token `('   
/bin/sh: -c: line 0: `cat <(grep '#' temp2.vcf) <(sort <(grep -v '#' temp2.vcf) | sortBed -i - | uniq ) > Out.vcf'

but when I run in the command line it works.



Solution 1:[1]

Python's call() function invokes the command with sh by default. The process substitution syntax is supported by bash, but not by sh.

$ sh -c "cat <(date)"  
sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `cat <(date)'

$ bash -c "cat <(date)"
Mon Mar 14 11:12:48 PDT 2022

If you really need to use the bash-specific syntax, you should be able to specify the shell executable (but I have not tried this):

subprocess.call(arg2, shell=True, executable='/bin/bash')

Solution 2:[2]

The immediate error is that your attempt uses Bash-specific syntax. You can work around that with an executable="/bin/bash" keyword argument; but really, why are you using a complex external pipeline here at all? Python can do all these things except sortBed natively.

with open("temp2.vcf", "r"
      ) as vcfin, open("out.vcf", "w") as vcfout:
    sub = subprocess.Popen(
        ["sortBed", "-i", "-"],
        text=True,
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE)

    for line in vcfin:
        if "#" in line:
            vcfout.write(line)
        else:
            sub.stdin.write(line)

    subout, suberr = sub.communicate()

    if suberr is not None:
        sys.stderr.write(suberr)

    seen = set()
    for line in subout.split("\n"):
        if line not in seen:
            vcfout.write(line + "\n")
        seen.add(line)

The Python reimplementation is slightly clunkier (and untested, as I don't have sortBed or your input data) but that also means it's more obvious where to change something if you want to modify it.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2