On OS X, there is an API to create a "bookmark" for a given file on disk, which will track its target even if it is moved or renamed. An OS X application could then serialise the bookmark, store it by whatever means it wants, and at some later date—perhaps after being quit and re-launched—deserialise the bookmark and resolve the file path from it.
Does anything comparable exist for Linux?
http://en.wikipedia.org/wiki/Inotify
I guess that inotify is what you want.
With inotify, you can monitor following events for a file:
IN_ACCESS - read of the file
IN_MODIFY - last modification
IN_ATTRIB - attributes of file change
IN_OPEN - open of file
IN_CLOSE_WRITE - sent when a file opened for writing is closed
IN_CLOSE_NOWRITE - sent when a file opened not for writing is closed
IN_MOVED_FROM and IN_MOVED_TO - when the file is moved or renamed
IN_DELETE - a file/directory deleted
IN_CREATE - a file in a watched directory is created
IN_DELETE_SELF - file monitored is deleted
Related
I'll start by mentioning that I've no knowledge in Python but read online that it could help me with my situation.
I'd like to do a few things using (I believe?) a Python script.
I have a bunch of .yml files that I want to transfer the contents into one main .yml file (let's call it Main.yml). However, I'd also like to be able to take the name of each individual .yml and add it before it's content into Main.yml as "##Name". If possible, the script would look like each file in a directory, instead of having to list every .yml file I want it to look for (my directory in question only contains .yml files). Not sure if I need to specify, but just in case: I want to append the contents of all files into Main.yml & keep the indentation (spacing). P.S. I'm on Windows
Example of what I want:
File: Apes.yml
Contents:
Documentation:
"Apes":
year: 2009
img: 'link'
After running the script, my Main.yml would like like:
##Apes.yml
Documentation:
"Apes":
year: 2009
img: 'link'
I'm just starting out in Python too so this was a great opportunity to see if my newly learned skills work!
I think you want to use the os.walk function to go through all of the files and folders in the directory.
This code should work - it assumes your files are stored in a folder called "Folder" which is a subfolder of where your Python script is stored
# This ensures that you have the correct library available
import os
# Open a new file to write to
output_file = open('output.txt','w+')
# This starts the 'walk' through the directory
for folder , sub_folders , files in os.walk("Folder"):
# For each file...
for f in files:
# create the current path using the folder variable plus the file variable
current_path = folder+"\\"+f
# write the filename & path to the current open file
output_file.write(current_path)
# Open the file to read the contents
current_file = open(current_path, 'r')
# read each line one at a time and then write them to your file
for line in current_file:
output_file.write(line)
# close the file
current_file.close()
#close your output file
output_file.close()
I have experienced a weird behaivour on our production environment.
We have a NFS and a linux server which runs our application.
On the linux server there is a mount to the NFS,
from: /configuration/data (on the NFS)
To: /software (on the linux server).
Which the application modifies the files there periodically.
Some time ago someone accidentally moved to "data" folder to: /configuration/other/data
The application kept running without any side effect, and modified the files periodically, and the files inside /configuration/other/data also changed even though the mount (/configuration/data) point to nothing.
I guess there is a shortcut to the origin of the mount which being modified on the folder relocation, but that just a guess.
I would like to know why and how this behaivour is possible, and how it works internally.
and how it works internally.
File descriptor refers to a file. You can move the file, you can remove the file - the file descriptor refers to the same "entity". So in shell you can for example:
# open fd 10 to refer to /tmp/10
$ exec 10>/tmp/10
# Just write something so that it works
$ echo abc >&10
$ cat /tmp/10
abc
# Move the file to some dir
$ mkdir /tmp/dir
$ mv /tmp/10 /tmp/dir/10
# now it still writes to the same "file", even when moved
$ echo def >&10
$ cat /tmp/dir/10
abc
def
# You can remove the file and still access it
# The file still "exists"
$ exec 11</tmp/dir/10
$ rm /tmp/dir/10
$ echo 123 >&10
$ cat <&11
abc
def
123
Creating a file descriptor to a file and then removing the file is typically in C programs:
char *filename = mkstemp(...);
int fd = open(filename);
unlink(filename);
// use fd
The file is really "removed" when there are no links to it - when the last file descriptor is closed. Research posix file descriptors and see for example man 2 unlink and other resources explaining what is a file descriptor.
Most probably you application has continously opened file descriptors to files inside /configuration/data, so after the file is moved, the data become available at the new location but application still uses same file descriptors.
Upon looping a directory to delete txt files ONLY - a message is returned indicating The System cannot find the file specified: 'File.txt'.
I've made sure the txt files that I'm attempting to delete exist in the directory I'm looping. I've also checked my code and to make sure it can see my files by printing them in a list with the print command.
import os
fileLoc = 'c:\\temp\\files'
for files in os.listdir(fileLoc):
if files.endswith('.txt'):
os.unlink(files)
Upon initial execution, I expected to see all txt files deleted except for other non-txt files. The actual result was an error message "FileNotFoundError: [WinError 2] The system cannot find the file specified: 'File.txt'.
Not sure what I'm doing wrong, any help would be appreciated.
It isn't found because the the path you intended to unlink is relative to fileLoc. In fact with your code, the effect is to unlink the file relative to the current working directory. If there were *.txt files
in the cwd then the code would have unfortunate side-effects.
Another way to look at it:
Essentially, by analogy, in the shell what you're trying to do is equivalent to this:
# first the setup
$ mkdir foo
$ touch foo/a.txt
# now your code is equvalent to:
$ rm *.txt
# won't work as intended because it removes the *.txt files in the
# current directory. In fact the bug is also that your code would unlink
# any *.txt files in the current working directory unintentionally.
# what you intended was:
$ rm foo/*.txt
The missing piece was the path to the file in question.
I'll add some editorial: The Old Bard taught us to "when in doubt, print variables". In other words, debug it. I don't see from the OP an attempt to do that. Just a thing to keep in mind.
Anyway the new code:
Revised:
import os
fileLoc = 'c:\\temp\\files'
for file in os.listdir(fileLoc):
if file.endswith('.txt'):
os.unlink(os.path.join(fileLoc,file))
The fix: os.path.join() builds a path for you from parts. One part is the directory (path) where the file exists, aka: fileLoc. The other part is the filename, aka file.
os.path.join() makes a whole valid path from them using whatever OS directory separator is appropriate for your platform.
Also, might want to glance through:
https://docs.python.org/2/library/os.path.html
I am opening some VTU files from Directory X and there are other output files in that directory (for example log.txt) that I want to open via a plugin. If I do a os.getcwd() I end up in ParaViews installation directory. What I want is the directory of the VTU files I loaded BEFORE applying the plugin... So basically the start Point of the Pipline.
You could do something like this to get the reader
myreader = FindSource('MyReader')
then get the file name via the FileName attribute
myreader.FileName
Currently I have the following cron.file formula
date > system_cron:
cron.file:
- name: salt://crons/cron_jobs
- source_hash: "md5sum=895dcbbddd27bfa77056ef8c8340549a"
- user: security
But this updates the crontab each time the highstate is run event though the cron_jobs file has not changed and hence the state is the same.
Is there a way to stop creating temp crontab file each time highstate is run when using cron.file
I found that this happens when you have blank lines at the end of the file, or if you have dos line endings instead of unix line endings. Once this has been changed, the file will only be updated when it has changed.
Please note: as you have placed the file in "salt://", you don't need source_hash. This is only required for remote (i.e. http) files.