0
I wrote a backupsystem depending on extended file attributes. Many editing programs (like vim) remove these attributes from the files they edit. My idea is to hook any bash command referencing a file, so that the attributes get saved into a variable or temp file. A post-command-hook then reloads these attributes. I found out that one can run an arbitrary command before and after every bash command using trap i.e. adding:
trap date DEBUG
in .bashrc will run the date command before any bash command. However, I was not able to limit this to bash commands working on a file and get the filename. I'd love to be able to write something like this:
trap 'getfattr -d {} > /tmp/{}.xattr' FILECOMMAND
FILECOMMAND would imply that this hook is only exeuted for commands operating on a file
{} would be the absolute filepath of the file that is operated on
Another hook after the command could be written to override the file attributes of {} with the content of /tmp/{}.xattr
Is this somehow possible?
Another vague idea would be to hook systemcalls writing to files and executing some code in the hook methods, preserving the file attributes.
Any constructive input would be highly appreciated.
1When you edit a file, your editor may save changes in place. But at the same time any other process may read inconsistent, partially changed data from the file; power failure or a bug may occur mid-change and leave you a file that is neither the old version, nor a new one (data loss!). Solution: save the edited data as a separate file and then
mv
it to the old name.mv
is atomic (unless between filesystems) so in case of trouble you have either the old file or the whole new one. Maybe it's not programs "remove attributes" but rather "fail or neglect to copy attributes to the new file". – Kamil Maciorowski – 2019-03-12T18:02:48.080Thank you for pointing that out. The fileId changes when editing a file, which verifies that a new file was created. It is probably a good idea to work on the path then instead of the file itself – openGLisLife – 2019-03-12T18:38:58.830
Create a vi alias wrapper. Pass $@ to the preVi script, to vi and to postVi. Along the lines of
alias vi='preVi $@; vi $@; postVi $@'
– Ted D. – 2019-03-12T19:13:15.303This hasn't really worked for me, but led me on the right path. I ended up creating a function in my .bashrc and setting it as an alias for vi:
alias vi='Vi'; function Vi () {tempPath="/tmp/$1.attr"; getfattr -d "$1" > "$tempPath"; /usr/bin/vi "$1"; setfattr --restore="$tempPath";}
this works for vi and could be easily done for any command manually. Any ideas to make this more generic, so it works for every command? – openGLisLife – 2019-03-12T22:37:39.837