Re: Shell game? was Re: pmount could perhaps be of greater utility?

2019-05-08 Thread KHMan

On 5/9/2019 12:34 AM, David Wright wrote:

On Wed 08 May 2019 at 14:08:03 (+0800), KHMan wrote:

On Tue 07 May 2019 at 10:12:10 (+1000), David wrote:

On Mon, 6 May 2019 at 23:53, Erik Christiansen wrote:

On 06.05.19 09:03, Greg Wooledge wrote:

On Sat, May 04, 2019 at 01:48:01PM +0200, Jonas Smedegaard wrote:

[snipped all]

Hi Erik

Maybe you would enjoy answering this question then?
https://lists.gnu.org/archive/html/help-bash/2019-05/msg0.html



Running the result of a command execution and allowing the result to
control delimiters, dropping out of the string? Now that gives me the
jeebies, security-wise. :-)


I think you can heave a sigh of relief as I think I can show that's
not happening after all. The trick is to add   set -x   to the top
of the script (and I've set -v as well). It does appear (I think)
that the contents of the backquotes are interpreted earlier than
my working showed:

[snip]

Good tip, set -x is useful. I only know simple bash scripting. I 
am actually doing this to fix shell code syntax highlighting for 
the Scintilla edit control (Geany, Notepad++, SciTE, etc.) -- for 
this one I want to get to the bottom of this rather than implement 
its behaviour without fully understanding _why_.


[snip]

But I'm not sure how to distinguish the order of the interpretation
of \\ and \" in the above.


You need 5 backslashes to get \\x, I was trying such snippets 
earlier in the week:


$ echo "[` echo \" \x \" `]"
++ echo ' \\x '
+ echo '[ \\x ]'
[ \\x ]

Going by my theory below, the inner `` string would be read as:
 echo " \\\x "
where \\ -> \ and \" -> ". Then it is executed, and there is 
another \\ -> \ due to the "", so when the "" string is translated 
into a literal string, it becomes:

 echo ' \\x '
and the rest follows.

For double quotes:

$ echo "[` echo \" \\" \" `]"
++ echo ' " '
+ echo '[ " ]'
[ " ]

The inner `` string is first read as:
 echo " \" "
because of \\ -> \ and the " in the \\" becomes just a character 
since it is not an ending delimiter for the `` inner string. When 
executed, the " \" " string would be equivalent to the ' " ' 
literal string. The result follows.


If we try \\\":

$ echo "[` echo \" \\\" \" `]"
++ echo ' " '
+ echo '[ " ]'
[ " ]

Here, the inner `` string is first read as:
 echo " \" "
where \\ -> \ and \" -> ". When executed the " \" " string would 
again be equivalent to the ' " ' literal string. Final result is 
the same.


This would however cause an error:

$ echo "[` echo \" " \" `]"

The inner `` string is first read as:
 echo " \\" "
because of two \\ -> \ escapes. Then the " \\" " becomes ' \' plus 
an extra ".


Five backslashes will fail too, it still results in the inner string:
 echo " \\" "

Six backslashes work. It will give the interim of:
 echo " \\\" "
where " \\\" " end up as ' \" ' and the result is as predicted.



I have since been studying the bash sources, and posted another query
yesterday, see:

http://lists.gnu.org/archive/html/help-bash/2019-05/msg6.html

To summarize, consider our usual examples:
echo "[` echo \" \\" \" `]" A# [ " ] A
echo "[` echo \" \\x \" `]" J# [ \x ] J

Here's a theory: Inside the inner backquotes, \" gets escaped into "
because token processing sees the current delimiter as ". (But matched
pair processing sees the inner delimiters as ``.) The \\" becomes \"
and the \\x becomes \x. The inner commands are then run as:

echo " \" "
echo " \x "


I follow that. Unfortunately, set -x appears not to show the raw line
in that state, but interprets those outer double quotes and then
reports the line in its own single quotes.


giving the expected result. When entering the matched pair processing
function for the inner ``, the delimiter stack was not updated, so the
token function still sees the current delimiter as the outer one,
which is ".


So again it appears to involve the order of interpretation.


If you study the sources, bash does make string parsing calls 
recursively as expected for this kind of thing. The anomaly I see 
is at parse.y[3734] for bash-5.0. A call is made to parse the 
inner `` string while currently parsing a "" string, so it is 
nesting, _but_ the delimiter stack is not updated.


The read_token_word function uses the delimiter stack to determine 
escaping (see parse.y[4942] and parse.y[4961]) so inside that 
inner `` string, it is running the escape behaviour for "" 
strings. So I am trying to find out if it is intentional. Is the 
inner `` supposed to be semantically part of the outer "" string? 
If so, the additional level of escaping due to execution of the `` 
inner string serves to confuse matters a lot.




This is based on what I have studied in the sources, and it doesn't
make any sense to me from a syntax point-of-view, so I hope I can
eventually get a useful and definitive answer from the bash
maintainers.


Is backquote deprecated yet? :)


Doesn't matter, since editor users will hit this scenario, then 
the 

Re: Shell game? was Re: pmount could perhaps be of greater utility?

2019-05-08 Thread David Wright
On Wed 08 May 2019 at 14:08:03 (+0800), KHMan wrote:
> > On Tue 07 May 2019 at 10:12:10 (+1000), David wrote:
> > > On Mon, 6 May 2019 at 23:53, Erik Christiansen wrote:
> > > > On 06.05.19 09:03, Greg Wooledge wrote:
> > > > > On Sat, May 04, 2019 at 01:48:01PM +0200, Jonas Smedegaard wrote:
> [snipped all]
> > > Hi Erik
> > > 
> > > Maybe you would enjoy answering this question then?
> > > https://lists.gnu.org/archive/html/help-bash/2019-05/msg0.html

> Running the result of a command execution and allowing the result to
> control delimiters, dropping out of the string? Now that gives me the
> jeebies, security-wise. :-)

