Executing all files inside a folder in Python - python

I have 20 Python files which is stored inside a directory in ubuntu 14.04 like 1.py, 2.py, 3.py , 4.py soon
i have execute these files by "python 1.py", "python 2.py" soon for 20 times.
is their a way to execute all python files inside a folder by single command ?

find . -maxdepth 1 -name "*.py" -exec python3 {} \;

for F in $(/bin/ls *.py); do ./$F; done
You can use any bash construct directly from the command line, like this for loop. I also force /bin/ls to make sure to bypass any alias you might have set.

Use a loop inside the folder:
#!/bin/bash
for script in $(ls); do
python $script
done

You can try with the library glob.
First install the glob lybrary.
Then import it:
import glob
Then use a for loop to iterate through all files:
for fileName in glob.glob('*.py'):
#do something, for example var1 = filename
The * is used to open them all.
More information here: https://docs.python.org/2/library/glob.html

Related

Forgot path to module

I made a script called sm on a linux-os, which I want to update from python 3.6 to 3.9. But unfortunately I forgot the path to this file. I tried it with the command "locate sm.py" but it showed me thousands of things, where the name was something like the file name "sm.py", and I don't want to read through it. So does anyone know how to find this file more precisely than my locate-command?
try this in shell
find / -name "sm" -depth -exec echo {} \;

Execute bash commands that are within a list from python

