Skip to content

Instantly share code, notes, and snippets.

@weshouman
Last active December 9, 2019 14:41
Show Gist options
  • Save weshouman/ab6bd9708f5777cea3eaeb5e3fd864c4 to your computer and use it in GitHub Desktop.
Save weshouman/ab6bd9708f5777cea3eaeb5e3fd864c4 to your computer and use it in GitHub Desktop.
diff directory tree upon changes after executing a script

Sometimes we don't know which file exactly changed upon execution, usually it's something in the /var/log/ and may be in the tmp or even next to the application executable.

Method 1 - Size Differences

To handle such a situation, we may get the logical size (not physical size) of all the non-zero files then run the script.sh then get the new non-zero sizes and diff the outputs to get the specific files that got a change in size

TL;DR

Put the following script in .bashrc, and use it like that diff_sizes script.sh

# Use the file names, not the relative path to them, as we grep like that ./PRE_DU
PRE_DU=sizes_before.du
POST_DU=sizes_after.du

diff_sizes() { du -ab | grep -Pv "^0\t" | grep -Pv "[0-9]+\t./(${PRE_DU})|(${POST_DU})" >${PRE_DU}; $1; du -ab | grep -Pv "^0\t" | grep -Pv "[0-9]+\t./(${PRE_DU})|(${POST_DU})+" >${POST_DU}; diff ${PRE_DU} ${POST_DU}; };

Breakdown

du

  • -a get all the files alongside with the directories
  • -b get the logical size (in bytes) instead of physical size (in blocks)

grep

  • -P Perl style
  • -v Inverse search
  • grep -Pv "^0\t" skip all the zero sized files
  • grep -Pv "[0-9]+\t./(${PRE_DU})|(${POST_DU})" skip the sizes_before.du and sizes_after.du
  • >${PRE_DU} save the output to sizes_before.du
  • >${POST_DU} save the output to sizes_after.du

a Cleaner not tested yet version is

PRE_DU=sizes_before.du
POST_DU=sizes_after.du

diff_sizes() {
  du -ab | \
  grep -Pv "^0\t" | \
  grep -Pv "[0-9]+\t./(${PRE_DU})|(${POST_DU})" >${PRE_DU}; \
  $1; \
  du -ab | \
  grep -Pv "^0\t" | \
  grep -Pv "[0-9]+\t./(${PRE_DU})|(${POST_DU})+" >${POST_DU}; \
  diff ${PRE_DU} ${POST_DU}; \
};

Method 2 - Size and Date Differences

In case of requiring the date too, we'll have to use some other tool than du, specifically we'll be using ls however ls won't iterate over all the files by itself, so we'll combine both find and ls to replace du, such command will be find . -type f -exec ls -al {} +.

Selecting the size, date and name will take place using awk, we'll need to be careful with the escaping (we need to escape both $ and " to be able to set an alias).

For awk we could use simple print method with many quotations, however the need of making tabular format with tabs and sufficient spaces moves us to the use of printf.

Columns $5 till $9 are known based on the output of find . -type f -exec ls -al {} +.

Also we'll need to modify the grep -Pv "[0-9]\t./(${PRE_DU})|(${POST_DU})" to be grep -Pv " ./(${PRE_DU})|(${POST_DU})$" so it's more generic to accept the date too

Following is the updated script with all those changes

alias file_sizes_and_dates="find . -type f -exec ls -al {} + | awk {'printf(\"%8s\t%s %2s %5s %s\n\",\$5,\$6,\$7,\$8,\$9)'}"

PRE_DU=sizes_before.du
POST_DU=sizes_after.du

diff_sizes_and_dates() { file_sizes_and_dates | grep -Pv "^\s*0\t" | grep -Pv " ./(${PRE_DU})|(${POST_DU})$" >${PRE_DU}; $1; file_sizes_and_dates | grep -Pv "^\s*0\t" | grep -Pv " ./(${PRE_DU})|(${POST_DU})$" >${POST_DU}; diff ${PRE_DU} ${POST_DU}; };
echo Hello World >> /tmp/hello_test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment