Linux: Triggering Shell Command on File Save

Linux: Triggering Shell Command On File Save

Try inotify-tools. I'm having problems copying the link (sorry), but there is a wiki on GitHub which yu should be able to find with G-search-engine.

linux (and OSX) shell command to execute every time file is saved

There is a linux kernel feature called INotify that watches the file system for any changes. It is exposed as a number of system APIs.

For scripting, there is a package called inotify-tools that gives scripting access to the notification system.

Run a shell command when a file is added

I don't know how people are uploading content to this folder, but you might want to use something lower-tech than monitoring the directory with inotify.

If the protocol is FTP and you have access to your FTP server's log, I suggest tailing that log to watch for successful uploads. This sort of event-triggered approach will be faster, more reliable, and less load than a polling approach with traditional cron, and more portable and easier to debug than something using inotify.

The way you handle this will of course depend on your FTP server. I have one running vsftpd whose logs include lines like this:

Fri May 25 07:36:02 2012 [pid 94378] [joe] OK LOGIN: Client "10.8.7.16"
Fri May 25 07:36:12 2012 [pid 94380] [joe] OK UPLOAD: Client "10.8.7.16", "/path/to/file.zip", 8395136 bytes, 845.75Kbyte/sec
Fri May 25 07:36:12 2012 [pid 94380] [joe] OK CHMOD: Client "10.8.7.16", "/path/to/file.zip 644"

The UPLOAD line only gets added when vsftpd has successfully saved the file. You could parse this in a shell script like this:

#!/bin/sh

tail -F /var/log/vsftpd.log | while read line; do
if echo "$line" | grep -q 'OK UPLOAD:'; then
filename=$(echo "$line" | cut -d, -f2)
if [ -s "$filename" ]; then
# do something with $filename
fi
fi
done

If you're using an HTTP upload tool, see if that tool has a text log file it uses to record incoming files. If it doesn't consider adding some sort of logger function to it, so it'll produce logs that you can tail.

How to automatically execute a shell command after saving a file in Vim?

This runs run_tests.sh after any file is saved, with the current filename as the only parameter:

:autocmd BufWritePost * !run_tests.sh <afile>

View the auto-command with:

:autocmd BufWritePost *

And remove all auto-commands from the previous with:

:autocmd! BufWritePost *

Saving input before running command bash

Your modified script...

#!/usr/bin/env bash

mylog() {
local output="log"

# This is the key part right here. The 'tac' command here
# prints stdin in reverse. To do this, it must read _all_
# of stdin, so it buffers until it reads everything. Of course,
# we must use two 'tac's so stdin doesn't actually get reversed.
# You could also use `sponge(1)` here, but that does not come standard
# on all Linux distributions / MacOS
local buffer="$("$@" | tac | tac)"

# Nothing below will be printed until 'buffer' is completely filled with stdin
{
echo "----------------"
echo "$@"
echo "----------------"
echo "$buffer"
echo
} >> "$output"

printf "%s" "$buffer"
}

rm -f log
mylog cat file.txt | mylog sort >/dev/null

The resulting log

----------------
cat file.txt
----------------
bravo
alfa
charlie
delta
echo

----------------
sort
----------------
alfa
bravo
charlie
delta
echo

How to execute shell script and save in text file command through java in linux

Use a ProcessBuilder. It makes it easy to redirect output of a command to file as shown below:

new ProcessBuilder("echo", "hello").redirectOutput(new File("output.txt")).start();

If you want to append to the output file:

new ProcessBuilder("echo", "hello").redirectOutput(Redirect.appendTo(new File("output.txt"))).start();

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

Time multiple commands running in parallel in shell and save it in file

With some help I was able to find a way around this issue what worked for me is this

(time my_commnad1 && echo "output 1" >> my_log_file.log) 2>> my_log_file.log &

(time my_commnad2 && echo "output 2" >> my_log_file.log) 2>> my_log_file.log &

(time my_commnad3 && echo "output 3" >> my_log_file.log) 2>> my_log_file.log &

(time my_commnad4 && echo "output 4" >> my_log_file.log) 2>> my_log_file.log &
wait

the output i got was like this were the time is above the tag mentioned:

real    2m39.892s
user 8m37.383s
sys 0m3.338s
output 1:

real 2m39.892s
user 8m37.383s
sys 0m3.338s
output 2:

real 2m39.892s
user 8m37.383s
sys 0m3.338s
output 3:

real 2m39.892s
user 8m37.383s
sys 0m3.338s
output 4:

Moreover I couldn't test Jacek Zaleski's answer properly though as it gave me some errors with syntax when I tried it in my case.Thanks anyway to everyone for the time and effort. Hope this helps someone.



Related Topics



Leave a reply



Submit