[colug-432] Gracefully Doing Nothing
jep200404 at columbus.rr.com
jep200404 at columbus.rr.com
Wed Feb 8 20:02:39 EST 2017
On Mon, 30 Jan 2017 10:37:07 -0800, Rick Hornsby <richardjhornsby at gmail.com> wrote:
> [> ]On January 30, 2017 at 11:57:53, jep200404 at columbus.rr.com (
> [> ]jep200404 at columbus.rr.com) wrote:
>
> [> ]How does one do nothing gracefully in a Bourne shell for loop?
> Typically, I'd think of two approaches to this.
> The first is just to throw away any error output.
> That's probably not ideal, because in case something
> goes wrong (destination volume full, etc) you won't know.
Yup. That's not graceful.
> The other is to generate an array of files, then wrap your loop in an if
> statement. "if" might not seem super cool, but it might do the trick for
> you:
> $ cat backup.sh
> prefix=<set the date or whatever>
> files=([a-z]*)
> if [ -e "${files[0]}" ]; then
> for f in "${files[@]}"; do
> mv "$f" "$prefix-$f"
> done
> fi
Yes. We have all had to do stuff like that.
It is not graceful.
> An option that might be slightly less readable but could be done in fewer
> lines (eliminates the explicit loop construct entirely) is to use `find`
> with exec mv or xargs. I haven't tested this, so consider it metacode -
> find . -name '^[a-z]*' -maxdepth 1 -exec mv "{}" "$prefix-{}" \;
That gracefully does nothing, and does so with Bourne shells.
Another nice thing about that is that it does not crash
when there are a large number of files.
Initially I had a for loop with shopt -s nullglob
inspired by Jeff Frontz.
Today, for a different task, I settled on the following technique,
similar to your find technique.
find ... | while read f; do echo do something with "$f";done
shown more fully below
doj at pan:~ $ head -n 1000 -v .foo_config bin/delete-log-files bin/delete-files
==> .foo_config <==
mybin="$HOME/bin"
PATH="$PATH:$mybin"
log_dir="$HOME/logs"
minimum_log_space=10000000 ;# Unit is 1024 bytes.
deletable_log_filename_glob='[0-9]*'
==> bin/delete-log-files <==
#!/bin/sh
. "$HOME/.foo_config"
find "$log_dir" -name "$deletable_log_filename_glob" |
sort |
delete-files ~/logs "$minimum_log_space"
==> bin/delete-files <==
#!/bin/sh
if [ "$#" -lt 2 ]; then
exec >&2
echo Deletes files while df reports space is less than minimum_space.
echo Filenames are specified on stdin, one filename per line.
echo
echo Usage: `basename "$0"` directory minimum_space
echo
echo minimum_space unit is 1024 bytes.
echo
echo 'e.g., find ~/logs -name '\''[0-9]*'\'' | sort |'
echo delete-files ~/logs 09764200
exit 1
fi
dir="$1"
minimum_space="$2"
while read f; do
space=`df --output=avail "$dir" | grep -v '[A-Z][a-z][a-z]*'`
# echo $0 $dir $space $minimum_space if [ "0$space" -ge "0$minimum_space" ]
if [ "0$space" -ge "0$minimum_space" ]; then
# echo $?
# echo ok
break
fi
# echo $?
# echo low [ "0$space" -ge "0$minimum_space" ]
# echo rm "$f"
rm "$f"
# sleep .1
done
doj at pan:~ $
More information about the colug-432
mailing list