How to control a newly created file in a directory using bash?

I have a log directory consisting of many log files, one log file is created after a system event occurs. I want to write an oneline bash script that always controls the list of files and displays the contents of the newly created file on the terminal. Here's what it looks like:

Currently, all I have is to display the contents of the entire directory:

for f in *; do cat $f; done

It lacks the monitoring function that I wanted. One of the limitations of my system is that I do not have a command watch . I also don't have a package manager to install fancy tools. Raw BSD is all I have. I have tail, I was thinking of something like tail -F $(ls)that, but it pushes each file instead of a list of files.

In conclusion, I want to modify my script so that I can control the contents of all newly created files.

+4
source share
6 answers
+2

inotifywait

:

  • :

    ext=(php css other)
    while :;do
        subname=''
        ((RANDOM%10))||printf -v subname -- "-%04x" $RANDOM
        date >/tmp/test$subname.${ext[RANDOM%3]}
        sleep 1
      done
    

    /tmp/test.php, /tmp/test.css /tmp/test.other, ( 1 /10) /tmp/test-XXXX.[css|php|other], XXXX .

  • :

    waitPaths=(/{home,tmp})
    while read file ;do
        if [ "$file" ] &&
         ( [ -z "${file##*.php}" ] || [ -z  "${file##*.css}" ] ) ;then
            (($(stat -c %Y-%X $file)))||echo -n new
            echo file: $file, content:
            cat $file
        fi
      done < <(
        inotifywait -qme close_write --format %w%f ${waitPaths[*]}
    )
    

    - :

    file: /tmp/test.css, content:
    Tue Apr 26 18:53:19 CEST 2016
    file: /tmp/test.php, content:
    Tue Apr 26 18:53:21 CEST 2016
    file: /tmp/test.php, content:
    Tue Apr 26 18:53:23 CEST 2016
    file: /tmp/test.css, content:
    Tue Apr 26 18:53:25 CEST 2016
    file: /tmp/test.php, content:
    Tue Apr 26 18:53:27 CEST 2016
    newfile: /tmp/test-420b.php, content:
    Tue Apr 26 18:53:28 CEST 2016
    file: /tmp/test.php, content:
    Tue Apr 26 18:53:29 CEST 2016
    file: /tmp/test.php, content:
    Tue Apr 26 18:53:30 CEST 2016
    file: /tmp/test.php, content:
    Tue Apr 26 18:53:31 CEST 2016
    

:

  • waitPaths=(/{home,tmp}) waitPaths=(/home /tmp) : waitPaths=/var/log
  • if , *.php *.css
  • (($(stat -c %Y-%X $file)))||echo -n new .
  • inotifywait
    • -q, quiet ( , )
    • -m : , .
    • -e close_write .
    • -f %w%f : path/file

:

:

  • (CLOSE_WRITE | CREATE)
  • , CLOSE_WRITE.

Ctrl + C , :

waitPaths=(/{home,tmp})
declare -A newFiles
while read path event file; do
    if [ "$file" ] && ( [ -z "${file##*.php}" ] || [ -z "${file##*.css}" ] ); then
        if [ "$event" ] && [ -z "${event//*CREATE*}" ]; then
            newFiles[$file]=1
        else
            if [ "${newFiles[$file]}" ]; then
                unset newFiles[$file]
                echo NewFile: $file, content:
                sed 's/^/>+ /' $file
            else
                echo file: $file, content:
                sed 's/^/>  /' $path/$file
            fi
        fi
    fi
done < <(inotifywait -qme close_write -e create ${waitPaths[*]})

:

file: test.css, content:
>  Tue Apr 26 22:16:02 CEST 2016
file: test.php, content:
>  Tue Apr 26 22:16:03 CEST 2016
NewFile: test-349b.css, content:
>+ Tue Apr 26 22:16:05 CEST 2016
file: test.css, content:
>  Tue Apr 26 22:16:08 CEST 2016
file: test.css, content:
>  Tue Apr 26 22:16:10 CEST 2016
file: test.css, content:
>  Tue Apr 26 22:16:13 CEST 2016
+2

,

, , :

:

wpath=/var/log
while : ;do
    while read -a crtfile ;do
        if [ "${crtfile:0:1}" = "-" ] &&
          [ "${crtfile[8]##*.}" != "gz" ] &&
          [ "${files[${crtfile[8]}]:-0}" -lt ${crtfile[4]} ] ;then
            printf "\e[47m## %-14s :- %(%a %d %b %y %T)T ##\e[0m\n" ${crtfile[8]} -1
            tail -c +$[1+${files[${crtfile[8]}]:-0}] $wpath/${crtfile[8]}
            files[${crtfile[8]}]=${crtfile[4]}
        fi
    done < <( /bin/ls -l $wpath )
    sleep 1
done

( , .gz) /var/log, , .

