|
|
|
|
||||||
| comp.unix.shell Using and programming the Unix shell. |
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Hi All -
I have a question that is a little confusing to me. 1. First this 'find' command will list files in the current directory, find * -type d -prune -o -type f -print If the current dir has directories only, it will list nothing; if the current dir has both dirs and files, it will list files only. This was tested, and was what I expected. However, the current dir that contains dirs only and that contains both dirs and files behaves differently if I pipe the above command with xargs ls. 2. For the current dir that has dirs only, $find * -type d -prune -o -type f -print this lists nothing; $find * -type d -prune -o -type f -print | xargs ls this strangely lists all the dirs, which I don't understand - I would expect it lists nothing also. 3. For the current dir that has both dirs and files, the commands in (2) work just fine. IF the current dir has, dir1, dir2, dir3, file1, file2, file3, ... $find * -type d -prune -o -type f -print file1 file2 file3 $find * -type d -prune -o -type f -print | xargs ls file1 file2 file3 Can anyone explain to me why in (2), before 'xargs ls', there is nothing, how come 'xargs ls' takes 'nothing' as input and outputs all the dirs under the current dir? Thanks for any insights. |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
On Tue, 07 Nov 2006 09:28:31 -0800, newbie wrote:
> Hi All - > > I have a question that is a little confusing to me. > > 1. First this 'find' command will list files in the current directory, > find * -type d -prune -o -type f -print > If the current dir has directories only, it will list nothing; if > the current dir has both dirs and files, > it will list files only. This was tested, and was what I expected. > > However, the current dir that contains dirs only and that contains both > dirs and files behaves differently if I pipe the above command with > xargs ls. > > 2. For the current dir that has dirs only, > $find * -type d -prune -o -type f -print > this lists nothing; > $find * -type d -prune -o -type f -print | xargs ls > this strangely lists all the dirs, which I don't understand - I > would expect it lists nothing also. > > 3. For the current dir that has both dirs and files, the commands in > (2) work just fine. > IF the current dir has, > dir1, dir2, dir3, file1, file2, file3, ... > $find * -type d -prune -o -type f -print > file1 > file2 > file3 > $find * -type d -prune -o -type f -print | xargs ls > file1 file2 file3 > > > Can anyone explain to me why in (2), before 'xargs ls', there is > nothing, how come 'xargs ls' takes 'nothing' as input and outputs all > the dirs under the current dir? > > Thanks for any insights. It appears that your 'xargs' program runs the command at least once. Try running 'xargs ls < /dev/null'. And of course if you run just 'ls' it lists the things in the current directory. |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
Icarus Sparry wrote: > On Tue, 07 Nov 2006 09:28:31 -0800, newbie wrote: > > > Hi All - > > > > I have a question that is a little confusing to me. > > > > 1. First this 'find' command will list files in the current directory, > > find * -type d -prune -o -type f -print > > If the current dir has directories only, it will list nothing; if > > the current dir has both dirs and files, > > it will list files only. This was tested, and was what I expected. > > > > However, the current dir that contains dirs only and that contains both > > dirs and files behaves differently if I pipe the above command with > > xargs ls. > > > > 2. For the current dir that has dirs only, > > $find * -type d -prune -o -type f -print > > this lists nothing; > > $find * -type d -prune -o -type f -print | xargs ls > > this strangely lists all the dirs, which I don't understand - I > > would expect it lists nothing also. > > > > 3. For the current dir that has both dirs and files, the commands in > > (2) work just fine. > > IF the current dir has, > > dir1, dir2, dir3, file1, file2, file3, ... > > $find * -type d -prune -o -type f -print > > file1 > > file2 > > file3 > > $find * -type d -prune -o -type f -print | xargs ls > > file1 file2 file3 > > > > > > Can anyone explain to me why in (2), before 'xargs ls', there is > > nothing, how come 'xargs ls' takes 'nothing' as input and outputs all > > the dirs under the current dir? > > > > Thanks for any insights. > > It appears that your 'xargs' program runs the command at least once. Try > running 'xargs ls < /dev/null'. Thanks for quick reply. I just used \ find * -type d -prune -o -type f -print | xargs ls < /dev/null but this still listed all dirs in the current dir that had dirs only. > And of course if you run just 'ls' it lists the things in the current > directory. Yes. I understand this. What I was confused, why the current dir that has dirs only is different from that has files and dirs mixed when I issue the above command. The current dir that has dirs and files mixed behaves "correctly", but the current dir that has dirs only (no files) behaves "incorrectly". |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
On Tue, 07 Nov 2006 09:54:27 -0800, newbie wrote:
> Icarus Sparry wrote: >> On Tue, 07 Nov 2006 09:28:31 -0800, newbie wrote: >> [snip] >> > >> > Can anyone explain to me why in (2), before 'xargs ls', there is >> > nothing, how come 'xargs ls' takes 'nothing' as input and outputs all >> > the dirs under the current dir? >> > >> > Thanks for any insights. >> >> It appears that your 'xargs' program runs the command at least once. Try >> running 'xargs ls < /dev/null'. > > Thanks for quick reply. I just used \ > find * -type d -prune -o -type f -print | xargs ls < /dev/null > but this still listed all dirs in the current dir that had dirs only. > >> And of course if you run just 'ls' it lists the things in the current >> directory. > > Yes. I understand this. What I was confused, why the current dir that > has dirs only is different from that has files and dirs mixed when I > issue the above command. The current dir that has dirs and files mixed > behaves "correctly", but the current dir that has dirs only (no files) > behaves "incorrectly". Sorry you misunderstood me. I suggested that you tried running just the following 4 word command xargs ls < /dev/null to gain insight into what was happening, not to append the '< /dev/null' to your command. Essentially if the "find" produces no output then the "xargs" fires off "ls". If say the find produces "fred" and "joe" as output then the xargs fires off "ls fred joe". You can reasonably assert that this is a bug in your copy of xargs. Is this any clearer? Icarus |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
Icarus Sparry wrote: > On Tue, 07 Nov 2006 09:54:27 -0800, newbie wrote: > > > Icarus Sparry wrote: > >> On Tue, 07 Nov 2006 09:28:31 -0800, newbie wrote: > >> > [snip] > >> > > >> > Can anyone explain to me why in (2), before 'xargs ls', there is > >> > nothing, how come 'xargs ls' takes 'nothing' as input and outputs all > >> > the dirs under the current dir? > >> > > >> > Thanks for any insights. > >> > >> It appears that your 'xargs' program runs the command at least once. Try > >> running 'xargs ls < /dev/null'. > > > > Thanks for quick reply. I just used \ > > find * -type d -prune -o -type f -print | xargs ls < /dev/null > > but this still listed all dirs in the current dir that had dirs only. > > > >> And of course if you run just 'ls' it lists the things in the current > >> directory. > > > > Yes. I understand this. What I was confused, why the current dir that > > has dirs only is different from that has files and dirs mixed when I > > issue the above command. The current dir that has dirs and files mixed > > behaves "correctly", but the current dir that has dirs only (no files) > > behaves "incorrectly". > > Sorry you misunderstood me. I suggested that you tried running just the > following 4 word command > > xargs ls < /dev/null > > to gain insight into what was happening, not to append the '< /dev/null' > to your command. Oops, Sorry for the misunderstanding. If I just run $xargs ls < /dev/null, it also lists everything - the same results as $ls. Hmmm... > Essentially if the "find" produces no output then the "xargs" fires off > "ls". If say the find produces "fred" and "joe" as output then the xargs > fires off "ls fred joe". Thanks very much, this explains the puzzle. > You can reasonably assert that this is a bug in your copy of xargs. I am wondering is there a copy of xargs that has not this 'bug'? I tried on a couple of machines, which seemed have the same 'xargs'. > Is this any clearer? Yep, Thank you very much. > Icarus |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
On Tue, 07 Nov 2006 10:42:04 -0800, newbie wrote:
> Icarus Sparry wrote: [snip] >> You can reasonably assert that this is a bug in your copy of xargs. > > I am wondering is there a copy of xargs that has not this 'bug'? I > tried on a couple of machines, which seemed have the same 'xargs'. GNU xargs has a "-r" option which says not to run the command if the input is empty. |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
newbie wrote: > Icarus Sparry wrote: > > On Tue, 07 Nov 2006 09:54:27 -0800, newbie wrote: > > > > > Icarus Sparry wrote: > > >> On Tue, 07 Nov 2006 09:28:31 -0800, newbie wrote: > > >> > > [snip] > > >> > > > >> > Can anyone explain to me why in (2), before 'xargs ls', there is > > >> > nothing, how come 'xargs ls' takes 'nothing' as input and outputs all > > >> > the dirs under the current dir? > > >> > > > >> > Thanks for any insights. > > >> > > >> It appears that your 'xargs' program runs the command at least once. Try > > >> running 'xargs ls < /dev/null'. > > > > > > Thanks for quick reply. I just used \ > > > find * -type d -prune -o -type f -print | xargs ls < /dev/null > > > but this still listed all dirs in the current dir that had dirs only. > > > > > >> And of course if you run just 'ls' it lists the things in the current > > >> directory. > > > > > > Yes. I understand this. What I was confused, why the current dir that > > > has dirs only is different from that has files and dirs mixed when I > > > issue the above command. The current dir that has dirs and files mixed > > > behaves "correctly", but the current dir that has dirs only (no files) > > > behaves "incorrectly". > > > > Sorry you misunderstood me. I suggested that you tried running just the > > following 4 word command > > > > xargs ls < /dev/null > > > > to gain insight into what was happening, not to append the '< /dev/null' > > to your command. > > Oops, Sorry for the misunderstanding. > If I just run $xargs ls < /dev/null, it also lists everything - the > same results as $ls. > Hmmm... > > > Essentially if the "find" produces no output then the "xargs" fires off > > "ls". If say the find produces "fred" and "joe" as output then the xargs > > fires off "ls fred joe". > > Thanks very much, this explains the puzzle. > > > You can reasonably assert that this is a bug in your copy of xargs. > > I am wondering is there a copy of xargs that has not this 'bug'? I > tried on a couple of machines, which seemed have the same 'xargs'. Ah Huh, just read one of the early posts, 'xargs --no-run-if-empty ls' will do the trick. Is this gonna potentially cause other unexpected results? > > Is this any clearer? > > Yep, Thank you very much. > > > Icarus |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
newbie wrote:
> Hi All - > > I have a question that is a little confusing to me. > > 1. First this 'find' command will list files in the current directory, > find * -type d -prune -o -type f -print > If the current dir has directories only, it will list nothing; if > the current dir has both dirs and files, > it will list files only. This was tested, and was what I expected. > > However, the current dir that contains dirs only and that contains both > dirs and files behaves differently if I pipe the above command with > xargs ls. > > 2. For the current dir that has dirs only, > $find * -type d -prune -o -type f -print > this lists nothing; > $find * -type d -prune -o -type f -print | xargs ls > this strangely lists all the dirs, which I don't understand - I > would expect it lists nothing also. > > 3. For the current dir that has both dirs and files, the commands in > (2) work just fine. > IF the current dir has, > dir1, dir2, dir3, file1, file2, file3, ... > $find * -type d -prune -o -type f -print > file1 > file2 > file3 > $find * -type d -prune -o -type f -print | xargs ls > file1 file2 file3 > > > Can anyone explain to me why in (2), before 'xargs ls', there is > nothing, how come 'xargs ls' takes 'nothing' as input and outputs all > the dirs under the current dir? > > Thanks for any insights. > How about the alternative ls -p | grep -v '/$' -- Michael Tosch @ hp : com |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
2006-11-07, 18:53(+00), Icarus Sparry:
> On Tue, 07 Nov 2006 10:42:04 -0800, newbie wrote: > >> Icarus Sparry wrote: > [snip] >>> You can reasonably assert that this is a bug in your copy of xargs. >> >> I am wondering is there a copy of xargs that has not this 'bug'? I >> tried on a couple of machines, which seemed have the same 'xargs'. > > GNU xargs has a "-r" option which says not to run the command if the input > is empty. Anyway, find's output is not compatible with xargs expected input format and find (at least standard compliant implementations) already has the -exec cmd {} + that makes xargs useless. find . -type d -o -type f -exec ls {} + Or with GNU or BSD find/xargs: find . -type d -o -type f -print0 | xargs -r0 ls -- Stéphane |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
2006-11-7, 10:56(-08), newbie:
[...] > Ah Huh, just read one of the early posts, 'xargs --no-run-if-empty ls' > will do the trick. Is this gonna potentially cause other unexpected > results [...] Yes, if any of the filenames contain spaces, tabs, newline, single or double quote, or backslash characters. If using GNU find/xargs, use -print0 | xargs -r0 Portably, use -exec ls {} + (though some old versions of GNU find don't support it). -- Stéphane |
|
|
|
#11 |
|
Messages: n/a
Hébergeur: |
Stephane CHAZELAS wrote: > 2006-11-7, 10:56(-08), newbie: > [...] > > Ah Huh, just read one of the early posts, 'xargs --no-run-if-empty ls' > > will do the trick. Is this gonna potentially cause other unexpected > > results > [...] > > Yes, if any of the filenames contain spaces, tabs, newline, > single or double quote, or backslash characters. > > If using GNU find/xargs, use -print0 | xargs -r0 > > Portably, use -exec ls {} + Actually earlier I tried 'find -exec ls {} \;', but it display each file/dir with a new line, that's why I tried to use xargs. But the '+' worked this time. Thanks! > (though some old versions of GNU find don't support it). > > -- > Stéphane Thank you Stéphane, your posts were very ful, and also thanks to Michael Tosch's method, which worked too. |
|
|
|
#12 |
|
Messages: n/a
Hébergeur: |
Icarus Sparry <usenet@icarus.freeuk.com> wrote:
: >> > : >> > Can anyone explain to me why in (2), before 'xargs ls', there is : >> > nothing, how come 'xargs ls' takes 'nothing' as input and outputs all : >> > the dirs under the current dir? : >> : >> It appears that your 'xargs' program runs the command at least once. Try : >> running 'xargs ls < /dev/null'. : > Yes, this is the default. [...] : Essentially if the "find" produces no output then the "xargs" fires off : "ls". If say the find produces "fred" and "joe" as output then the xargs : fires off "ls fred joe". : : You can reasonably assert that this is a bug in your copy of xargs. No, AFIK the default is to run xargs once even if input is empty. The GNU 'xargs' has a "-r" or "--no-run-if-empty" to not run even once if the input is only blankspace -- wyatt@cfa.harvard.edu.nospam |
|
|
|
#13 |
|
Messages: n/a
Hébergeur: |
2006-11-7, 17:19(-04), Bill Wyatt:
[...] > : Essentially if the "find" produces no output then the "xargs" fires off > : "ls". If say the find produces "fred" and "joe" as output then the xargs > : fires off "ls fred joe". > : > : You can reasonably assert that this is a bug in your copy of xargs. > > No, AFIK the default is to run xargs once even if input is empty. The > GNU 'xargs' has a "-r" or "--no-run-if-empty" to not run even once if > the input is only blankspace [...] Actually, there seems to be a bug in GNU xargs (at least from findutils-4.2.28): $ echo "''" | xargs -r printf '<%s>\n' $ echo "'' " | xargs -r printf '<%s>\n' <> The first one is not correct and should return as the second one. Same problem without -r: $ echo "''" | xargs sh -c 'echo "$#"' sh 0 $ echo "'' " | xargs sh -c 'echo "$#"' sh 1 Obviously, this doesn't apply to the output of "find .". -- Stéphane |
|
|
|
#14 |
|
Messages: n/a
Hébergeur: |
In article <slrnel1nac.c39.stephane.chazelas@spam.is.invalid> ,
Stephane CHAZELAS <this.address@is.invalid> wrote: > 2006-11-7, 10:56(-08), newbie: > [...] > > Ah Huh, just read one of the early posts, 'xargs --no-run-if-empty ls' > > will do the trick. Is this gonna potentially cause other unexpected > > results > [...] > > Yes, if any of the filenames contain spaces, tabs, newline, > single or double quote, or backslash characters. I think you're answering a different question than the one he asked -- you're explaining a general problem with use of find, not a problem that's introduced by the above option. -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** *** PLEASE don't copy me on replies, I'll read them in the group *** |
|
|
|
#15 |
|
Messages: n/a
Hébergeur: |
2006-11-08, 00:30(-05), Barry Margolin:
> In article <slrnel1nac.c39.stephane.chazelas@spam.is.invalid> , > Stephane CHAZELAS <this.address@is.invalid> wrote: > >> 2006-11-7, 10:56(-08), newbie: >> [...] >> > Ah Huh, just read one of the early posts, 'xargs --no-run-if-empty ls' >> > will do the trick. Is this gonna potentially cause other unexpected >> > results >> [...] >> >> Yes, if any of the filenames contain spaces, tabs, newline, >> single or double quote, or backslash characters. > > I think you're answering a different question than the one he asked -- > you're explaining a general problem with use of find, not a problem > that's introduced by the above option. That's right. Though the problem is overall in combining find -print output with xargs. find -print is not post-processable as the file path separator (newline) is a character allowed in a filename (unless you use some tricks like find .//. to identify where the start of a new path is). And xargs expects a very specific input format which to my knowledge no standard utility outputs. By the way, for GNU xargs (at least version 4.2.28), because of another bug, we should add all the [:space:] characters (formfeed, vertical tab and carriage return (\f, \v, \n)) to the list of characters that would cause problem in find -print | xargs. -- Stéphane |
|
![]() |
| Outils de la discussion | |
|
|