I am writing a python code on eclipse and want to open a file that is present in Downloads folder. I am using MAC OSX 10.8.2. I tried with f=os.path.expanduser(\"~/Downloa
It is most likely a permissions issue, if you try your code in the Python interpreter you will probably receive a "Permission denied" error from the shell when you call subprocess.Popen. If this is the case then you will need to make the file a minimum of 700 (it's probably 644 by default) and you'll probably want 744.
Try the code in the Python interpreter and check for the "Permission denied" error, if you see that then do this in a shell:
chmod 744 ~/Downloads/DeletingDocs.txt
Then run the script. To do it all in Python you can use os.system:
import os
import subprocess
filename = "~/Downloads/DeletingDocs.txt"
os.system("chmod 744 "+filename)
ss=subprocess.Popen(filename, shell=True)
ss.communicate()
The reason it "just works" in Windows is because Windows doesn't support file permission types (read, write and execute) in the same way as *nix systems (e.g. Linux, BSD, OS X, etc.) do.
I am hesitant to answer because this question was double-posted and is confusingly phrased, but... if you want to "open" the file in OSX using the default editor, then add the open
command to your subprocess. This works for me:
subprocess.Popen("open myfile.txt",shell=True)
from os.path import baspath, expanduser
filepath = abspath(expanduser("~/") + '/Downloads/DeletingDocs.txt')
print('Opening file', filepath)
with open(filepath, 'r') as fh:
print(fh.read())
Take note of OSX file-handling tho, the IO is a bit different depending on the filetype.
For instance, a .txt
file which under Windows would be considered a "plain text-file" is actually a compressed data-stream under OSX because OSX tries to be "smart" about the storage space.
This can literately ruin your day unless you know about it (been there, had the headache.. moved on)
When double-clicking on a .txt
file in OSX for instance normally the text-editor pops up and what it does is call for a os.open()
instead of accessing it on a lower level which lets OSX middle layers do disk-area|decompression pipe|file-handle -> Texteditor
but if you access the file-object on a lower level you'll end up opening the disk-area where the file is stored and if you print the data you'll get garbage because it's not the data you'd expect.
So try using:
import os
fd = os.open( "foo.txt", os.O_RDONLY )
print(os.read(fd, 1024))
os.close( fd )
And fiddle around with the flags.
I honestly can't remember which of the two opens the file as-is from disk (open()
or os.open()
) but one of them makes your data look like garbage and sometimes you just get the pointer to the decompression pipe (giving you like 4 bytes of data even tho the text-file is hughe).
from time import ctime
from os.path import getmtime, expanduser, abspath
from os import walk
for root, dirs, files in walk(expanduser('~/')):
for fname in files:
modtime = ctime(getmtime(abspath(root + '/' + fname)))
print('File',fname,'was last modified at',modtime)
And if the time differs from your last check, well then do something cool with it. For instance, you have these libraries for Python to work with:
And MANY more, so instead of opening an external application as your first fix, try opening them via Python and modify to your liking instead, and only as a last resort (if even then) open external applications via Popen.
But since you requested it (sort of... erm), here's a Popen approach:
from subprocess import Popen, PIPE, STDOUT
from os.path import abspath, expanduser
from time import sleep
run = Popen('open -t ' + abspath(expanduser('~/') + '/example.txt'), shell=True, stdout=PIPE, stdin=PIPE, stderr=STDOUT)
##== Here's an example where you could interact with the process:
##== run.stdin.write('Hey you!\n')
##== run.stdin.flush()
while run.poll() == None:
sleep(1)
This will print a files contents every time it's changed.
with open('test.txt', 'r') as fh:
import time
while 1:
new_data = fh.read()
if len(new_data) > 0:
fh.seek(0)
print(fh.read())
time.sleep(5)
How it works:
The regular file opener with open() as fh
will open up the file and place it as a handle in fh
, once you call .read()
without any parameters it will fetch the entire contents of the file.
This in turn doesn't close the file, it simply places the "reading" pointer at the back of the file (lets say at position 50 for convenience).
So now your pointer is at character 50 in your file, at the end.
Wherever you write something in your file, that will put more data into it so the next .read()
will fetch data from position 50+ making the .read()
not empty, so we place the "reading" pointer back to position 0 by issuing .seek(0)
and then we print all the data.
Combine that with os.path.getmtime()
to fine any reversed changes or 1:1 ratio changes (replacing a character mis-spelling etc).