:

  • :

    ext=(php css other)
    ( while :; do
        subname=''
        ((RANDOM%10)) || printf -v subname -- "-%04x" $RANDOM
        name=test$subname.${ext[RANDOM%3]}
        printf "%-16s" $name
        { 
            date +"%a %d %b %y %T" | tee /dev/fd/5
            fortune /usr/share/games/fortunes/bofh-excuses
        } >> /tmp/$name
        sleep 1
    done ) 5>&1
    

    fortune, BOFH.

    fortune, :

    LANG=C ext=(php css other)
    ( while :; do
        subname=''
        ((RANDOM%10)) || printf -v subname -- "-%04x" $RANDOM
        name=test$subname.${ext[RANDOM%3]}
        printf "%-16s" $name
        { 
            date +"%a %d %b %y %T" | tee /dev/fd/5
            for ((1; RANDOM%5; 1))
            do
                printf -v str %$[RANDOM&12]s
                str=${str// /blah, }
                echo ${str%, }.
            done
        } >> /tmp/$name
        sleep 1
    done ) 5>&1
    

    - :

    test.css        Thu 28 Apr 16 12:00:02
    test.php        Thu 28 Apr 16 12:00:03
    test.other      Thu 28 Apr 16 12:00:04
    test.css        Thu 28 Apr 16 12:00:05
    test.css        Thu 28 Apr 16 12:00:06
    test.other      Thu 28 Apr 16 12:00:07
    test.php        Thu 28 Apr 16 12:00:08
    test.css        Thu 28 Apr 16 12:00:09
    test.other      Thu 28 Apr 16 12:00:10
    test.other      Thu 28 Apr 16 12:00:11
    test.php        Thu 28 Apr 16 12:00:12
    test.other      Thu 28 Apr 16 12:00:13
    
  • :

    declare -A files
    wpath=/tmp
    while :; do
        while read -a crtfile; do
            if [ "${crtfile:0:1}" = "-" ] && [ "${crtfile[8]:0:4}" = "test" ] &&
             ( [ "${crtfile[8]##*.}" = "css" ] || [ "${crtfile[8]##*.}" = "php" ] ) &&
             [ "${files[${crtfile[8]}]:-0}" -lt ${crtfile[4]} ]; then
                printf "\e[47m## %-14s :- %(%a %d %b %y %T)T ##\e[0m\n" ${crtfile[8]} -1
                tail -c +$[1+${files[${crtfile[8]}]:-0}] $wpath/${crtfile[8]}
                files[${crtfile[8]}]=${crtfile[4]}
            fi
        done < <(/bin/ls -l $wpath)
        sleep 1
    done
    

    • ( -),
    • , test,
    • , css php,
    • ,
    • ,
      • tail -c
    • 1

    - :

    ## test.css       :- Thu 28 Apr 16 12:00:09 ##
    Thu 28 Apr 16 12:00:02
    BOFH excuse #216:
    
    What office are you in? Oh, that one.  Did you know that your building was built over the universities first nuclear research site? And wow, aren't you the lucky one, your office is right over where the core is buried!
    Thu 28 Apr 16 12:00:05
    BOFH excuse #145:
    
    Flat tire on station wagon with tapes.  ("Never underestimate the bandwidth of a station wagon full of tapes hurling down the highway" Andrew S. Tannenbaum) 
    Thu 28 Apr 16 12:00:06
    BOFH excuse #301:
    
    appears to be a Slow/Narrow SCSI-0 Interface problem
    ## test.php       :- Thu 28 Apr 16 12:00:09 ##
    Thu 28 Apr 16 12:00:03
    BOFH excuse #36:
    
    dynamic software linking table corrupted
    Thu 28 Apr 16 12:00:08
    BOFH excuse #367:
    
    Webmasters kidnapped by evil cult.
    ## test.css       :- Thu 28 Apr 16 12:00:10 ##
    Thu 28 Apr 16 12:00:09
    BOFH excuse #25:
    
    Decreasing electron flux
    ## test.php       :- Thu 28 Apr 16 12:00:13 ##
    Thu 28 Apr 16 12:00:12
    BOFH excuse #3:
    
    electromagnetic radiation from satellite debris
    

    Nota: - , .

+2

, , script :

#!/bin/bash

[ ! -d "$1" ] && {
    printf "error: argument is not a valid directory to monitory.\n"
    exit 1
}

while :; fname="$1/$(inotifywait -q -e modify -e create --format '%f' "$1")"; do
    cat "$fname"
done

, , cat . :

$ bash watchdir.sh my_logdir &

cat my_logdir.

+1

Although this is not very pleasant, the following gives (and repeats) the last 50 lines of the newest file in the current directory:

while true; do tail -n 50 $(ls -Art | tail -n 1); sleep 5; done
0
source

You can update every minute with cronjob:

$crontabe -e


 * * * * * /home/script.sh

if you need to update in less than a minute, you can use the "sleep" command inside your script.

0
source

All Articles