python 2.7.12 on Linux behaving differently than on Windows

Michael Torrie torriem at gmail.com
Mon Dec 5 14:08:13 EST 2016


On 12/05/2016 11:21 AM, Chris Angelico wrote:
> On Tue, Dec 6, 2016 at 5:02 AM, BartC <bc at freeuk.com> wrote:
>> If the syntax is:
>>
>>   program filespec
>>
>> or:
>>
>>   program filespec file
>>
>> how do you tell whether the last file in an argument list is the optional
>> 'file', or the last file of the expansion of 'filespec'?
> 
> Why should you care? I have used shell globbing to pass precisely two
> parameters to a program. More often, I use this syntax, which Windows
> simply doesn't support:
> 
> ffmpeg -i some-really-long-file-name.{avi,mkv}
> 
> to convert a file from one format to another. And if the .mkv file
> already exists, I can just use ".*" at the end, although that does
> depend on them being in alphabetical order. The shell is predictable
> and therefore useful. This trick is guaranteed to work, no matter what
> program I'm using. On Windows, I have to hope that the program expands
> these notations correctly.

Agreed. I do this sort of trick all the time, even when I want to pass
just a single file to a program.  I often use expansion for paths as well:

somecommand /path/to/somelongname*withendpart/myepisode*2x03*mp4

I could use tab expansion as I go, but tab expansion might reveal
several options to pick from, requiring a few additional keystrokes to
arrive at the path I want.  Globs save that typing.  And shells are
smart enough to expand the expression even after several wildcards have
been used.  It's a win win.  And the program doesn't have to know
anything about it to work.

Now I usually can use the same expressions in cmd.exe. But I find other
parts of Windows' command-line parsing to really strange, particularly
when it comes to spaces in the filenames.  I'm not sure if this is
cmd.exe's fault or just the win32 api.

In the Unix world, there are times when you don't want shell expansion.
For example, when dealing with ssh or rsync, you most often want the
wildcards and other expression characters to be passed through to the
remote process.  By default zsh makes you escape them all so they won't
attempt expansion locally.  If zsh can't expand an expression locally,
it gives you an error.  This can be controlled with a config option.

Bash on the other hand, passes through any expressions it can't expand
as is.  So under certain circumstances, "python a*.py" would indeed pass
"a*.py" to the program.  But 99% of the time this does not matter.
Whether the glob expands to zero files or the program attempts to open
"a*.py" as a literal file, the effect is usually the same.  Most unix
shells default to this behavior, which is useful when using rsync.

I'd far rather leave it up to the shell to do expansion than to do it
myself in a program. It allows consistency within the shell experience.
If people want the zsh idea of erring out on an expansion, they can have
that.  Or they can use a shell that behaves like bash.  Either way there
is a consistency there that's just not there on Windows.


More information about the Python-list mailing list