I think you can heave a sigh of relief as I think I can show that's
not happening after all. The trick is to add   set -x   to the top
of the script (and I've set -v as well). It does appear (I think)
that the contents of the backquotes are interpreted earlier than
my working showed:

$ bash bash-bit
echo
+ echo

echo "[` echo \" \x \\x \\\x x \\" \\\" \" `]"
++ echo ' \x \x \x \x " " '
+ echo '[ \x \x \x \x " " ]'
[ \x \x \x \x " " ]
echo
+ echo

echo "[` echo \" \\" \\\" " \" `]"
bash-bit: command substitution: line 6: unexpected EOF while looking for 
matching `"'
bash-bit: command substitution: line 7: syntax error: unexpected end of file
+ echo '[]'
[]
echo
+ echo

#
$ 

But I'm not sure how to distinguish the order of the interpretation
of \\ and \" in the above.

> I have since been studying the bash sources, and posted another query
> yesterday, see:
> 
> http://lists.gnu.org/archive/html/help-bash/2019-05/msg6.html
> 
> To summarize, consider our usual examples:
> echo "[` echo \" \\" \" `]" A# [ " ] A
> echo "[` echo \" \\x \" `]" J# [ \x ] J
> 
> Here's a theory: Inside the inner backquotes, \" gets escaped into "
> because token processing sees the current delimiter as ". (But matched
> pair processing sees the inner delimiters as ``.) The \\" becomes \"
> and the \\x becomes \x. The inner commands are then run as:
> 
> echo " \" "
> echo " \x "

I follow that. Unfortunately, set -x appears not to show the raw line
in that state, but interprets those outer double quotes and then
reports the line in its own single quotes.

> giving the expected result. When entering the matched pair processing
> function for the inner ``, the delimiter stack was not updated, so the
> token function still sees the current delimiter as the outer one,
> which is ".

So again it appears to involve the order of interpretation.

> This is based on what I have studied in the sources, and it doesn't
> make any sense to me from a syntax point-of-view, so I hope I can
> eventually get a useful and definitive answer from the bash
> maintainers.

Is backquote deprecated yet? :)

I saw Greg's followup to your new post; it seems mainly aimed at
outlawing overlapping strings and allowing only nested ones.
I guess, then, that that does prevent delimiting a string by a
quote from one level paired with one "dropping out of" (returned by)
the inner command.

Cheers,
David.
#
set -x -v
echo
echo "[` echo \" \x \\x \\\x x \\" \\\" \" `]"
echo
echo "[` echo \" \\" \\\" " \" `]"
echo
#


Re: Shell game? was Re: pmount could perhaps be of greater utility?

2019-05-08 Thread KHMan

On Tue 07 May 2019 at 10:12:10 (+1000), David wrote:

On Mon, 6 May 2019 at 23:53, Erik Christiansen wrote:
> On 06.05.19 09:03, Greg Wooledge wrote:
> > On Sat, May 04, 2019 at 01:48:01PM +0200, Jonas Smedegaard wrote:

[snipped all]

Hi Erik

Maybe you would enjoy answering this question then?
https://lists.gnu.org/archive/html/help-bash/2019-05/msg0.html

Because apparently no-one else has, hehe :D


Hi everyone, I'm the poster of the above query and I have just 
subscribed here. Replying via the web link so if there is any 
discussion, list thread won't break (hopefully).




My take on this problem goes as follows.

B is easy. man bash says "When the old-style backquote form of
substitution is used, backslash retains its literal meaning except
when followed by $, `, or \." So the \\ in B's inner echo becomes
\ in the outer echo. BB shows the result of running the outer echo
on the substitution made in B.

A is tricky, mainly because of the middle Quotation Mark¹. So the first
thing I would do is substitute a benign character, like x. The result
of that substitution is shown at J. Work with that, and then change x
back to Quotation Mark at the end.

So K runs the inner echo and shows the result. L then runs the outer
echo on that result (leaving out the [] brackets). Because \x is
meaningless in double quotes, it survives the outer echo untouched.


Running the result of a command execution and allowing the result 
to control delimiters, dropping out of the string? Now that gives 
me the jeebies, security-wise. :-)


If you try to encapsulate the \" in a separate script file, then 
it appears the above does not occur. Try this:


test.sh:
#/bin/bash
echo \"

$ echo "`./test.sh \\"`"
"

