I'm new and I'm trying to run a script that runs a sequence of scripts based on what I put in a text file.
For example, I have Script1.py with print("Script1") ... then Script2.py with print("Script2"), Script3.py with print("Script3") ... and in the text file to once:
Script1.py
Script3.py
then another time to have:
Script2.py
Script1.py
Script3.py
Script2.py
And the main script to execute the sequence of scripts in the text file.
PS: Apologies for my English language
Thank you in advance
def Script1():
Script1.py
def Script2():
Script2.py
def Script3():
Script3.py
commands_table = {'Script1':Script1, 'Script2':Script2, 'Script3':Script3}
with open('test.txt', 'r') as command_file:
for cmd in command_file:
cmd = cmd.strip()
commands_table[cmd]()
Use import to grab functions from other files
scripts.py
def script1():
print('1')
def script2():
print('2')
app.py
import scripts
commands_table = {'Script1':scripts.script1, 'Script2':scripts.script2}
with open('test.txt') as command_file:
for cmd in command_file:
commands_table[cmd.strip()]()
To run a sequence of scripts based on what is listed in a text file, you can use the following steps:
Read the contents of the text file using Python's built-in open function and the readlines method. This will give you a list of strings, where each string corresponds to a script name.
Loop through the list of script names and use Python's subprocess module to run each script in turn. The subprocess module provides a way to spawn new processes, connect to their input/output/error pipes, and obtain their return codes.
Example:
import subprocess
# Step 1: Read the contents of the text file
with open('script_list.txt', 'r') as f:
script_names = [line.strip() for line in f.readlines()]
# Step 2: Loop through the list of script names and run each script
for script_name in script_names:
subprocess.run(['python', script_name])
Assuming that your text file is named "script_list.txt" and contains the string "Script1.py", "Script2.py", and "Script3.py", this script will run each of those scripts in order, printing out "Script1", "Script2", and "Script3" to the console.
import os
with open('test.txt', 'r') as command_file:
commands = command_file.read()
commandsList = commands.splitlines()
for cmd in commandsList:
os.system(cmd)
You have to chmod +x all your scripts to be executable and the first line of each script should be:
#! /usr/local/bin/python3
or whatever your python interpreter is
Related
I have two files, one bell.mp3 one main.py file, that plays back bell.mp3 via subprocess.
If I do:
pyinstaller main.py
the Dist file ends up correctly, and everything works fine, The program runs in a directory.
This is the code for my file which i call pyinst_tester.py
it creates a text file, and plays a bell.mp3 file
#
from con import * # this is just a configuration file that has g='play' in it.
import subprocess
f=open(r'/home/godzilla/Desktop/Pyinstaller testing/testfile1','w')
f.write('This has worked')
f.close()
file='/home/godzilla/Desktop/Pyinstaller testing/data/bell.mp3'
if 'play' == g:
subprocess.call(['/usr/bin/cvlc',file])
a single file is created, but if I delete the bell.mp3 file it doesn't work. In a single file isn't the bell.mp3 zipped inside the main.exe ? therefore, redundant as a separate file ?
What Is the point having a single file exe, if you need an adjacent file with all the mp3s inside?
Pyinstaller has many features and if you want to include non python files (for example mp3 files) you have to do so explicitly with the --add-binary switch.
In one file mode the executable will be unpacked into a temporary directory prior to execution of the python code.
So how to write your code to access these data files.
You might want to look at the pyinstaller documention at following sections:
https://pyinstaller.readthedocs.io/en/stable/runtime-information.html#run-time-information
https://pyinstaller.readthedocs.io/en/stable/runtime-information.html#using-sys-executable-and-sys-argv-0
I personally place all my files in a separate directory. e.g. data.
If you place the file bell.mp3 in the directory data, then you had to call pyinstaller with the option --add-binary data:data
in the one file mode the executable is extracted into a temporary directory
whose path you get get from the variable sys._MEIPASS
Your data directory will bi in the sub directory data of sys._MEIPASS
In my example I create a function, that will be able to locate the data files in normal python mode and in pyinstaller one file or one directory mode.
Just try it out it should be self explaining
simple example:
minitst.py
import os, sys
import time
is_frozen = getattr(sys, "frozen", False)
MYDIR = os.path.realpath(os.path.dirname(__file__))
def data_fname(fname):
if is_frozen:
return os.path.join(sys._MEIPASS, "data", fname)
else:
return os.path.join(MYDIR, "data", fname)
def main():
print("This application is %s frozen" %
("" if is_frozen else "not"))
print("executable =", sys.executable,
"File =", __file__,
"mydir =", MYDIR)
if is_frozen:
print("MEIPASS", sys._MEIPASS)
fname = data_fname("tst.txt")
print("will open", fname)
with open(fname) as fin:
print(fin.read())
time.sleep(5) # this shall allow to view the console e.g. on windows if clicking on the executable.
if __name__ == "__main__":
main()
now create a directory data and place a file "tst.txt"
data/tst.txt
Hello world
Now call
pyinstaller -F minitst.py --add-binary data:data -c
and call dist/minitst from a console.
The output should look like:
This application is frozen
executable = /home/gelonida/so/pyinst/dist/minitst File = minitst.py mydir = /home/gelonida/so/pyinst
MEIPASS /tmp/_MEIKGqah9
will open /tmp/_MEIKGqah9/data/tst.txt
Hello
Now concerning your code.
I compacted the code to determine the datadir a little, but it is the same logic as in the upper example
import os, sys
from con import * # this is just a configuration file that has g='play' in it.
import subprocess
basedir = getattr(sys, "_MEIPASS", os.path.realpath(os.path.dirname(__file__)))
f=open('testfile1','w')
f.write('This has worked')
f.close()
file=os.path.join(basedir, 'data/bell.mp3')
if 'play' == g:
subprocess.call(['/usr/bin/cvlc',file])
I have compiled my python program with cx_Freeze with the lines
import sys
print(sys.argv[0])
to get the name of the extension file that runs my application.
I want to be able to double click on a file named Foo.bas and then my compiled executable starts and it can open the file and read its contents. So I want to get the extension path and file name and read its contents like this
with open(file, "r") as f:
data = f.read()
# do things with contents
where file would be the extension path and name
So how would I do that?
sys.argv[0] gives you the first entry of the command used to run your script, which is the script name itself. If you double-click on a file whose extension is associated with your script or frozen application, the name of this file becomes the second argument of the command, which is available through sys.argv[1]. See for example sys.argv[1] meaning in script.
So try with the following script:
import os
import sys
if len(sys.argv) > 1:
filename = sys.argv[1]
print('Trying with', filename)
if os.path.isfile(filename):
with open(filename, 'r') as f:
data = f.read()
# do things with contents
else:
print('No arguments provided.')
input('Press Enter to end')
This works both as unfrozen script and as executable frozen with cx_Freeze. On Windows you can drag and drop your Foo.bas file onto the icon of your script or executable, or right-click on Foo.bas, chose Open with and select your script or executable as application.
I have a list of files which will be used to extract by another linux script like this:
gzip -dc input/test_log.gz | bin/recreate state/object_mappings.sort > output/recreate.out
I need to change the name test_log.gz with my list of files with python loop, how can I execute this script dynamically. here is my code:
import os
from subprocess import call
files = os.listdir("/my directory/")
files.sort()
for i in files:
call('gzip -dc input/test_log.gz | bin/recreate state/object_mappings.sort > output/recreate.out')
I dont know how to change this script with dynamic variable i??
You can use an f-string literal:
import os
from subprocess import call
files = os.listdir("/my directory/")
files.sort()
for file in files:
call(f'gzip -dc {os.path.abspath(file)} | bin/recreate state/object_mappings.sort > output/recreate.out')
In my case the below method works.
from subprocess import call
files = ['input.txt', 'input1.txt', 'input2.txt', 'input3.txt']
for file in files:
call(['sed', '-i', 's+NameToBeReplaced+NewName+', file])
sed : is stream editor
-i : Allows to edit the source file
+: Is delimiter.
call: Takes command in array format.
For example: if you want to run ls -l input.txt
call(['ls', '-l', file])
I hope the above information works for you 😃.
I am trying to use subprocess to start a command on the command-line for which I want to have the output written into some file. So, in other words, I want to have e.g. the following command executed within python:
python my_code.py --arg1 > output.txt
I tried the following:
import subprocess
cwd = "/home/path/to/the/executable"
cmd = "python my_code.py --arg1"
with open('output.txt', "w") as outfile:
subprocess.Popen(cmd.split(), stdout=outfile, cwd = cwd)
but the output file stayed empty. How to else do it (not blocking!)?
Addition:
My guess is that the output file is created, but is being closed as soon as the above code finishes. Therefore, no output to that file...
sys.stdout is buffered by default. You can disable it by passing -u to python.
import subprocess
cwd = "/home/path/to/the/executable"
cmd = "python -u my_code.py --arg1"
with open('output.txt', "w") as outfile:
subprocess.Popen(cmd.split(), stdout=outfile, cwd = cwd)
I need to run several python script's, some of those are scrapy projects.
To run a spider I try this:
from subprocess import call
import subprocess
call(["scrapy",'crawl','my_spider','-o output_file.csv'],cwd='/home/luis/Schreibtisch/kukun/bbb_new_pro/scripts/2_Get_links)
I wonder whether is posible to specify the output's file directory, I tried this:
call(["scrapy",'crawl','my_spider','-o folder_1/folder_2/output_file.csv'],cwd='project_folder')
But that only creates a new folders under the project directory I want the file outside tht folder.
The other thing is, Can I specify the name of the ouput file in a variable? something like:
file_name = 'output file.csv'
call(["scrapy",'crawl','my_spider','-o + file_name '],cwd='project_folder')
This worked for me:
from subprocess import call
name = "spider_name"
call(["scrapy", "crawl", "{0}".format(name), "-o {0}.json".format(name)])