From: Stephane CHAZELAS on
2010-02-05, 11:23(+00), lbrtchx(a)gmail.com:
[...]
> _BSLSH="\\"
>
>
> # SPACE
> _SPC=" "
>
> # FIND DIRECTORY
> _FND_DIR=/UNIONFS/var
>
> # EXCLUDING (should be done in a loop and using awk)
> _XKLD="-noleaf -wholename '/proc' -prune -o -wholename '/media/sda1' -prune"
>
> #eval find ${_FND_DIR} ${_XKLD} -o -type f -printf '%s %d ' -exec md5sum -b {} \; > 2sort_md5sum.tmp
> #find: paths must precede expression: %d
[...]

You're asking eval to evaluate the concatenation of "find", the
arguments resulting of word splitting and globbing performed on
the expansion of $_FND_DIR and $_XKLD, that is "/UNIONFS/var",
"-noleaf", "-wholename", "'/proc'", "-prune", "-o",
"-wholename", "'/media/sda1'", "-prune" and then "-o", "-type", "f",
"-printf", "%s %d ", "-exec", "md5sum", "-b", "{}" and ";"

That is:

"find /UNIONFS/var -noleaf -wholename '/proc' -prune -o -wholename '/media/sda1' -prune -o -type f -printf %s %d -exec md5sum -b {} ;"

That's a valid shell command line which is interpreted as
invoking find with those arguments:

"find", "/UNIONFS/var", "-noleaf", "-wholename", "/proc",
"-prune", "-o", "-wholename", "/media/sda1", "-prune", "-o",
"-type", "f", "-printf", "%s", "%d", "-exec", "md5sum", "-b",
"{}"

However, find won't like that list of arguments as there are 2
syntax errors in it: that "%d" argument by itself and the
non-terminated -exec (; was interpreted by eval as a command
separator).

You want:

eval "find \"\$_FND_DIR\" $_XKLD -o -type f -printf '%s %d ' -exec md5sum -b {} \; > 2sort_md5sum.tmp"

That is, you want just one string passed to eval that contains
the code to be evaluated, you probably don't want $_FND_DIR to
be expanded before it is passed to eval, you don't want $_XKLD
to undergo word splitting nor filename generation, you want the
' and \ passed to eval.

--
St�phane
From: Ed Morton on
On 2/5/2010 6:38 AM, Ben Bacarisse wrote:
> lbrtchx(a)gmail.com writes:
>
> You might want to check your newsreader's setup. I find the added ~s
> and the unwrapped paragraphs make your posts hard to read.
>
>> ~
>> it amazes me how fragile bash scripting is
>> ~
>> you try first things on the command prompt which works just find
>> but then when you paste your command on a bash files thing stops
>> working. As I see "I am not the only one". I'd wish I could not the
>> reason why that happens to be smarter about this
>> ~
>> I am just trying to use find with printf and exec(dir). I found a
>> few such commands that work, but their results was not what I
>> needed
>> ~
>> # BSLSH
>> _BSLSH="\\"
>
> Why do you put _ in front of your bash variable names?

That's the way I was taught to name local shell variables, too - with a
preceeding underscore to make them easily distinguishable from function,
command, etc. names. I was also taught to only use all-upper-case for exported
variables though.

Without those conventions, if you look at a script and see the word "file" you
have to think about the context to know if it is a command name (file), a local
variable name (_file), or an exported variable name (FILE) rather than being
able to tell at first glance, and then if you had a bug in your program where
you used "file" instead of "$file" in the wrong context, you'd get some pretty
confusing results.

Not a big deal in reality though...

>
>> # SPACE
>> _SPC=" "
>>
>> # FIND DIRECTORY
>> _FND_DIR=/UNIONFS/var
>>
>> # EXCLUDING (should be done in a loop and using awk)
>> _XKLD="-noleaf -wholename '/proc' -prune -o -wholename '/media/sda1' -prune"
>>
>> #eval find ${_FND_DIR} ${_XKLD} -o -type f -printf '%s %d ' -exec md5sum -b {} \;> 2sort_md5sum.tmp
>> #find: paths must precede expression: %d
>
> This, and all the subsequent errors, are caused by the eval. Why are
> you using eval? It is quite rare in shell scripting and certainly not
> needed when all you want to do is run a command.

He wants to be able to store parts of the command in shell variables and then
execute them together later.

>
> A couple of other details: Why use {} round your variables?

That was something I got in the habit of too and still find myself doing for no
good reason today. I wonder if the OP went to Glasgow University....

Ed.

I find
> $XKLD simpler and more readable than ${_XKLD}. Second, what are all
> the initial # characters? Are they, too, from you newsreader when you
> paste output? Anyway, they confuse matters (at least they confuse me)
> so you might want to look at removing them.
>
> <snip>

From: Bit Twister on
On Fri, 05 Feb 2010 07:24:14 -0600, Ed Morton wrote:
> On 2/5/2010 6:38 AM, Ben Bacarisse wrote:
>>
>> Why do you put _ in front of your bash variable names?
>
> That's the way I was taught to name local shell variables, too -
> with a preceeding underscore to make them easily distinguishable
> from function, command, etc. names. I was also taught to only use
> all-upper-case for exported variables though.

I also used leading _ for the above reasons, plus the additional benefit of
sorting results from env would group all my _whatever variables in one place.

>>
>> A couple of other details: Why use {} round your variables?
>
> That was something I got in the habit of too and still find myself
> doing for no good reason today. I wonder if the OP went to Glasgow
> University....

