I've written simple python script which provides me with a list of absolute paths of subfolders and subfolders of subfolders of given directory. The list is then written to file. My next goal would be to somehow parse that file in order to manipulate the permissions of directories (chmod, chgrp etc).
Here's a snippet of the file with some (MS Windows) paths, but actually I'll utilize it on Unix machine/s.
C:\Users\Me\Desktop\gopro\New folder\1
C:\Users\Me\Desktop\gopro\New folder\2
C:\Users\Me\Desktop\gopro\New folder\3
C:\Users\Me\Desktop\gopro\New folder\4
I'd appreciate any ideas on the best way to accomplish this. I'm a Python newb so keep that in mind.
I might be misunderstanding the question, but I think if you want to run shell commands on the directories, this is what you are looking for:
import os # this is insecure, so USE WITH CAUTION (never in production).
with open('list_of_directories.txt') as f:
for folder_name in f.readlines(): # read each line from the file.
os.system("chmod 777 {}".format(folder_name)) # os.system lets you run shell commands.
# ...
Please note that while os.system() is the easiest way to solve the problem, it is extremely insecure. Never use it on a production script, but it's fine for quick utility scripts, as I presume that is your use case.
Since you mentioned MS Windows, you can use subprocess.run, which basically runs commands in your shell.
import subprocess
with open("somefile.txt") as txtfile:
for each_path in txtfile.readline():
subprocess.run(
["chmod", "777", each_path],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
shell=True,
)
Related
So I am trying to encrypt a directory using python and I'm not sure what the best way to do that is. I am easily able to turn the folder into a zip file, but from there I have tried looking up how to encrypt it with AES, but couldn't get that to work and I have also tried encrypting using 7zip to archive the folder, but also couldn't get that to work, so if anybody has another solution to encrypt a directory or could point me in the right direction on how to use one of the previous methods that would be helpful. (I'm on windows if that has any significance)
I still recommend 7-zip.
let's say you want to name the zip folder as myzip.zip
Import subprocess
zp = subprocess.call(['7z', 'a', 'your password', '-y', 'myzip.zip'] + ['your file'])
An alternative way:
Import pyminzip
level=4 #level of compression
pyminizip.compress("your file", "myzip.zip", "your password", level)
Using 7-Zip through the subprocess module works. Here are some issues I encountered and had to resolve:
You need to specify the path to 7zip separate from the cmd variable in the Popen subprocess, and build the command with variables rather than a solid string:
appPath="C:\Program Files\\7-Zip"
zApp="7z.exe"
zAction='a'
zPass='-pPASSWORD'
zAnswer='-y'
zDir=directoryToZip
progDir=os.path.join(appPath,zApp)
cmd = [zApp, zAction, zipFileName, zPass, zAnswer, zDir]
subprocess.Popen(cmd, executable=progDir, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
That will create a zip file (in the location with the name in the zipFileName variable), including the contents (directories and files) inside the "directoryToZip" path
progDir has to be specified for separate from the application you are calling as part of the Open command (this is the executable path), and the command string needed to be built out as variables to deal with the windows backslash escaping setup.
I am trying to execute a system executable on UNIX with python. I have used op.system() to do this, but really need to use subprocess.call() instead. My op.System call is below:
os.system('gmsh default.msh_timestep%06d* animation_options.geo' %(timestep));
and works fine. It calls the program gmsh and gmsh reads a series of files specified in default.msh_timestep%06d*. I then try to do the equivalent thing with subprocess, but I get errors saying that the files are not there. Below is the subprocesses call:
call(["gmsh", "default.msh_timestep%06d*" %(timestep), "animation_options.geo"],shell=True);
Does anyone know what could be going on here? I'm admittedly a Python noob, so this might be a silly question.
Globbing is done by the shell for you. In Python, you need to do it yourself. You can use glob.glob to get file list that match the pattern:
import glob
call(["gmsh"] + glob.glob("default.msh_timestep%06d*" % (timestep,)) +
["animation_options.geo"])
If you want to use shell=True, pass a string isntead of a list of strings:
call("gmsh default.msh_timestep%06d* animation_options.geo" % (timestep,), shell=True)
I am trying to make a python script that will open a directory, apply a perl script to every file in that directory and get its out put in either multiple text files or just one.
I currently have:
import shlex, subprocess
arg_str = "perl tilt.pl *.pdb > final.txt"
arg = shlex.split(arg_str)
import os
framespdb = os.listdir("prac_frames")
for frames in framespdb:
subprocess.Popen(arg, stdout=True)
I keep getting *.pdb not found. I am very new to all of this so any help trying to complete this script would help.
*.pdb not found means exactly that - there won't be a *.pdb in whatever directory you're running the script... and as I read the code - I don't see anything to imply it's within 'frames' when it runs the perl script.
you probably need os.chdir(path) before the Popen.
How do I "cd" in Python?
...using a python script to run somewhat dubious syscalls to perl may offend some people but everyone's done it.. aside from that I'd point out:
always specify full paths (this becomes a problem if you will later say, want to run your job automatically from cron or an environment that doesn't have your PATH).
i.e. 'which perl' - put that full path in.
./.pdb would be better but not as good as the fullpath/.pdb (which you could use instead of the os.chdir option).
subprocess.Popen(arg, stdout=True)
does not expand filename wildcards. To handle your *.pdb, use shell=True.
I spend a few hours writing a little script.
Basically what it does is create a new text file and fills it up with whatever.
I zip the text file --using zipfile-- and here's where my problem lies.
I want to run the Windows system command:
copy /b "imgFile.jpg" + "zipFile.zip" newImage.jpg
To merge the image "imgFile.jpg" and the zip "zipFile.zip".
So:
os.system("copy /b \"imgFile.jpg\" + \"zipFile.zip\" newImage.jpg")
When I run my script, it all seems to go fine.
But when it's done and I try to extract the 'newImage.jpg' file, it gives me:
The archive is either in unknown format or damaged
This ONLY happens when I run the system command within the script.
It works fine when I use the shell. It even works if I use a separate script.
I've double checked my zip file. Everything is in good shape.
Is there something I'm doing wrong? Something I'm not seeing?
Have you tried using shutil?
import shutil
shutil.copy(src, dst)
There may be a problem with the way Python is passing the arguments to the shell command. Try using subprocess.call. This method takes arguments as an array and passes them that way to the command:
import subprocess
subprocess.call(["copy", "/b", '"imgFile.jpg" + "zipFile.zip"', "newImage.jpg"])
I'm trying to to a ls -l from python, to check for the last modification date of a file.
os.listdir doesn't show the long list format.
subprocess.call shows the format, but actually prints it, and returns 0. I want to be able to put it in a variable. Any ideas ?
Also, I tried
subprocess.call("ls","*.py")
which answers
ls: cannot access *.py: No such file or directory
it works with shell=True, but if someone could explain why it doesn't work without it, I'll appreciate. If you know how to make it work, even better.
It doesn't work without shell=True because the * is a shell expansion character - going from *.py to a list of files ending in .py is a function performed by the shell itself, not ls or python.
If you want to get the output of a command invoked via subprocess, you should use subprocess.check_output() or subprocess.Popen.
ls_output = subprocess.check_output(['ls', '-l'])
With nice formatting:
import subprocess
print(subprocess.check_output(['ls', '-lh']).decode('utf-8'))