python subprocess shouldn't run from within the folder - python

I am trying to use the C&C NLP library in my mac and it uses terminal as its interface. so naturally I'm trying to run the command from my python, but here's what happens:
candc:could not open model configuration file for reading:models/config
turns out candc should not be called from the same directory, and should be called from outside of the binary folder, something like "bin/candc".
how can I make this work?
this is my code:
cmd="candc/bin/candc --models models"
subprocess.check_output('{} | tee /dev/stderr'.format( cmd ), shell=True)

Pass the cwd argument with your desired working directory.
For example, if you want to run it as bin/candc from the candc directory:
import os
cmd="bin/candc --models models"
subprocess.check_output('{} | tee /dev/stderr'.format( cmd ), shell=True, cwd=os.path.abspath('candc'))
(I'm not sure whether you actually need os.path.abspath. Do test both with and without it.)

Use the full path in cmd:
cmd = "/home/your-username/python-programs/cnc/candc/bin/canc --models models
Whatever that full path might be. You can use (if you're on linux) pwd inside the candc directory to find out what it is.

Related

Find the system paths not contained in the environment variable with python

So when I try to find the path from the cmd with where azuredatastudio, I get the path. When I go in Python and do print(os.environ), I get many defined paths, but not this from the upper command in cmd.
How to get in this example azuredatastudio path from Python and where is it stored?
The WHERE command is roughly equivalent to the UNIX 'which' command. By default, the search is done in the current directory and in the PATH.
Source: https://ss64.com/nt/where.html
So you'll have to explicitly look at the paths in the PATH environment variable: os.environ['PATH']. You'll find an implementation in this question here for example: Test if executable exists in Python?
Also, you should be able to just run the command from Python:
from subprocess import check_output
path = check_output(["where", "azuredatastudio"])
print(path)
A easy way to do this is:
import os
os.system("where azuredatastudio")
or if you want to save it in a variable.
import subprocess
process = subprocess.Popen("where azuredatastudio",stdout=subprocess.PIPE)
print(process.stdout.readline())

Python: change file/folder attributes in windows OS

I have made a folder using python3 script, and to apply multiple attributes (+h +s) to the folder I have to run ATTRIB command in Command Prompt.
But I want to know how it can be done from the same python3 script.
import os
os.makedir("C:\\AutoSC")
# Now I want the code to give the same result such that I have opned CMD and writen following command
# C:\> attrib +h +s AutoSC
# Also show in the code, necessary imported modules
I want the folder to be created and immediately hidden as system folder.
Which is not visible even after show hidden files.
Use the subprocess module or use os.system to send commands directly to OS.
import subprocess
subprocess.run(["ls","-l"])# in linux, for windows, it may change.
import os
os.system('attrib +h +s AutoSC')

running bash script from python file

I have a bash script which changes the path on my command line,
This one,
#!/usr/bin/env python
cd /mnt/vvc/username/deployment/
I have a python script which i wish to run after the path changes to the desired path,
The script,
#!/usr/bin/env python
import subprocess
import os
subprocess.call(['/home/username/new_file.sh'])
for folder in os.listdir(''):
print ('deploy_predict'+' '+folder)
I get this
File "/home/username/new_file.sh", line 2
cd /mnt/vvc/username/deployment/
^
SyntaxError: invalid syntax
Any suggestions on how can i fix this?thanks in advance
You need to explicitly tell subprocess which shell to run the sh file with. Probably one of the following:
subprocess.call(['sh', '/home/username/new_file.sh'])
subprocess.call(['bash', '/home/username/new_file.sh'])
However, this will not change the python program's working directory as the command is run in a separate context.
You want to do this to change the python program's working directory as it runs:
os.chdir('/mnt/vvc/username/deployment/')
But that's not really great practice. Probably better to just pass the path into os.listdir, and not change working directories:
os.listdir('/mnt/vvc/username/deployment/')

Python scripts for writing UNIX commands on terminal

I wish to write a python script that allows me to navigate and git pull multiple repositories. Basically the script should type the following on the command-line:
cd
cd ~/Desktop/Git_Repo
git pull Git_Repo
I am not sure if there is a python library already out there that can perform such a task.
Use subprocess, os, and shlex. This should work, although you might require some minor tweaking:
import subprocess
import shlex
import os
# relative dir seems to work for me, no /'s or ~'s in front though
dir = 'Desktop/Git_Repo'
# I did get fetch (but not pull) to work
cmd = shlex.split('git pull Git_Repo')
# you need to give it a path to find git, this lets you do that.
env = os.environ
subprocess.Popen(cmd, cwd=dir, env=env)
Also, you'll need your login preconfigured.

Change working directory in shell with a python script

I want to implement a userland command that will take one of its arguments (path) and change the directory to that dir. After the program completion I would like the shell to be in that directory. So I want to implement cd command, but with external program.
Can it be done in a python script or I have to write bash wrapper?
Example:
tdi#bayes:/home/$>python cd.py tdi
tdi#bayes:/home/tdi$>
Others have pointed out that you can't change the working directory of a parent from a child.
But there is a way you can achieve your goal -- if you cd from a shell function, it can change the working dir. Add this to your ~/.bashrc:
go() {
cd "$(python /path/to/cd.py "$1")"
}
Your script should print the path to the directory that you want to change to. For example, this could be your cd.py:
#!/usr/bin/python
import sys, os.path
if sys.argv[1] == 'tdi': print(os.path.expanduser('~/long/tedious/path/to/tdi'))
elif sys.argv[1] == 'xyz': print(os.path.expanduser('~/long/tedious/path/to/xyz'))
Then you can do:
tdi#bayes:/home/$> go tdi
tdi#bayes:/home/tdi$> go tdi
That is not going to be possible.
Your script runs in a sub-shell spawned by the parent shell where the command was issued.
Any cding done in the sub-shell does not affect the parent shell.
cd is exclusively(?) implemented as a shell internal command, because any external program cannot change parent shell's CWD.
As codaddict writes, what happens in your sub-shell does not affect the parent shell. However, if your goal is to present the user with a shell in a different directory, you could always have Python use os.chdir to change the sub-shell's working directory and then launch a new shell from Python. This will not change the working directory of the original shell, but will leave the user with one in a different directory.
As explained by mrdiskodave
in Equivalent of shell 'cd' command to change the working directory?
there is a hack to achieve the desired behavior in pure Python.
I made some modifications to the answer from mrdiskodave to make it work in Python 3:
The pipes.quote() function has moved to shlex.quote().
To mitigate the issue of user input during execution, you can delete any previous user input with the backspace character "\x08".
So my adaption looks like the following:
import fcntl
import shlex
import termios
from pathlib import Path
def change_directory(path: Path):
quoted_path = shlex.quote(str(path))
# Remove up to 32 characters entered by the user.
backspace = "\x08" * 32
cmd = f"{backspace}cd {quoted_path}\n"
for c in cmd:
fcntl.ioctl(1, termios.TIOCSTI, c)
I shall try to show how to set a Bash terminal's working directory to whatever path a Python program wants in a fairly easy way.
Only Bash can set its working directory, so routines are needed for Python and Bash. The Python program has a routine defined as:
fob=open(somefile,"w")
fob.write(dd)
fob.close()
"Somefile" could for convenience be a RAM disk file. Bash "mount" would show tmpfs mounted somewhere like "/run/user/1000", so somefile might be "/run/user/1000/pythonwkdir". "dd" is the full directory path name desired.
The Bash file would look like:
#!/bin/bash
#pysync ---Command ". pysync" will set bash dir to what Python recorded
cd `cat /run/user/1000/pythonwkdr`

Categories

Resources