I cannot remember exact details, but I started using brackets after the
first time I was trying to build a name from several variables and
parser broke on something like
_var=gg
_fn=$_varxx

_varxx not found. Changed code to _fn=${_var}xx and problem went away.

I will admit I only use the brackets on cases where variable is hard
to see at a glance in a long string generation operation.
From: Stephane CHAZELAS on
2010-02-5, 14:01(+00), Bit Twister:
> On Fri, 05 Feb 2010 07:24:14 -0600, Ed Morton wrote:
>> On 2/5/2010 6:38 AM, Ben Bacarisse wrote:
>>>
>>> Why do you put _ in front of your bash variable names?
>>
>> That's the way I was taught to name local shell variables, too -
>> with a preceeding underscore to make them easily distinguishable
>> from function, command, etc. names. I was also taught to only use
>> all-upper-case for exported variables though.
>
> I also used leading _ for the above reasons

variables have a $ in front of them already (and possibly {}
around them as well), why do we need yet another character, I
don't get it.

> plus the additional benefit of
> sorting results from env would group all my _whatever variables in one place.

If they are local variables, then don't appear in the output of
env.

>>> A couple of other details: Why use {} round your variables?
>>
>> That was something I got in the habit of too and still find myself
>> doing for no good reason today. I wonder if the OP went to Glasgow
>> University....
>
> I cannot remember exact details, but I started using brackets after the
> first time I was trying to build a name from several variables and
> parser broke on something like
> _var=gg
> _fn=$_varxx

Like in C, I'd avoid using _ prefixed variables except for some
"infrastructure" code or very generic code used everywhere even
in places where we don't know what variable names are being
used.

For instance in a "logging" package that may be used in any
script, in a log() function, you could use:

log() {
for _myLoggingPackage_i do
...
done
}

instead of

log() {
for i do
...
done
}

as that "log" function might be used in places where a "i"
variable is already being used.

Here, we use _<namespace>_<var-name>, <namespace> to avoid
clashes, and the extra leading underscore to denote
"infrastructure" code (though it's probably not good enough an
example here), so they appear separately in the output of "set".

--
St�phane
From: Ed Morton on
On 2/5/2010 8:46 AM, Stephane CHAZELAS wrote:
> 2010-02-5, 14:01(+00), Bit Twister:
>> On Fri, 05 Feb 2010 07:24:14 -0600, Ed Morton wrote:
>>> On 2/5/2010 6:38 AM, Ben Bacarisse wrote:
>>>>
>>>> Why do you put _ in front of your bash variable names?
>>>
>>> That's the way I was taught to name local shell variables, too -
>>> with a preceeding underscore to make them easily distinguishable
>>> from function, command, etc. names. I was also taught to only use
>>> all-upper-case for exported variables though.
>>
>> I also used leading _ for the above reasons
>
> variables have a $ in front of them already (and possibly {}
> around them as well), why do we need yet another character, I
> don't get it.

An example where, say, someone mistakenly used "()" instead of "{}" in tst2.sh:

$ cat tst1.sh
file="$1"
echo "${file}WithSufx"

$ ./tst1.sh foo
fooWithSufx

$ cat tst2.sh
file="$1"
echo "$(file)WithSufx"

$ ./tst2.sh foo
Usage: file [-bcikLhnNrsvz0] [-e test] [-f namefile] [-F separator] [-m magicfil
es] file...
file -C -m magicfiles
Try `file --help' for more information.
WithSufx

Now, imagine trying to figure out what that error message meant if you made that
mistake in a large script and/or the command that just happened to have the same
names as the variable didn't produce such a nice error message and/or had nasty
side effects.

Compare to:

$ cat ./tst1.sh
_file="$1"
echo "${_file}WithSufx"

$ ./tst1.sh foo
fooWithSufx

$ cat ./tst2.sh
_file="$1"
echo "$(_file)WithSufx"

$ ./tst2.sh foo
../tst2.sh: line 2: _file: command not found
WithSufx

Note the clear error message identifying the line number the error was on. Like
I said, it doesn't happen much so it's debatable how useful it really is.

>
>> plus the additional benefit of
>> sorting results from env would group all my _whatever variables in one place.
>
> If they are local variables, then don't appear in the output of
> env.
>
>>>> A couple of other details: Why use {} round your variables?
>>>
>>> That was something I got in the habit of too and still find myself
>>> doing for no good reason today. I wonder if the OP went to Glasgow
>>> University....
>>
>> I cannot remember exact details, but I started using brackets after the
>> first time I was trying to build a name from several variables and
>> parser broke on something like
>> _var=gg
>> _fn=$_varxx
>
> Like in C, I'd avoid using _ prefixed variables except for some
> "infrastructure" code or very generic code used everywhere even
> in places where we don't know what variable names are being
> used.

OT: just to be clear, the time to use "_" prefixes in C is when you're declaring
variables inside macros to avoid clashing with variables of the same name
declared in the code calling the macros, so variables declared inside macros
must start with _ and variables decalared everywhere else must not, except
pre-defined/compiler variables that start with 2 underscores (__).

>
> For instance in a "logging" package that may be used in any
> script, in a log() function, you could use:
>
> log() {
> for _myLoggingPackage_i do
> ...
> done
> }
>
> instead of
>
> log() {
> for i do
> ...
> done
> }
>
> as that "log" function might be used in places where a "i"
> variable is already being used.

Just like macros in C. Right.

>
> Here, we use _<namespace>_<var-name>,<namespace> to avoid
> clashes, and the extra leading underscore to denote
> "infrastructure" code (though it's probably not good enough an
> example here), so they appear separately in the output of "set".

Makes sense.

Ed.