The " returned by test.sh doesn't close anything. \\" is passed as 
argument to test.sh (I guess as \") and disappears. Unless echo as 
a built-in (is it?) behaves differently. Still, the power to 
control the parent's delimiters seems unlikely, IMHO.



I have since been studying the bash sources, and posted another 
query yesterday, see:


http://lists.gnu.org/archive/html/help-bash/2019-05/msg6.html

To summarize, consider our usual examples:
echo "[` echo \" \\" \" `]" A# [ " ] A
echo "[` echo \" \\x \" `]" J# [ \x ] J

Here's a theory: Inside the inner backquotes, \" gets escaped into 
" because token processing sees the current delimiter as ". (But 
matched pair processing sees the inner delimiters as ``.) The \\" 
becomes \" and the \\x becomes \x. The inner commands are then run as:


echo " \" "
echo " \x "

giving the expected result. When entering the matched pair 
processing function for the inner ``, the delimiter stack was not 
updated, so the token function still sees the current delimiter as 
the outer one, which is ".


This is based on what I have studied in the sources, and it 
doesn't make any sense to me from a syntax point-of-view, so I 
hope I can eventually get a useful and definitive answer from the 
bash maintainers.




Now put back the Quotation Mark in place of x. man bash says "A double
quote may be quoted within double quotes by preceding it with a
backslash." And that's what we've got in M.

Now working outwards, I've added the [] brackets at LL and MM, where
they play no role. Finally the outer double quotes: because they pair
up with the double quotes from L, that leaves the \x exposed to the
outer echo and it becomes just x.

Who processed the \" into " in A? The outer echo (or, if you like, the
shell handing the arguments to the outer echo).

Over to Greg for checking.

¹ Quotation Mark rather than double quote because it never plays the
role of an active double quote as far as bash is concerned.



--
Cheers,
Kein-Hong Man (esq.)
Selangor, Malaysia



Shell game? was Re: pmount could perhaps be of greater utility?

2019-05-07 Thread David Wright
On Tue 07 May 2019 at 10:12:10 (+1000), David wrote:
> On Mon, 6 May 2019 at 23:53, Erik Christiansen  
> wrote:
> > On 06.05.19 09:03, Greg Wooledge wrote:
> > > On Sat, May 04, 2019 at 01:48:01PM +0200, Jonas Smedegaard wrote:
> > > > Quoting Erik Christiansen (2019-05-04 08:43:53)
> 
> > > > >  pmount $1 `e2label $1`
> 
> > > and is using the ancient deprecated command substitution syntax (which
> > > will work in this case, but is not a good habit).
> 
> > That does appear to remain opinion. The venerably traditional syntax is
> > still fully legal supported bash syntax, e.g.:
> >
> > http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_03
> >
> > The recent (late last century, IIRC) introduction of the $(...)
> > alternative syntax has admittedly brought newer *nix users who know
> > nothing else, and so delude themselves that there is nothing else. That
> > is a misapprehension. To each, his own, especially amongst adequately
> > equivalent alternatives.
> 
> Hi Erik
> 
> Maybe you would enjoy answering this question then?
> https://lists.gnu.org/archive/html/help-bash/2019-05/msg0.html
> 
> Because apparently no-one else has, hehe :D

My take on this problem goes as follows.

B is easy. man bash says "When the old-style backquote form of
substitution is used, backslash retains its literal meaning except
when followed by $, `, or \." So the \\ in B's inner echo becomes
\ in the outer echo. BB shows the result of running the outer echo
on the substitution made in B.

A is tricky, mainly because of the middle Quotation Mark¹. So the first
thing I would do is substitute a benign character, like x. The result
of that substitution is shown at J. Work with that, and then change x
back to Quotation Mark at the end.

So K runs the inner echo and shows the result. L then runs the outer
echo on that result (leaving out the [] brackets). Because \x is
meaningless in double quotes, it survives the outer echo untouched.

Now put back the Quotation Mark in place of x. man bash says "A double
quote may be quoted within double quotes by preceding it with a
backslash." And that's what we've got in M.

Now working outwards, I've added the [] brackets at LL and MM, where
they play no role. Finally the outer double quotes: because they pair
up with the double quotes from L, that leaves the \x exposed to the
outer echo and it becomes just x.

Who processed the \" into " in A? The outer echo (or, if you like, the
shell handing the arguments to the outer echo).

Over to Greg for checking.

¹ Quotation Mark rather than double quote because it never plays the
role of an active double quote as far as bash is concerned.

Cheers,
David.
#
echo
echo
echo ` echo \" \\" \" ` B# " " " B
 echo \" \" \"  BB   # " " " BB
echo
echo
echo "[` echo \" \\" \" `]" A# [ " ] A
echo "[` echo \" \\x \" `]" J# [ \x ] J
 echo \" \\x \"  K   # " \x " K
echo " \x " L#  \x  L
echo " \" " M#  "  M
echo
echo
echo "[` echo \" \\" \" `]" A# [ " ] A
echo "[` echo \" \\x \" `]" J# [ \x ] J
 echo \" \\x \"  K   # " \x " K
echo [" \x "] LL # [ \x ] LL
echo [" \" "] MM # [ " ] MM
echo
echo
echo "[` echo \" \\" \" `]" A# [ " ] A
echo "[` echo \" \\x \" `]" J# [ \x ] J
 echo \" \\x \"  K   # " \x " K
echo "[" \x "]" LLL  # [ x ] LLL
echo "[" \" "]" MMM  # [ " ] MMM
echo \x exposed  # x exposed
echo \" exposed  # " exposed
#


