Prev: find errors "paths must precede expression: %d" ..., "missing argument to `-exec'"
Next: Ya didnae ha' te use brackets. Be curly, Jimmeh!
From: Stephane CHAZELAS on 5 Feb 2010 07:48 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 5 Feb 2010 08:24 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 5 Feb 2010 09:01 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 5 Feb 2010 09:46 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 5 Feb 2010 10:10
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. |