In python I'm doing a os.system('chmod o+w filename.png') command so I can overwrite the file with pngcrush.
These are the permissions after I set them in python:
-rw-rw-rw- 1 me users 925 Sep 20 11:25 filename.png
Then I attempt:
os.system('pngcrush filename.png filename.png')
which is supposed to overwrite the file, but I get:
Cannot overwrite input file filename.png
What could be the problem? Isn't pngcrush being run as an 'other' user, for which write permissions are enabled?
Thanks!
The problem is with the way you execute the pngcrush program, not with permissions of filename.png or Python. It simply attempts to open filename.png both for input and output, which is of course invalid.
Give pngcrush either the -e or the -d option to tell it how to write output. Read its man for more information.
Perhaps pngcrush isn't letting you use the same name for both input and output files? Have you tried changing the output filename? If so, what were the results?
As an aside (not related to the problem of the input and output files being the same), you can change the mode of a file using os.chmod, which is more efficient than running chmod:
import os
import stat
path = "filename.png"
mode = os.stat(path).st_mode # get current mode
newmode = mode | stat.S_IWOTH # set the 'others can write' bit
os.chmod(path, newmode) # set new mode
Perhaps you're supposed to give a different (non-existing) filename for output. Have you tried the same in a shell?
Related
I'm trying to remove file permissions in python. I am aware that the mode to do so is "000." However I'm seeing the removal of file permissions be done with flags as well such as "stat.S_IRWXO." Can anyone explain what I'm doing wrong
import os
import stat
file_path = 'random file'
os.chmod(file_path, stat.S_IRWXO)
My attempt with the "000" mode:
import os
import stat
file_path = "C:\Script\poop.txt"
os.chmod(file_path, 000)
EDIT
Using subprocesses, I was able to resolve the problem. I have not read the full documentation to know if chmod is not fully compatible with Windows, but it seems like it is at the very least, severely limited. Below is the code to use Window's "icacls" command to set permission. This is much more efficient.
import subprocess
file_path = r'C:\Script\poop.txt'
subprocess.check_output(['icacls.exe',file_path,'/deny','everyone:(f)'],stderr=subprocess.STDOUT)
SOURCES
calling windows' icacls from python
https://docs.python.org/2/library/os.html#os.chmod
This string:
file_path = "C:\Script\poop.txt"
is un-escaped. Thus the path becomes something like "C:Scriptpoop.txt". Use a raw string:
file_path = r"C:\Script\poop.txt"
or use \\ instead of \.
You can try to use subprocess module as an general solution:
import subprocess
file_path = 'file.txt'
subprocess.call(['chmod', '000', file_path])
terminal output ls -la:
-r--r--r-- 1 kernel 197121 0 Mar 8 10:29 file.txt
On ms-windows, you can only use os.chmod to set and remove the read-only bit. All others bits are ignored.
Basically, file permissions work differently on ms-windows than on POSIX operating systems. You will have to modify Access Control Lists using win32 API calls. To do that from within Python, you will need pywin32.
I have a list of files on my filesystem which I'd like to chmod to 664 via python.
On of the filenames/dirpaths (I am not allowed to change the filename nor dirpaths!!!) is:
/home/media/Music/Ke$ha/song.mp3 (NOTE $ is a literal, not a variable!)
I receive the files in a list: ['/some/path/file1', '/some/otherpath/file2', etc...]
If I try to run the following code:
files = ['/home/media/Music/Ke$ha/song.mp3']
for file in files:
os.chmod(file, 0664)
It complains that it cannot find /home/media/Music/Ke$ha/song.mp3. Most likely (I guess) because the called shell tries to expand $ha, which is obviously wrong.
The 'Ke$ha' file is just an example, there are many more files with escape characters in it (e.g. /home/media/Music/Hill's fire/song.mp3)
The question I have is: How can I elegantly convince python and/or the shell to handle these files properly?
Kind regards,
Robert Nagtegaal.
You can do like this
files=["/home/media/Music/Ke$ha/song.mp3", "/home/media/Music/Hill's fire/song.mp3"]
import os,re
os.system("chmod 777 " + re.escape(files[i]))
How about this, a raw string? Also is your username 'media'?
files = [r'/home/media/Music/Ke$ha/song.mp3']
I'm following the python tutorial seen here (LINK) with this code:
# !/usr/bin/python
import os
import stat
filename = '/tmp/tmpfile'
mode = 0600|stat.S_IRUSR
# filesystem node specified with different modes
os.mknod(filename, mode)
That works well. But I want to write the file with group write permissions. But when I change mode to "Write by group" mode:
mode = 0600|stat.S_IWGRP
(from LINK2) the file runs without throwing an error, but the file doesn't have group write permissions. All the "mode" permissions work except group write and others write.
How can I get my python/uwsgi/nginx app to create files with group write permissions?
try this:
mode = stat.S_IFREG | stat.S_IWGRP | stat.S_IRUSR
from the help docstring:
mknod(filename [, mode=0600, device])
Create a filesystem node (file, device special file or named pipe)
named filename. mode specifies both the permissions to use and the
type of node to be created, being combined (bitwise OR) with one of
S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,
device defines the newly created device special file (probably using
os.makedev()), otherwise it is ignored.
P.S. try running umask in bash. If it returns something other that 0000 than it is automagically subtracting that value from what you specify (man 2 umask). Try running umask 0000 then running your python script again!
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 downloaded some scripts in both python and bash that prompt the user for command line input. Since I run these scripts often, I would like to automatically supply the input to the programs. I prefer not to modify the scripts. Is there a way to do it without modifying the original code?
[UPDATE] thanks to EnabrenTane's advice, it seems to work pretty well, until I got to a line that read password = getpass.getpass('password: '). It complains the following:
File "/usr/lib/python2.4/getpass.py", line 29, in unix_getpass
old = termios.tcgetattr(fd) # a copy to save
termios.error: (25, 'Inappropriate ioctl for device')
Any way to get around that?
Like this on bash: $ ./python_script < input.txt
edit:
Alternatively you could write your scripts to take ARGV as a file name to read from. You could reopen STDIN to the file and not have to change any other lines.
Since the responses in via stdin:
cat answers | yourscript.py
Due to the password requirement, I ended up using pexpect, a python module that automates user input.