Re: Shell game? was Re: pmount could perhaps be of greater utility?
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?
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?
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?
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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]