Re: shell game

2002-12-08 Thread Frank Gevaerts
On Sun, Dec 08, 2002 at 12:31:30AM -0600, Michael Heironimus wrote:
 On Sat, Dec 07, 2002 at 08:26:21PM +0100, Frank Gevaerts wrote:
 find . -name '*.jpg' -print0 | xargs -r0 mpg123
  
  Any special reason not to use -exec (except of course that xargs works
  with any input, while -exec only with find (obviously))
 
 I always use xargs instead of find -exec because it just comes more
 naturally to me. There are some technical reasons for it, though.

I guess the most important reason is that xargs can combine arguments,
so it calls the command less often. Since I mostly use find/exec/xargs
for commands that can take only one filename, I didn;'t think of this
immediately.

 GNU xargs is considerably more versatile than -exec. On some platforms
 (not sure about GNU find/xargs) find also spawns a subshell for every
 file with -exec, which makes xargs considerably more efficient. Not much
 difference for a dozen files, but if you have a few thousand results
 you're saving the time of starting a few thousand shells that do nothing
 but run a single command and exit.

I didn't know about this. I might checxk on the GNU find behaviour some
day.

Frank


 -- 
 Michael Heironimus
 
 
 -- 
 To UNSUBSCRIBE, email to [EMAIL PROTECTED] 
 with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED] 
with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]




Re: shell game

2002-12-07 Thread Bob Proulx
Drew Cohan [EMAIL PROTECTED] [2002-12-07 01:00:29 -0500]:
 
 Using a bash shell script (/bin/sh), I need to know how to check to see
 if certain files exist in a directory, as in, Are there any jpegs in
 this directory?.  I've tried various things (like using -s, -f with
 test and a do/for loop) but nothing seems to work right.  The closest I
 can come is
 
 if test `ls /opt/images/*.jpg | wc -l` -gt 0 then ...

Ugh.

 So what am I missing here?

You are trying to find files in a directory.  Therefore I recommend
you use the 'find' command.

  find . -name '*.jpg' -print

I assume you will want to operate on those files once you have found
them.  List them and save the list and then operate on the list.
(Slightly possible that you will exceed ARG_MAX.  File names with
spaces and newlines will cause problems.)

  mp3playlist=$(find . -name '*.jpg' -print)

  for mp3 in $mp3playlist; do
mpg123 $mp3
  done

Bob



msg17634/pgp0.pgp
Description: PGP signature


Re: shell game

2002-12-07 Thread Frank Gevaerts
On Sat, Dec 07, 2002 at 11:47:54AM -0700, Bob Proulx wrote:
 Drew Cohan [EMAIL PROTECTED] [2002-12-07 01:00:29 -0500]:
  
  Using a bash shell script (/bin/sh), I need to know how to check to see
  if certain files exist in a directory, as in, Are there any jpegs in
  this directory?.  I've tried various things (like using -s, -f with
  test and a do/for loop) but nothing seems to work right.  The closest I
  can come is
  
  if test `ls /opt/images/*.jpg | wc -l` -gt 0 then ...
 
 Ugh.
 
  So what am I missing here?
 
 You are trying to find files in a directory.  Therefore I recommend
 you use the 'find' command.
 
   find . -name '*.jpg' -print
 
 I assume you will want to operate on those files once you have found
 them.  List them and save the list and then operate on the list.
 (Slightly possible that you will exceed ARG_MAX.  File names with
 spaces and newlines will cause problems.)
 
   mp3playlist=$(find . -name '*.jpg' -print)
 
   for mp3 in $mp3playlist; do
 mpg123 $mp3
   done

Why not just 
find . -name \*.jpg -exec mpg123 {} \;
?

Much shorter, and no problems with number of arguments...

However, be careful with find. If you do not want to search
subdirectories, it is probably not what you want.

Frank

 
 Bob



-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED] 
with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]




