1

I have a file with a .run extension, e.g. myfile.run. It is executable, i.e. the permission level has been correctly set.

In a Linux terminal, I can execute it simply by submitting ./myfile.run.

In Python 3.6, I tried executing this same file using the subprocess.run() function but have not been successful. :( I tried:

result = subprocess.run( ['./home/user1/myfile.run'], stdout=subprocess.PIPE )
Traceback (most recent call last):
  File "<pyshell#51>", line 1, in <module>
    result = subprocess.run( [a], stdout=subprocess.PIPE )
  File "/usr/lib/python3.6/subprocess.py", line 423, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/lib/python3.6/subprocess.py", line 729, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.6/subprocess.py", line 1364, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
NotADirectoryError: [Errno 20] Not a directory: './home/user1/myfile.run'

I tried:

result = subprocess.run( ['/home/user1/myfile.run'], stdout=subprocess.PIPE )

and

result = subprocess.run( '/home/user1/myfile.run', stdout=subprocess.PIPE, shell=True ) 

Nothing happened.

What is the correct subprocess.run() syntax that I should use? Thanks.

Sun Bear
  • 7,594
  • 11
  • 56
  • 102
  • What do you mean "nothing happened"? Does `myfile.run` output things, and have you checked `result`? – wizzwizz4 Jul 30 '19 at 10:29
  • @wizzwizz4 There were no error msg. The file is suppose to copy/install a bunch of file to another directory. But nothing happened? – Sun Bear Jul 30 '19 at 10:33
  • what os.stat(path) says ? – napuzba Jul 30 '19 at 10:33
  • @SunBear Have you checked all the directories remotely to do with what you're trying to do? (Also, does the program require `sudo`?) – wizzwizz4 Jul 30 '19 at 10:35
  • No sudo required. File only requires user permission to execute it and does a local install/copying of files. – Sun Bear Jul 30 '19 at 10:38
  • @napuzba `os.stat('/home/user1/myfile.run') os.stat_result(st_mode=33277, st_ino=16911510, st_dev=66308, st_nlink=1, st_uid=1000, st_gid=1000, st_size=25752830, st_atime=1564444885, st_mtime=1564444885, st_ctime=1564478804)` – Sun Bear Jul 30 '19 at 11:39
  • @wizzwizz4 I found this command works `result = subprocess.run( ['/bin/bash', '/home/user1/myfile.run'], stdout=subprocess.PIPE )` Files were then installed into a sub-directory of the directory holding my python script which submitted the subprocess.run() function. However, this outcome is wrong. The files should have been written into a sub-directory of the directory holding 'myfile.run'; this was the outcome when `./home/user1/myfile.run` was submitted in a terminal. Can you advice me on how I can correct this matter? – Sun Bear Jul 30 '19 at 12:23
  • @SunBear Change your PWD. Also, you should [edit] this information into your question. – wizzwizz4 Jul 30 '19 at 12:26
  • @wizzwizz4 I should not need to edit my question. I had used the wrong syntax hence nothing happened. I was missing `/bin/bash` as one of elements of the list argument of `subprocess.run()`. This is the answer to the present question. As for `os.chdir()`, it is a separate question and had been asked and explained by others. Appreciate your advises. – Sun Bear Jul 30 '19 at 12:51
  • @SunBear Then post an answer to your question! – wizzwizz4 Jul 30 '19 at 12:53
  • The error message shows that you used `./home/` instead of `/home/`. – tripleee Jul 30 '19 at 13:22
  • 1
    @wizzwizz4 The solution on [How do I change directory cd in Python?](https://stackoverflow.com/questions/431684/how-do-i-change-directory-cd-in-python) is dated. `subprocess.run()` in Python 3.6 has the `cwd` keyword argument. Therefore the `os.chdir()` command is not required to solve the wrong directory issue. The correct approach is to set the value of the `cwd` keyword argument of `subprocess.run()` . Appreciate you remove your comment that this is a duplicate question as it isn't. – Sun Bear Jul 31 '19 at 14:29
  • @SunBear Great! It'd be good if you amended the snippet in your answer, to include the `kwarg` usage you discovered. I've reconsidered (in light of your answer's phrasing, suggesting that [`.run` files are actually standard things](https://duckduckgo.com/?q=.run+file&t=ffab&ia=web)), and have voted to re-open the question; I no longer think it's a duplicate. – wizzwizz4 Jul 31 '19 at 14:33
  • @wizzwizz4 Yes, I had explained the matter in the "Update" section of my answer. – Sun Bear Jul 31 '19 at 14:40
  • @SunBear https://meta.stackoverflow.com/q/255644/5223757 – wizzwizz4 Jul 31 '19 at 14:49
  • @wizzwizz4 Thanks for the explanation on how to phrase an answer. Learnt another new lesson today. Cheers. Answer revised. Btw, I still see "marked as duplicate by wizzwizz4" in my question. Does the SOF system leaves it there even though you have voted to re-open the question? – Sun Bear Jul 31 '19 at 15:16
  • @triplee As earlier explained in my question, I had tried both `./home/` and `/home/`. The former returned an error while the latter returned nothing. After posting my question, and after further trials and thoughts, I discovered that I had to explicitly declare `/bin/bash` in the `args` list of the `subprocess.run()` function to execute a bash script in Python 3.6. The need for `/bin/bash` in `subprocess.run()` was not articulated in any of the answers of the question that you had claimed my question is a repeat of.Can you explain why you view my question as a duplicate of the other question? – Sun Bear Jul 31 '19 at 15:32
  • I added one more duplicate which hopefully fills in the missing piece. – tripleee Jul 31 '19 at 15:42
  • @tripleee The answers in the new link that you had cited can't be implemented exactly to solve my question. I can't put a "shebang" at the top of a python script, it's already occupied with `#!/usr/bin/python3.6`. Although I concede that the `subprocess.run()` function is a python interface to run bash command, the answer to my question, i.e. where to correctly assign a `/bin/bash` syntax in the case of a python subprocess.run() function, is purely unique to python (not implementable in bash) scripting. – Sun Bear Jul 31 '19 at 16:26
  • @tripleee Also, in the answers you had cited, no where does the keyword `subprocess` appears despite `/bin/bash` is mentioned. I find it too big a stretch to claim that my question already has an answer in the links you had provided. Please reconsider. Thanks. – Sun Bear Jul 31 '19 at 16:28
  • 1
    The shebang would go at the top of the Bash script which you are trying to run in a subprocess. This is basic Unix 101 so it really has been covered before, hundreds of times. – tripleee Jul 31 '19 at 16:38

1 Answers1

1

The correct syntax to using subprocess.run() to execute a .run executable file is:

result = subprocess.run( ['/bin/bash', '/home/user1/myfile.run'], stdout=subprocess.PIPE )

Essentially, the .run file is a bash script, and to run a bash file I needed to activate /bin/bash. The . symbol commonly used to run a bash script in a terminal could not work in subprocess.run(). Hence, /bin/bash had to be declared explicitly.

After solving my question, I discovered that the data created by the myfile.run bash script was written to a sub-directory of the directory holding my python script which submitted the subprocess.run() function. However, this outcome was wrong. The data should have been written into a sub-directory of the directory holding the myfile.run bash script; this was the outcome when ./home/user1/myfile.run was submitted in a terminal.

A common view on how to change the current working directory in python is to use the function os.chdir() (see here). However, I discovered that the function subprocess.run() in Python 3.6 has a current working directory keyword argument kwarg called cwd=None. Hence, to resolve my wrong directory issue (as described above), I simply had to equate the working directory that I want with cwd, e.g. cwd='/home/user1/Project'. Meaning, the use of os.chdir() with subprocess.run() function is unnecessary and avoided.

Sun Bear
  • 7,594
  • 11
  • 56
  • 102