Linux Script That Monitors File Changes Within Folders (Like Autospec Does!)

linux script that monitors file changes within folders (like autospec does!)

After reading replies to other posts, I found a post (now gone), I created this script :-

#!/bin/bash

sha=0
previous_sha=0

update_sha()
{
sha=`ls -lR . | sha1sum`
}

build () {
## Build/make commands here
echo
echo "--> Monitor: Monitoring filesystem... (Press enter to force a build/update)"
}

changed () {
echo "--> Monitor: Files changed, Building..."
build
previous_sha=$sha
}

compare () {
update_sha
if [[ $sha != $previous_sha ]] ; then changed; fi
}

run () {
while true; do

compare

read -s -t 1 && (
echo "--> Monitor: Forced Update..."
build
)

done
}

echo "--> Monitor: Init..."
echo "--> Monitor: Monitoring filesystem... (Press enter to force a build/update)"
run

How to run a shell script when a file or directory changes?

Use inotify-tools.

The linked Github page has a number of examples; here is one of them.

#!/bin/sh

cwd=$(pwd)

inotifywait -mr \
--timefmt '%d/%m/%y %H:%M' --format '%T %w %f' \
-e close_write /tmp/test |
while read -r date time dir file; do
changed_abs=${dir}${file}
changed_rel=${changed_abs#"$cwd"/}

rsync --progress --relative -vrae 'ssh -p 22' "$changed_rel" \
usernam@example.com:/backup/root/dir && \
echo "At ${time} on ${date}, file $changed_abs was backed up via rsync" >&2
done

How can I detect file accesses in Linux?

One option is to use strace:

strace -o logfile -eopen yourapp

This will log all file-open events, but it will impose a performance penalty that may be significant. It has the advantage of being easy to use however.

Another option is to use LD_PRELOAD. This corresponds to your option #2. The basic idea is to do something like this:

#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>

int open(const char *fn, int flags) {
static int (*real_open)(const char *fn, int flags);

if (!real_open) {
real_open = dlsym(RTLD_NEXT, "open");
}

fprintf(stderr, "opened file '%s'\n", fn);
return real_open(fn, flags);
}

Then build with:

gcc -fPIC -shared -ldl -o preload-example.so preload-example.c

And run your program with eg:

$ LD_PRELOAD=$PWD/preload-example.so cat /dev/null
opened file '/dev/null'

This has much less overhead.

Note, however, that there are other entry points for opening files - eg, fopen(), openat(), or one of the many legacy compatibility entry points:

00000000000747d0 g    DF .text      000000000000071c  GLIBC_2.2.5 _IO_file_fopen
0000000000068850 g DF .text 000000000000000a GLIBC_2.2.5 fopen
000000000006fe60 g DF .text 00000000000000e2 GLIBC_2.4 open_wmemstream
00000000001209c0 w DF .text 00000000000000ec GLIBC_2.2.5 posix_openpt
0000000000069e50 g DF .text 00000000000003fb GLIBC_2.2.5 _IO_proc_open
00000000000dcf70 g DF .text 0000000000000021 GLIBC_2.7 __open64_2
0000000000068a10 g DF .text 00000000000000f5 GLIBC_2.2.5 fopencookie
000000000006a250 g DF .text 000000000000009b GLIBC_2.2.5 popen
00000000000d7b10 w DF .text 0000000000000080 GLIBC_2.2.5 __open64
0000000000068850 g DF .text 000000000000000a GLIBC_2.2.5 _IO_fopen
00000000000d7e70 w DF .text 0000000000000020 GLIBC_2.7 __openat64_2
00000000000e1ef0 g DF .text 000000000000005b GLIBC_2.2.5 openlog
00000000000d7b10 w DF .text 0000000000000080 GLIBC_2.2.5 open64
0000000000370c10 g DO .bss 0000000000000008 GLIBC_PRIVATE _dl_open_hook
0000000000031680 g DF .text 0000000000000240 GLIBC_2.2.5 catopen
000000000006a250 g DF .text 000000000000009b GLIBC_2.2.5 _IO_popen
0000000000071af0 g DF .text 000000000000026a GLIBC_2.2.5 freopen64
00000000000723a0 g DF .text 0000000000000183 GLIBC_2.2.5 fmemopen
00000000000a44f0 w DF .text 0000000000000088 GLIBC_2.4 fdopendir
00000000000d7e70 g DF .text 0000000000000020 GLIBC_2.7 __openat_2
00000000000a3d00 w DF .text 0000000000000095 GLIBC_2.2.5 opendir
00000000000dcf40 g DF .text 0000000000000021 GLIBC_2.7 __open_2
00000000000d7b10 w DF .text 0000000000000080 GLIBC_2.2.5 __open
0000000000074370 g DF .text 00000000000000d7 GLIBC_2.2.5 _IO_file_open
0000000000070b40 g DF .text 00000000000000d2 GLIBC_2.2.5 open_memstream
0000000000070450 g DF .text 0000000000000272 GLIBC_2.2.5 freopen
00000000000318c0 g DF .text 00000000000008c4 GLIBC_PRIVATE __open_catalog
00000000000d7b10 w DF .text 0000000000000080 GLIBC_2.2.5 open
0000000000067e80 g DF .text 0000000000000332 GLIBC_2.2.5 fdopen
000000000001e9b0 g DF .text 00000000000003f5 GLIBC_2.2.5 iconv_open
00000000000daca0 g DF .text 000000000000067b GLIBC_2.2.5 fts_open
00000000000d7d60 w DF .text 0000000000000109 GLIBC_2.4 openat
0000000000068850 w DF .text 000000000000000a GLIBC_2.2.5 fopen64
00000000000d7d60 w DF .text 0000000000000109 GLIBC_2.4 openat64
00000000000d6490 g DF .text 00000000000000b6 GLIBC_2.2.5 posix_spawn_file_actions_addopen
0000000000121b80 g DF .text 000000000000008a GLIBC_PRIVATE __libc_dlopen_mode
0000000000067e80 g DF .text 0000000000000332 GLIBC_2.2.5 _IO_fdopen

You may need to hook all of these for completeness - at the very least, the ones not prefixed with _ should be hooked. In particular, be sure to hook fopen seperately, as the libc-internal call from fopen() to open() is not hooked by a LD_PRELOAD library.

A similar caveat applies to strace - there is the 'openat' syscall as well, and depending on your architecture there may be other legacy syscalls as well. But not as many as with LD_PRELOAD hooks, so if you don't mind the performance hit, it may be an easier option.

how to get value in text field

In javascript the plus (+) sign is used for string concatenation, so

$('#qtyProductID_'+productIDVal[1]).attr('value'); 

but just like brad said, it can be written as

$('#qtyProductID_'+productIDVal[1]).val(); 

because jQuery offers a unified method of getting values from form input fields, not just <input>, but <select> and <textarea> as well.



Related Topics



Leave a reply



Submit