Re: shell game

2002-12-07 Thread Bob Proulx
Frank Gevaerts [EMAIL PROTECTED] [2002-12-07 19:58:00 +0100]:
 On Sat, Dec 07, 2002 at 11:47:54AM -0700, Bob Proulx wrote:
  You are trying to find files in a directory.  Therefore I recommend
  you use the 'find' command.
  [..contrived.example...]
mp3playlist=$(find . -name '*.jpg' -print)
for mp3 in $mp3playlist; do
  mpg123 $mp3
done
 
 Why not just 
 find . -name \*.jpg -exec mpg123 {} \;
 ?
 
 Much shorter, and no problems with number of arguments...

I was only proposing the mpg123 as an example.  I really don't know
what the OP wanted to do with it.

You are right that using find's exec and {} avoids the file with
spaces problem.  But instead I would use this if I wanted to play
every file.

  find . -name '*.jpg' -print0 | xargs -r0 mpg123

 However, be careful with find. If you do not want to search
 subdirectories, it is probably not what you want.

Not true!  Check out the -maxdepth option.  This only searches one
directory deep.  The second only operates on the command line files.

  find . -name '*.jpg' -maxdepth 1 -print0 | xargs -r0 mpg123
  find *.jpg -maxdepth 0 -print0 2/dev/null | xargs -r0 mpg123

Bob



msg17637/pgp0.pgp
Description: PGP signature


Re: shell game

2002-12-07 Thread Bob Proulx
Bob Proulx [EMAIL PROTECTED] [2002-12-07 12:13:11 -0700]:
  find . -name \*.jpg -exec mpg123 {} \;
 I was only proposing the mpg123 as an example.  I really don't know
 what the OP wanted to do with it.

You can tell what I was doing in the background while reading and
responding to these messages.  I was playing my Evil mp3s and had it
on my mind.  :-) Obviously I was mixing mp3s and jpegs in my example.
And I am happy to have suckered you into this as well.  Time for me to
take a break from the keyboard for a while.

Bob



msg17638/pgp0.pgp
Description: PGP signature


Re: shell game

2002-12-07 Thread Frank Gevaerts
On Sat, Dec 07, 2002 at 12:13:11PM -0700, Bob Proulx wrote:
 Frank Gevaerts [EMAIL PROTECTED] [2002-12-07 19:58:00 +0100]:
  On Sat, Dec 07, 2002 at 11:47:54AM -0700, Bob Proulx wrote:
   You are trying to find files in a directory.  Therefore I recommend
   you use the 'find' command.
   [..contrived.example...]
 mp3playlist=$(find . -name '*.jpg' -print)
 for mp3 in $mp3playlist; do
   mpg123 $mp3
 done
  
  Why not just 
  find . -name \*.jpg -exec mpg123 {} \;
  ?
  
  Much shorter, and no problems with number of arguments...
 
 I was only proposing the mpg123 as an example.  I really don't know
 what the OP wanted to do with it.

IIRC he wanted to know if there was at least one jpg file in the
directory.

 You are right that using find's exec and {} avoids the file with
 spaces problem.  But instead I would use this if I wanted to play
 every file.
 
   find . -name '*.jpg' -print0 | xargs -r0 mpg123

Any special reason not to use -exec (except of course that xargs works
with any input, while -exec only with find (obviously))

 
  However, be careful with find. If you do not want to search
  subdirectories, it is probably not what you want.
 
 Not true!  Check out the -maxdepth option.  This only searches one
 directory deep.  The second only operates on the command line files.
 
   find . -name '*.jpg' -maxdepth 1 -print0 | xargs -r0 mpg123
   find *.jpg -maxdepth 0 -print0 2/dev/null | xargs -r0 mpg123

Yes indeed. I need to sleep more.

Maybe we should change the examples to feed .mp3 files to mpg123
instead of .jpg files...

Frank

 Bob



-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED] 
with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]




Re: shell game