i got this list
commands = ['cd var','cd www','cd html','sudo rm -r folder']
I'm trying to execute one by one all the elements inside as a bash script, with no success. Do i need a for loop here?
how to achieve that?, thanks all!!!!
for command in commands:
os.system(command)
is one way you could do it ... although just cd'ing into a bunch of directories isnt going to have much impact
NOTE this will run each command in its own subshell ... so they would not remember their state (ie any directory changes or environmental variables)
if you need to run them all in one subshell than you need to chain them together with "&&"
os.system(" && ".join(commands)) # would run all of the commands in a single subshell
as noted in the comments, in general it is preferred to use subprocess module with check_call or one of the other variants. however in this specific instance i personally think that you are in a 6 to 1 half a dozen to the other, and os.system was less typing (and its gonna exist whether you are using python3.7 or python2.5 ... but in general use subprocess exactly which call probably depends on the version of python you are using ... there is a great description in the post linked in the comments by #triplee why you should use subprocess instead)
really you should reformat your commands to simply
commands = ["sudo rm -rf var/www/html/folder"] note that you will probably need to add your python file to your sudoers file
also Im not sure exactly what you are trying to accomplish here ... but i suspect this might not be the ideal way to go about it (although it should work...)
This is just a suggestion, but if your just wanting to change directories and delete folders, you could use os.chdir() and shutil.rmtree():
from os import chdir
from os import getcwd
from shutil import rmtree
directories = ['var','www','html','folder']
print(getcwd())
# current working directory: $PWD
for directory in directories[:-1]:
chdir(directory)
print(getcwd())
# current working directory: $PWD/var/www/html
rmtree(directories[-1])
Which will cd three directories deep into html, and delelte folder. The current working directory changes when you call chdir(), as seen when you call os.getcwd().
declare -a command=("cd var","cd www","cd html","sudo rm -r folder")
## now loop through the above array
for i in "${command[#]}"
do
echo "$i"
# or do whatever with individual element of the array
done
# You can access them using echo "${arr[0]}", "${arr[1]}" also

How can I use files/directories in python on Linux that start with .?

I'm a COMPLETE beginner to python, I'm making my first python script that really does anything. I'm assigning a directory to a variable so I can use it to move a file, but the directory includes a folder starting with . and python says it's invalid syntax. So how can I get python to ignore the .?
EDIT: Here's the code
#!/usr/bin/env python
import os
Optifine = find /home/Sol33t303/.minecraft -name
OptiFine_1.10.2_HD_U_E3.jar
shutil.move(Optifine, "/home/Sol33t303/.minecraft/mods")
You are mixing two very different things.
Are you writing Python or Bash, cause this is totally Bash:
Optifine = find /home/Sol33t303/.minecraft -name
You can't just run Bash commands inside a Python script!
If, for example you want to run a shell command inside your script and get its output you can use:
Optifine = subprocess.check_output(['find', '/home/Sol33t303/.minecraft', '-name'])
And then you split the output by line, and foreach line (file found), move it to the desired destination:
for line in Optifine.splitlines():
shutil.move(Optifine, "/home/Sol33t303/.minecraft/mods")

run python script in every file in a directory through command line

I have a python script which takes the filename as a command argument and processes that file. However, i have thousands of files I need to process, and I would like to run the script on every file without having to add the filename as the argument each time.
for example:
process.py file1 will do exactly what I want
however, I want to run process.py on a folder containing thousands of files (file1, file2, file3, etc.)
I have found out it that it can be done simply in Bash
for f in *; do python myscript.py $f; done
However, I am on windows and don't want to install something like Cygwin.
What would a piece of code for the Windows command line look like that would emulate what the above Bash code accomplishes?
for %%f in (*.py) do (
start %%f
)
I think that'll work -- I don't have a Windows box handy at the moment to try it
How to loop through files matching wildcard in batch file
That link might help
import os, subprocess
for f in os.listdir('.'):
if os.path.isfile(f):
subprocess.call(["python", "myscript.py", f])
this solution will work on every platform, provided the python executable is in the PATH.
Also, if you want to recursively process files in nested subdirectories, you can use os.walk() instead of os.listdir()+os.path.isfile().
Since you have python, why not use that?
import subprocess
import glob
import sys
import os.path
for fname in glob.iglob(os.path.join('some-directory-name','*')):
proc = subprocess.Popen([sys.executable, 'myscript.py', fname])
proc.wait()
What's more, its portable.
For each file in current dir.
for %f in (*) do C:\Python34\python.exe "%f"
Update:
Note the quotes on the %f. You need them if your files contain spaces in the name. You can also put any path+executable after the do.
If we imagine your files look like:
./process.py
./myScripts/file1.py
./myScripts/file2.py
./myScripts/file3.py
...
In your example, would simply be:
for %f in (.\myScripts\*) do process.py "%f"
This would invoke:
process.py ".\myScripts\file1.py"
process.py ".\myScripts\file2.py"
process.py ".\myScripts\file3.py"

Why can't bash see my files?

I have a simple bash script that allows cron to execute a series of Python scripts in a virtualenv. The script keeps raising No such file or directory errors.
~/nightly.sh works fine:
#!/bin/bash
source virt_env/myproject/bin/activate
cd virt_env/myproject/main
python script1.py
python script2.py
I want to keep everything in ~/virt_env/myproject/main/ to simplify deployment. I thought I could call bash virt_env/myproject/main/nightly.sh on this:
#!/bin/bash
MAINDIR=`dirname $0`
cd $MAINDIR
source ../bin/activate
python script1.py
python script2.py
but I get the No such file or directory. If I manually cd to ~/virt_env/myproject/main/, then I can run the main commands no problem. Clearly I'm missing something about how dirname and cd work in this context.
How can I point bash at the right place?
Solution
As proposed in the accepted answer, it's best to avoid calling cd from within the script and use an explicit path variable instead. Here's the working version of virt_env/myproject/main/nightly.sh:
#!/bin/bash
MAINDIR=`dirname $0`
echo "The main directory is" $MAINDIR
# Activate virtual environment
source $MAINDIR/../bin/activate
# Run Python scripts
python $MAINDIR/python1.py
python $MAINDIR/python2.py
Because the Python scripts are now called from an arbitrary path, I needed to update the python scripts to be smarter about path awareness as well.
This code fails because os.path.basename omits path information:
# works when called with "python python1.py"
# fails when called with "python $MAINDIR/python1.py"
CONFIG_FILE = os.path.basename(__file__)[:-3] + ".config"
f = open(CONFIG_FILE,"r")
Updating it to use os.path.abspath fixes the problem:
# works regardless of how it is called
CONFIG_FILE = os.path.abspath(__file__)[:-3] + ".config"
f = open(CONFIG_FILE,"r")
Perhaps it would simply be better to eliminate the 'cd' command. Invoke everything from a full path specification. In your example add $MAINDIR/ to the executables.
Your bash script can then be in any directory where the executables are reachable. You are not exposed to the problems of what happens when cd fails.
Example:
cd yourdir
rm -f yourglob # oops things got removed from where you started if yourdir did not exist.
Two things:
Are you sure you know what the dirname command is doing? It's going to remove the top-level directory as well as the leading slash on whatever you call it on. I would make absolutely sure that the output of dirname is exactly what you think it is.
For example, /home/user/ will output /home.
You're using ~, which references the $HOME variable in your environment. You didn't mention where the cron is listed, but make sure it's not being run as a different user. Root's ~ and your ~ will be two completely different directories.
That's all I can think of. I hope that helps!
Add echo $MAINDIR after
MAINDIR=`dirname $0`
cd $MAINDIR
So you can see, if the contents of MAINDIR is correct.
Also you can run sh with -x or add set -x to the beginning of the script to see what happens.

Categories