1

Is there any way to pass variable in subprocess? This didn't work.

subprocess.check_output(["cat test.txt | grep %s"], shell=True) %(variable)
user3270211
  • 915
  • 4
  • 20
  • 42
  • The `%` operator has to go after the string it is operating on. `"cat test.txt | grep %s"%variable` . You have got it off some place to the right. – khelwood Feb 19 '15 at 09:28

1 Answers1

1

You can use str.format:

"cat test.txt | grep {}".format(variable)

Or using old style formatting put the variable directly after.

"cat test.txt | grep %s"%variable

Your list is also redundant when using shell=True:

subprocess.check_output("cat fable.txt | grep %s" %variable, shell=True)

If you were using a list of args without shell = True, you could use Popen:

from subprocess import Popen,PIPE
p1 = Popen(["cat","text.txt"], stdout=PIPE)
p2 = Popen(["grep", variable], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()  
out,err = p2.communicate()
p1.wait()
print(out)
jfs
  • 399,953
  • 195
  • 994
  • 1,670
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
  • How will it work if I want to have multiple variables ? – user3270211 Feb 19 '15 at 09:48
  • multiple variables will be exactly the same, `"cat test.txt | grep {} {}".format(variable,variable2)`, same idea using "%s", I prefer str.format as I think it is more obvious. – Padraic Cunningham Feb 19 '15 at 09:49
  • thanks, another question, if I want to awk multiple colons of a command and put in multiple variables. Is there a simple way of doing that instead of running the subprocess for every varaible ? – user3270211 Feb 19 '15 at 10:03
  • can you give me an example? – Padraic Cunningham Feb 19 '15 at 10:04
  • @user3270211: to escape shell metacharacters such as `'\`$!`, you could use `pipes.quote(variable)`. `cat` is useless here, you could pass the file to `grep` directly: `output = check_output(['grep', variable, 'fable.txt'])` (note: no `shell=True`). It is also simple to implement `grep`-like functionality in pure Python (search a substring, use regexes, etc). – jfs Feb 19 '15 at 15:06
  • In general, to emulate `a | b` you could also use `b = Popen('b', stdin=PIPE, stdout=PIPE); a = Popen('a', stdout=b.stdin); out = b.communicate()[0]; a.wait()` – jfs Feb 19 '15 at 15:08
  • @J.F.Sebastian, thanks did not realize I missed the `.wait()`. – Padraic Cunningham Feb 19 '15 at 15:57