2002-12-07 Thread Shyamal Prasad
Drew == Drew Cohan [EMAIL PROTECTED] writes:

Drew Hi, Using a bash shell script (/bin/sh), I need to know how
Drew to check to see if certain files exist in a directory, as
Drew in, Are there any jpegs in this directory?.  I've tried
Drew various things (like using -s, -f with test and a do/for
Drew loop) but nothing seems to work right.  The closest I can
Drew come is

Drew if test `ls /opt/images/*.jpg | wc -l` -gt 0 then ...

Drew Unfortunately, this gives me the error message ls:
Drew /opt/images/*.jpg: No such file or directory when there are
Drew no jpegs in /opt/images.

Drew So what am I missing here?

Try this instead:

if [ `find . -maxdepth 1 -name '*.jpg' -print` !=  ]
then 
  # do what you want
fi

The -maxdepth 1 restricts find to the current directory. Take it out
if you want to find anything in subdirectories. If you want to operate
on each file you want to write

for i in `find . -maxdepth 1 -name '*.jpg' -print`
do
  # do something with $i
done

Cheers!
Shyamal


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED] 
with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]




Re: shell game

2002-12-07 Thread Herbert Xu
Michael Heironimus [EMAIL PROTECTED] wrote:
 
 There is a way that looks slightly better, but it's still ugly because
 it relies on bash-specific options. Something like this should do it.
 
 #! /bin/bash
 # Make globs that don't match expand to null string
 shopt -s nullglob
 if [ -n $(echo /path/to/*.jpg) ] ; then
# Do stuff because .jpg files exist
 fi

Here's how you can do it in a POSIX shell:

set -- /path/to/*.jpg
if [ -e $1 ]; then
# Do stuff because .jpg files exist
fi
-- 
Debian GNU/Linux 3.0 is out! ( http://www.debian.org/ )
Email:  Herbert Xu ~{PmVHI~} [EMAIL PROTECTED]
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED] 
with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]




Re: shell game

2002-12-07 Thread Bob Proulx
Shyamal Prasad [EMAIL PROTECTED] [2002-12-07 13:53:57 -0600]:

 if [ `find . -maxdepth 1 -name '*.jpg' -print` !=  ]

A very slight danger here.  If the first filename starts with a '-'
then test will see this as an option instead of as a string and
complain.  This is why people prefix with a known character.  Usually
using an '_' or 'X' or whatever the programmer prefers.  This is
safer.  This is typical when comparing against a non-zero sized
string.

  if [ _`find . -maxdepth 1 -name '*.jpg' -print` != _ ]

However, if you are only testing against a zero length string as here
then using the test operators -z or -n work well without the extra
safeguarding.

  if [ -n `find . -maxdepth 1 -name '*.jpg' -print` ]

Bob



msg17661/pgp0.pgp
Description: PGP signature


Re: shell game

2002-12-07 Thread Shyamal Prasad
Bob == Bob Proulx [EMAIL PROTECTED] writes:

Bob A very slight danger here.  If the first filename starts with
Bob a '-' then test will see this as an option instead of as a
Bob string and complain.  This is why people prefix with a known
Bob character.  Usually using an '_' or 'X' or whatever the
Bob programmer prefers.  This is safer.  This is typical when
Bob comparing against a non-zero sized string.

Bob   if [ _`find . -maxdepth 1 -name '*.jpg' -print` != _ ]

Good catch Bob! Funny thing is that when I wrote this at the shell
prompt to test it I actually did stick a character in (I use 'z'
instead of an underscore, some old habit). I took it out so I would
not have to explain why it was there. In retrospect I should've, no
point in spreading bad habits :-(

Cheers!
Shyamal


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED] 
with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]




Re: shell game

2002-12-07 Thread Michael Heironimus
On Sat, Dec 07, 2002 at 08:26:21PM +0100, Frank Gevaerts wrote:
find . -name '*.jpg' -print0 | xargs -r0 mpg123
 
 Any special reason not to use -exec (except of course that xargs works
 with any input, while -exec only with find (obviously))

I always use xargs instead of find -exec because it just comes more
naturally to me. There are some technical reasons for it, though.

GNU xargs is considerably more versatile than -exec. On some platforms
(not sure about GNU find/xargs) find also spawns a subshell for every
file with -exec, which makes xargs considerably more efficient. Not much
difference for a dozen files, but if you have a few thousand results
you're saving the time of starting a few thousand shells that do nothing
but run a single command and exit.

-- 
Michael Heironimus


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED] 
with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]




shell game

2002-12-06 Thread Drew Cohan
Hi,

Using a bash shell script (/bin/sh), I need to know how to check to see
if certain files exist in a directory, as in, Are there any jpegs in
this directory?.  I've tried various things (like using -s, -f with
test and a do/for loop) but nothing seems to work right.  The closest I
can come is

if test `ls /opt/images/*.jpg | wc -l` -gt 0 then ...

Unfortunately, this gives me the error message ls: /opt/images/*.jpg:
No such file or directory when there are no jpegs in /opt/images.

So what am I missing here?

Thanks,

Drew Cohan
[EMAIL PROTECTED]





-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED] 
with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]




Re: shell game

2002-12-06 Thread Lloyd Zusman
Travis Crump [EMAIL PROTECTED] writes:

 Drew Cohan wrote:
 Hi,
 Using a bash shell script (/bin/sh), I need to know how to check to see
 if certain files exist in a directory, as in, Are there any jpegs in
 this directory?.  I've tried various things (like using -s, -f with
 test and a do/for loop) but nothing seems to work right.  The closest I
 can come is
 if test `ls /opt/images/*.jpg | wc -l` -gt 0 then ...
 Unfortunately, this gives me the error message ls: /opt/images/*.jpg:
 No such file or directory when there are no jpegs in /opt/images.
 So what am I missing here?


  From the there has got to be a better way department:

 ls /opt/images/*.jpg  /dev/null 21  echo there are jpegs

Here's one of several ways to do it in bash that won't involve forking a
subprocess, in case you want to conserve system resources:

  shopt -s nullglob
  result=; for result in /opt/images/*.jpg; do break; done

After this, the '$result' variable will be empty unless there are one or
more files which match the pattern.

-- 
 Lloyd Zusman
 [EMAIL PROTECTED]


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED] 
with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]




Re: shell game

2002-12-06 Thread Gary Turner
Drew Cohan wrote:

Hi,

Using a bash shell script (/bin/sh), I need to know how to check to see
if certain files exist in a directory, as in, Are there any jpegs in
this directory?.  I've tried various things (like using -s, -f with
test and a do/for loop) but nothing seems to work right.  The closest I
can come is

if test `ls /opt/images/*.jpg | wc -l` -gt 0 then ...

Unfortunately, this gives me the error message ls: /opt/images/*.jpg:
No such file or directory when there are no jpegs in /opt/images.

Try 

ls *.jpg  /dev/null 21   # tested command--output is
   
 # superfluous
if 
[ $? eq 0 ] # did last command succeed?
then echo yes # shout hooray
else echo no  # tears in your beer
fi
--
gt   [EMAIL PROTECTED]
It ain't so much what you don't know that gets you in trouble---
it's what you do know that ain't so.--unk


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED] 
with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]




Re: shell game

2002-12-06 Thread Michael Heironimus
On Sat, Dec 07, 2002 at 01:45:45AM -0500, Travis Crump wrote:
 From the there has got to be a better way department:
 
 ls /opt/images/*.jpg  /dev/null 21  echo there are jpegs

There is a way that looks slightly better, but it's still ugly because
it relies on bash-specific options. Something like this should do it.

#! /bin/bash
# Make globs that don't match expand to null string
shopt -s nullglob
if [ -n $(echo /path/to/*.jpg) ] ; then
# Do stuff because .jpg files exist
fi

-- 
Michael Heironimus


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED] 
with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]