Re: [SLUG] quoting

From: John Kinary (john.kinary@verizon.net)
Date: Fri Jun 02 2006 - 17:33:22 EDT


Eben King wrote:
> OK, I can't figure this out. I'm sure it's logical, but I don't have
> a handle on the logic.
>
> What I've got is a shell script, written in ksh (think of it as a
> dialect of bash):
>
> ...
> 40 function choose_a_background
> 41 {
> 42 [[ -z $BACKGROUNDDIR ]] &&
> BACKGROUNDDIR=/export/media/backgrounds
> 43 [[ -z $PATTERNDIR ]] && PATTERNDIR=/export/media/patterns
> 44 FIND_FLAGS="$BACKGROUNDDIR $PATTERNDIR -type f"
> 45 case $1 in
> 46 tall)
> 47 FIND_FLAGS="$FIND_FLAGS -name tall_\\*" ;;
> 48 wide)
> 49 FIND_FLAGS="$FIND_FLAGS ! -name tall_\\*"
> 50 esac
> 51 print -u2 "FIND_FLAGS='$FIND_FLAGS'" # diagnostic
> 52 # Initialize PRNG in ksh
> 53 [[ -c /dev/random ]] \
> 54 && RANDOM=$( dd if=/dev/random bs=4 count=1 2>/dev/null \
> 55 | sum - \
> 56 | cut -f 1 -d " " )
> 57 numfiles=$(find $FIND_FLAGS ! -name random\* | wc -l)
> 58 print -u2 found $numfiles files # diagnostic
> ...
>
> I run this script every 6 hours to change my backdrop. It _should_
> choose one appropriately shaped, i.e. tall ones for when the screen is
> rotated, regular ones otherwise. That's why I have the "case $1 in"
> business. Likewise, tall images are named tall_something.
>
> So, I need to add "-name tall\*" or "! -name tall\*" to find's
> options. I've tried between 1 and 6 backslashes in line 47, single
> quotes around tall_\\* with varying numbers of backslashes, reducing
> "$BACKGROUNDDIR $PATTERNDIR" to "/export", reducing tall_\\* to \\*,
> and what I've found out is that:
>
> with this many backslashes it'll find
> 0 something having to do with filenames in $PWD
> 1 files named "*"
> 2 files named "\*"?
> 3+ ??
>
> It seems I have the filenames correct:
>
> find /export/media/backgrounds /export/media/patterns -type f -name
> tall_\* | wc -l
> 37
>
> So, can anyone see where I've screwed up?
>
A friend of mine gave this solution:

Re:

> > So, I need to add "-name tall\*" or "! -name tall\*" to find's
> > options. I've tried between 1 and 6 backslashes in line 47, single
> > quotes around tall_\\* with varying numbers of backslashes, reducing
> > "$BACKGROUNDDIR $PATTERNDIR" to "/export", reducing tall_\\* to \\*,
> > and what I've found out is that:
> > with this many backslashes it'll find
> > 0 something having to do with filenames in $PWD
> > 1 files named "*"
> > 2 files named "\*"?
> > 3+ ??
>

I don't think so. I don't think he tried 0 backslashes. Patterns
within quotes are not globbed so:

   FIND_FLAGS="$FIND_FLAGS -name tall_*"

should work fine. However I tend to use single quotes in find
patterns which avoid even this amount of thinking.

   FIND_FLAGS="$FIND_FLAGS -name 'tall_*'"
   find $FIND_FLAGS

   find $BACKGROUNDDIR $PATTERNDIR -type f -name 'tall_*'

Both work without having to think about globbing.

By the way, I was impressed by the way a random number was generated:
   
  RANDOM=$(dd if=/dev/random bs=4 count=1 2>/dev/null |\
           sum - | cut -f 1 -d " ")

which should give a value in the range 0 through 65535. But *not*
in bash where the $RANDOM variable generates an new random number
in the range 0 through 32767 each time it is referenced. In bash
another name for the variable needs to be used. Or just use $RANDOM
and avoid the shell expression.

You didn't show how the image file was selected. My guess is (using
bash's RANDOM):

   numfiles=$(find $FIND_FLAGS ! -name 'random*' | wc -l)
   imagenum=$(expr $numfiles \* $RANDOM / 32767 + 1)
   imagefile=$(find $FIND_FLAGS ! -name 'random*' |\
               sed -n ${imagenum}p)

Hope this helps.

John

-----------------------------------------------------------------------
This list is provided as an unmoderated internet service by Networked
Knowledge Systems (NKS). Views and opinions expressed in messages
posted are those of the author and do not necessarily reflect the
official policy or position of NKS or any of its employees.



This archive was generated by hypermail 2.1.3 : Fri Aug 01 2014 - 20:00:30 EDT