Get directory dynamically with python script - python

I run my python script in the background from a terminal with:
python myscript.py &
In the script I have a loop which gets the current directory with os.getcwd(). If I change my working directory in the terminal though, the script doesn't get the new directory because as far as I have understood the script is attached to the original directory from which it was launched.
How can I update the current directory from a python script, i.e. how can I keep track of the current working directory of the process that launched the script?

Disclaimer: don't do this.
import os
import subprocess
from time import sleep
ppid = os.getppid()
print "parent process id: ", ppid
subprocess.check_call(['pwdx', str(ppid)])
sleep(5) # do `cd other` in the parent process here
subprocess.check_call(['pwdx', str(ppid)])

Related

How do I export environment variables using a script in the same shell in python?

My django project fetches credentials from environment variables, now I want to automate this process and store the credentials in the vault(hashivcorp).
I have a python and shell script which fetches data from an API and exports it as environment variables, when I run it using os.system command it runs the shell script but as it runs it in a subprocess, I can't access the variables in the main(parent) process/shell. Only way of doing it by inserting the shell script in the settings.py file.
Is there any way I can do it so that I get those in the main process?
P.s: I did try sourcing, os.system didn't recognise it as a command.
Here's the code I'm running:
import os
os.environ['ENV'] = 'Demo'
os.system('python3 /home/rishabh/export.py')
print(os.environ.get('RDS_DB_NAME'))
output:
None
the python file, shell script works just fine.
One way to do it is to run export.py in the same process, as user1934428 suggested:
import os
import sys
os.environ['ENV'] = 'Demo'
sys.path.append('/home/rishabh/')
import export # runs export.py in the same process
print(os.environ.get('RDS_DB_NAME'))
This assumes there are no __name__ == '__main__' checks inside export.py.
You only need the sys.path line if export.py is in a different directory than your current script.

Pyinstaller: Executable file opened with built in function in python closes after 1 sec when i make .exe file with pyinstaller

I make program in python to open some executable file given by path. I use:
os.startfile(path)
to start program. When i run script.py in IDLE it works fine, but when i make .exe file with pyinstaller when i run it that program i want to open starts to open and closes almost immediately. I tried with different functions like subprocess.Popen(path) and it does the same thing, open and close program after 1 second. Can someone help me? Is there a problem in python functions or in pyinstaller or even windows 10?
The problem is that your code most likely just runs and then the window closes.
You can add import time to your imports and time.sleep(x) or something to keep the window open for x seconds after you run
Read all the way through before doing anything!
Ok so try this:
Put this in a python file called start.py:
import os
import subprocess
#py_command - whatever opens python in cmd
#path - must be full path of file you want to call
def StartPythonScript(path, py_command):
command = 'start cmd /k ' + py_command + " " + path
subprocess.run(command, shell=True)
Now, take the code from file you are calling from the exe, let's say its name is run.py, and put it in a different file, say code.py.
Make sure start.py is in the same folder as run.py
In run.py, put this:
import start
cmd = "py" #change this to whatever opens python in cmd
path = "code.py" #change to the full path of code.py
start.StartPythonScript(path, cmd)
So when you click on the exe, it opens run.py which tells start.py to open code.py, which contains your program.
You can actually merge start.py and run.py, but you can reuse start.py if they are seperate.
OR...
Add import os to your program that is called by the exe.
Add os.system("pause") to the end of your program.
I'm not sure if this will work on an infinitely running program...but try this first to save time.
More info:
How to stop Python closing immediately when executed in Microsoft Windows
Good luck!

Running 3 python programs by a single program via subprocess.Popen method

I am trying to run 3 python programs simultaneously by running a single python program
I am using the following script in a separate python program sample.py
Sample.py:
import subprocess
subprocess.Popen(['AppFlatRent.py'])
subprocess.Popen(['AppForSale.py'])
subprocess.Popen(['LandForSale.py'])
All the three programs including python.py is in the same folder.
Error: OSError: [Errno 2] No such file or directory
Can someone guide me how can i do it using subprocess.Popen method?
The file cannot be found because the current working directory has not been set properly. Use the argument cwd="/path/to/script" in Popen
It's because your script are not in the current directory when you execute sample.py.
If you three script are in the same directory than sample.py, you could use :
import os
import subprocess
DIR = os.path.dirname(os.path.realpath(__file__))
def run(script):
url = os.path.join(DIR, script)
subprocess.Popen([url])
map(run, ['AppFlatRent.py','AppForSale.py', 'LandForSale.py'])
But honestly, if i was you i will do it using a bash script.
There might be shebang missing (#!..) in some of the scripts or executable permission is not set (chmod +x).
You could provide Python executable explicitly:
#!/usr/bin/env python
import inspect
import os
import sys
from subprocess import Popen
scripts = ['AppFlatRent.py', 'AppForSale.py', 'LandForSale.py']
def realpath(filename):
dir = os.path.realpath(os.path.dirname(inspect.getsourcefile(realpath)))
return os.path.join(dir, filename)
# start child processes
processes = [Popen([sys.executable or 'python', realpath(scriptname)])
for scriptname in scripts]
# wait for processes to complete
for p in processes:
p.wait()
The above assumes that script names are given relative to the module.
Consider importing the modules and running corresponding functions concurently using threading, multiprocessing modules instead of running them as scripts directly.

Run .exe in python with all files in directory

I am working on an auto restart script for an exe but there are config files in the directory I need to run with the exe. If I start the exe from the actual file folder it works fine but when I use the script to run the exe it starts the exe without the configuration files. What can I add to this script to use all files in the directory?
import os, subprocess, time
while True:
print("Starting process...")
p = subprocess.Popen("C:\\Users\\my-pc\\Desktop\\process\\process.exe")
time.sleep(7200)
print("Terminating process...")
p.terminate()
time.sleep(10)
You should set cwd parameter of Popen constructor to the working directory of the process, e.g.:
p = subprocess.Popen("C:\\Users\\my-pc\\Desktop\\process\\process.exe", cwd="C:\\Users\\my-pc\\Desktop\\process")
You may also find useful the official documentation of subprocess.Popen.
You should be able to call Popen with a "cwd" keyword argument that should pickup the configuration files.

How to change the working directory for a shell script (newbie here)

I have a python script that looks files up in a relative directory. For example: the python script is in /home/username/projectname/. I have a file that is being called within the python script that is in /home/username/projectname/subfolder.
If I run the script from the shell as python scriptname.py it runs perfectly fine.
However, i'm trying to run the script as a startup service. I'm setting it up in webmin, and I believe its using a terminal command to call it. In the startup command, I'm doing something like this to call the script:
execute python home/username/projectname/scriptname.py. The script is starting up fine, but I get an error because it cant access the files in the relative directory.
I am guessing that there is a better way to call the python program from within the startup command so that its aware of the relative path.
import os
os.chdir("/tmp")
Also have:
os.getcwd()
Maybe you need the following instead?
import os.path
dir = os.path.dirname(__file__)
The process that starts your python script (probably forkink) has a pwd (its working directory). The idea is to change the pwd of the process before to fork and execute python.
You need to look over the manual of the process that executes the shell command, and see how to set the pwd.(in shell you use cd or pushd)
__file__ is the path that was used to run your script.
Copy this into a script file and try running it:
import os
print "This script was run as: %r" % __file__
print "This script is: %r" % os.path.abspath(__file__)
script_dir = os.path.dirname(os.path.abspath(__file__))
print "This script is in directory: %r" % script_dir
print "When started, the current directory was: %r" % os.getcwd()
os.chdir(script_dir)
print "After calling os.chdir(), the current directory is: %r" % os.getcwd()

Categories