Script works for linux but not mac

hi all,

made a script and it works for linux but not for mac, here it is

#!/bin/bash

echo "please enter in the location where you want the log files to be saved (press tab to auto-complete)"
read -e log

echo "please enter in minutes how long you want to monitor disk usage, this excludes remote file systems"
read min
echo "please wait while I monitor disk usage"

hn=$(hostname)
dt=$(date "+%y%m%d%H%M")
df1=$log/disk_usage/$hn/$dt.df1.txt
df2=$log/disk_usage/$hn/$dt.df2.txt
loc=$log/disk_usage/$hn/$dt.loc.txt
list=$log/disk_usage/$hn/$dt.list.txt

mkdir -p "$log"/disk_usage/"$hn"

past=$(date "+%y-%m-%d %H:%M:%S")

df -l > "$df1" && sleep "$min"m

df -l > "$df2"

diff "$df1" "$df2" | awk '{print $7}' | sort | uniq > "$loc"

sed -i '/^$/d' "$loc"
sed -i '/Mounted/d' "$loc"

pres=$(date "+%y-%m-%d %H:%M:%S")

while IFS= read -r line; do
find $line -newerat "$past" ! -newerat "$pres" -type f -exec ls -lah {} + >> "$list"
done < "$loc"

echo "the log can be found below"
echo ""$log"/disk_usage/"$hn"/"$dt".list.txt"`

the commands that dont work on mac when i run the script are

sed -i '/^$/d' "$loc"
find $line -newerat "$past" ! -newerat "$pres" -type f -exec ls -lah {} + >> "$list"

why dont these work as i thought there unix commands?

thanks,
rob

I edited your code sample iwth the proper use of the markdown tags. Please be careful next time.
When you say "it works for linux but not for mac", in what way don't they work?
Any error messages? Wrong results?
have you tried running your script with the set -x enabled?
P.S. most likely your Linux based script takes advantages of the GNU functionality/extensions to some of the basic tools (e.g. sed and find) which don't exist in the other non-GNU distributions.

1 Like

got rid of "sed -i" altogether and using just one line

diff "$df1" "$df2" | awk '{print $10}' | sed '/Mounted/d' | sed '/Volumes/d' | sed '/^$/d' | sort | uniq > "$loc"

1 Like

probably could be simplified:

diff "$df1" "$df2" | awk 'NF && !/Mounted|Volumes/ {print $10}' | sort -u > "$loc"
2 Likes

thanks vgersh99!!!!

can anyone explain this to me which i dont understand

find / ! -ipath "/private*" -newerat 20-06-19 ! -newerat 20-06-19 -type f -exec ls -lah {} \;
find: /private/var/db/fpsd/dvp: Operation not permitted
find: /private/var/db/ConfigurationProfiles/Store: Operation not permitted

as you can see the above im excluding the "path /private" but its showing me it

but if i exclude the commands

-newerat 20-06-19 ! -newerat 20-06-19 it works

any idea why this is?!?

For multi-line code the markdown tags must be on separate lines. Please use the icons at the top of the editor to place proper markdowns!

You must use -prune to not descend into it, -path descends (running into the "access denied") then filters.
-prune is true when it prunes, so you must continue with -o (or, otherwise) for all the other items.
(And if you have further -o you need \( \). The simply chained conditions use implicit -a at a higher precedence)

find / -ipath "/private" -prune -o -newerat 20-06-19 ! -newerat 20-06-19 -type f -exec ls -lah {} \;
2 Likes

do you mean like this

find / -path "/proc*" -prune -o -path "/dev*" -prune -o -path "/sys*" -prune -o -path "/usr*" -prune -path "/var*" -prune -o -type f

Yes that should work, but one -o seems to be missing.
Note if you do not have an explicit action, there is an implicit -print action for each -o branch.
And you only need to prune=skip a process tree once so -path /proc skips only this (not a /proc1 or a /processes)
And with paranthesis you can make it shorter (need to be escaped for the shell)

find / \( -path /proc -o -path /dev -o -path /sys -o -path /usr -o -path /var \) -prune -o -type f -print

The explicit -print suppresses an implicit print for the pruned directories.

2 Likes

thanks @MadeInGermany

can i run the exec command after this?

You mean -exec? Yes you can use it after or instead of the -print.

1 Like

i ahve tested it with the read command and works a treat

[root@scripts ~]# /scripts/test.sh
any folders you dont want me to monitor (up to five x5)
/q /w /e /r /t
find  find / \( -path /q -o -path /w -o -path /e -o -path /r -o -path /t \) -prune -o
[root@scripts ~]# /scripts/test.sh
any folders you dont want me to monitor (up to five x5)
/z
find  find / \( -path /z -o -path  -o -path  -o -path  -o -path  \) -prune -o
[root@scripts ~]#

now all those empty paths ie

-path -o

will it totally ignore them or will this mess about with the find command?


echo "please enter in the location where you want the log files to be saved, make sure you start it with "/" (press tab to auto-complete)"
read -e log

hn=$(hostname)
dt=$(date "+%y%m%d%H%M%S")
df1=$log/disk_usage/$hn/$dt.df1.txt
df2=$log/disk_usage/$hn/$dt.df2.txt
changes=$log/disk_usage/$hn/$dt.changes.txt
list=$log/disk_usage/$hn/$dt.list.txt

echo "any folders you DONT want me to monitor,just leave a space between the folders and remove the last "/" for all folders (up to five x5)"
read -e path1 path2 path3 path4 path5

echo "please enter in minutes how long you want to monitor disk usage"
read min
echo "please wait while I monitor disk usage"

mkdir -p "$log"/disk_usage/"$hn"

past=$(date "+%y-%m-%d %H:%M:%S")

df -l > "$df1" && sleep "$min"m

df -l > "$df2"

diff "$df1" "$df2" | awk '{print $7}' | sed '/Mounted/d' | sed '/^$/d' | sort | uniq > "$changes"

pres=$(date "+%y-%m-%d %H:%M:%S")

while IFS= read -r line; do
find $line -path "$path1" -prune -o -path "$path2" -prune -o -path "$path3" -prune -o -path "$path4" -prune -o -path "$path5" -prune -o -newerat "$past" ! -newerat "$pres" -type f -exec ls -lah {} \; >> "$list"
done < "$changes"

echo "the log can be found below"
echo ""$log"/disk_usage/"$hn"/"$dt".list.txt" ```

You can generate the find arguments in a for loop

echo "any folders you DONT want me to monitor,just leave a space between the folders and remove the last / for all folders"
read -e paths
# we use unquoted variables to let the shell split their contents on whitespace.
# -f disables further expansions
set -f
fpaths=
for p in $paths
do fpaths+="${fpaths:+-o} -path $p"
done

(The :+ variable modifier puts the following string if the variable is not empty. Much more elegant than an if statement.)

And later insert $fpaths unquoted, like this:

find startdir \( $fpaths \) -prune -o -print
1 Like