1

I've GUI where if i press a button "process" calls a python script which needs one command line argument. so i used subprocess.Popen like this:

subprocess.Popen(['chbif /home/vnandak/Work/VS30_Cradle/SV000_sv000/cradle_vs30_dkaplus01_fwd_dl140606_fem140704_v00_mod1.bif'],shell=True)

chbif is the alias for the .py script

This works fine but now i want to choose a file of my choice by browsing using askfilename() func from tkFileDailog() module. how can i do this?

I thought of doing it like this:

def bifcall():
        name13= askopenfilename()
        subprocess.Popen(['chbif', name13],shell=True)

But if i use this it throws an error saying that it does'nt have one more command line argument which is the file name

ayaan
  • 715
  • 5
  • 18
  • 36
  • Please show the full traceback. – falsetru Aug 11 '14 at 03:53
  • Usage: query_master_model filename.bif Note: 1. full path+filename should be specified. 2. [arg] means argument "arg" is optional. Rene Visser, Jan-2007 Last modified: Mar-2010 (using script: /nfzcae/all/femdb/tools/nvh/python/lib/analysis_manager/query_master_model.pyc) this is the error i get – ayaan Aug 11 '14 at 04:05
  • Traceback (most recent call last): File "/usr/local/python/2.7.3/lib/python2.7/lib-tk/Tkinter.py", line 1410, in __call__ return self.func(*args) File "/net/s019fc000110ge/mnt_home/vol/home6/vnandak/Python_scripts/remodelstage.py", line 290, in checkbif subprocess.Popen(['chbif' + extrafunc.name13],stdin=subprocess.PIPE,shell=False) File "/usr/local/python/2.7.3/lib/python2.7/subprocess.py", line 679, in __init__ errread, errwrite) File "/usr/local/python/2.7.3/lib/python2.7/subprocess.py", line 1249, in _execute_child raise child_exception OSError: [Errno 20] Not a directory – ayaan Aug 11 '14 at 04:17

2 Answers2

3

If you pass shell=True, the first argument should be a string, and it will be interpreted as the shell would interpret it. If shell=False, then the first argument should be a list, which sort of bypasses the shell.

Here's an answer to another question that explains it well: https://stackoverflow.com/a/15109975/451201

Community
  • 1
  • 1
jnrbsn
  • 2,498
  • 1
  • 18
  • 25
  • so if i use shell =False it should work tat's wat u say @ jnrbsn then i'll try that – ayaan Aug 11 '14 at 03:56
  • @ayaan It is customary to accept the best answer (in your opinion) by clicking the checkmark next to that answer when your problem has been solved. – jnrbsn Aug 11 '14 at 04:15
  • yeah sry i'll do that but still i get a trace back error that's what i'm figuring out – ayaan Aug 11 '14 at 04:19
  • @ayaan: If `shell=False`, it should be a list—but a list with each argument in its own string, not a list with one giant string in it. As it is, you're asking it to find a program named `'chbif /home/vnandak/Work/VS3…'` somewhere on the path, and run it with no arguments, which is obviously going to fail. – abarnert Aug 11 '14 at 06:01
1

Because if you use shell=True, you can only use one string as the first argument.

Try to change

subprocess.Popen(['chbif', name13],shell=True)

to

subprocess.Popen('chbif ' + name13,shell=True)

But it is not recommended to use shell=True for security reasons (See https://docs.python.org/2/library/subprocess.html#frequently-used-arguments for details).

Rikka
  • 999
  • 8
  • 19
  • Traceback (most recent call last): File "/usr/local/python/2.7.3/lib/python2.7/lib-tk/Tkinter.py", line 1410, in __call__ return self.func(*args) File "/net/s019fc000110ge/mnt_home/vol/home6/vnandak/Python_scripts/remodelstage.py", line 290, in checkbif subprocess.Popen(['chbif' + extrafunc.name13],stdin=subprocess.PIPE,shell=False) File "/usr/local/python/2.7.3/lib/python2.7/subprocess.py", line 679, in __init__ errread, errwrite) File "/usr/local/python/2.7.3/lib/python2.7/subprocess.py", line 1249, in _execute_child raise child_exception – ayaan Aug 11 '14 at 04:14
  • the above error trace back error is occuring when i chose the file @Rikka – ayaan Aug 11 '14 at 04:16
  • @ayaan In the callback, you are using shell=False and a string as the first argument in you Popen function, different from my code. BTW, if you want to use shell=True, you have to add a space after chbif to separate the executable and the arguments ('chbif ' + name13, shell=True). To make it clear, In Popen(), if you use shell=False, then you need a list as the 1st argument; if you use shell=False, then you need a string as the 1st argument. – Rikka Aug 11 '14 at 04:23
  • thankq very much for all it's working finally and i understood the concept very well @Rikka – ayaan Aug 11 '14 at 04:26
  • I would highly recommend using `shell=False` and then passing a list. It's more secure, because you don't have to worry about quoting the filename. Otherwise, you should use something like `pipes.quote` to prevent someone from trying something bad. – jnrbsn Aug 11 '14 at 04:28
  • I totally agree with you @jnrbsn .And ayaan , you can use shlex.split() to split you command in order to use the command with shell=False. – Rikka Aug 11 '14 at 04:31