Unicode Chars in Windows Path

David bouncingcats at gmail.com
Thu Apr 3 22:02:40 EDT 2014


On 4 April 2014 12:16, Chris Angelico <rosuav at gmail.com> wrote:
> On Fri, Apr 4, 2014 at 11:15 AM, David <bouncingcats at gmail.com> wrote:
>> On 4 April 2014 01:17, Chris Angelico <rosuav at gmail.com> wrote:
>>>
>>> -- Get info on all .pyc files in a directory and all its subdirectories --
>>> C:\>dir some_directory\*.pyc /s
>>> $ ls -l `find some_directory -name \*.pyc`
>>>
>>> Except that the ls version there can't handle names with spaces in
>>> them, so you need to faff around with null termination and stuff.
>>
>> Nooo, that stinks! There's no need to abuse 'find' like that, unless
>> the version you have is truly ancient. Null termination is only
>> necessary to pass 'find' results *via the shell*. Instead, ask 'find'
>> to invoke the task itself.
>>
>> The simplest way is:
>>
>>     find some_directory -name '*.pyc' -ls
>>
>> 'find' is the tool to use for *finding* things, not 'ls', which is
>> intended for terminal display of directory information.
>
> I used ls only as a first example, and then picked up an extremely
> common next example (deleting files). It so happens that find can
> '-delete' its found files, but my point is that on DOS/Windows, every
> command has to explicitly support subdirectories. If, instead, the
> 'find' command has to explicitly support everything you might want to
> do to files, that's even worse! So we need an execution form...
>
>> If you require a particular feature of 'ls', or any other command, you
>> can ask 'find' to invoke it directly (not via a shell):
>>
>>     find some_directory -name '*.pyc' -exec ls -l {} \;
>
> ... which this looks like, but it's not equivalent.

> That will execute
> 'ls -l' once for each file. You can tell, because the columns aren't
> aligned; for anything more complicated than simply 'ls -l', you
> potentially destroy any chance at bulk operations.

Thanks for elaborating that point. But still ...

> equivalent it *must* pass all the args to a single invocation of the
> program. You need to instead use xargs if you want it to be
> equivalent, and it's now getting to be quite an incantation:
>
> find some_directory -name \*.pyc -print0|xargs -0 ls -l
>
> And *that* is equivalent to the original, but it's way *way* longer
> and less convenient, which was my point.

If you are not already aware, it might interest you that 'find' in
(GNU findutils) 4.4.2. has

 -- Action: -execdir command {} +
     This works as for `-execdir command ;', except that the `{}' at
     the end of the command is expanded to a list of names of matching
     files.  This expansion is done in such a way as to avoid exceeding
     the maximum command line length available on the system.  Only one
     `{}' is allowed within the command, and it must appear at the end,
     immediately before the `+'.  A `+' appearing in any position other
     than immediately after `{}' is not considered to be special (that
     is, it does not terminate the command).

I believe that achieves the goal, without involving the shell.

It also has an -exec equivalent that works the same but has an
unrelated security issue and not recommended.

But if that '+' instead of ';' feature is not available on the
target system, then as far as I am aware it would be necessary
to use xargs as you say.

Anyway, the two points I wished to contribute are:

1) It is preferable to avoid shell command substitutions (the
backticks in the first example) and expansions where possible.

2) My observations on 'find' syntax, for anyone interested.

Cheers,
David



More information about the Python-list mailing list