Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #38159 > unrolled thread

Opinion on best practice...

Started byAnthony Correia <akcorreia@gmail.com>
First post2013-02-04 20:14 -0800
Last post2013-02-05 22:07 -0700
Articles 20 on this page of 40 — 18 participants

Back to article view | Back to comp.lang.python


Contents

  Opinion on best practice... Anthony Correia <akcorreia@gmail.com> - 2013-02-04 20:14 -0800
    Re: Opinion on best practice... Michael Torrie <torriem@gmail.com> - 2013-02-04 23:04 -0700
    Re: Opinion on best practice... Terry Reedy <tjreedy@udel.edu> - 2013-02-05 02:56 -0500
      Re: Opinion on best practice... Grant Edwards <invalid@invalid.invalid> - 2013-02-05 13:23 +0000
    Re: Opinion on best practice... Ulrich Eckhardt <ulrich.eckhardt@dominolaser.com> - 2013-02-05 08:56 +0100
      Re: Opinion on best practice... Peter Otten <__peter__@web.de> - 2013-02-05 11:35 +0100
        Re: Opinion on best practice... Ulrich Eckhardt <ulrich.eckhardt@dominolaser.com> - 2013-02-05 14:05 +0100
    Re: Opinion on best practice... Grant Edwards <invalid@invalid.invalid> - 2013-02-05 13:22 +0000
      Re: Opinion on best practice... Walter Hurry <walterhurry@lavabit.com> - 2013-02-05 21:01 +0000
        Re: Opinion on best practice... Neil Cerutti <neilc@norwich.edu> - 2013-02-05 21:39 +0000
          Re: Opinion on best practice... Ethan Furman <ethan@stoneleaf.us> - 2013-02-05 14:07 -0800
            Re: Opinion on best practice... Grant Edwards <invalid@invalid.invalid> - 2013-02-05 23:00 +0000
              Re: Opinion on best practice... Chris Angelico <rosuav@gmail.com> - 2013-02-06 10:35 +1100
                Re: Opinion on best practice... Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-02-06 12:55 +1100
                  Re: Opinion on best practice... Dan Stromberg <drsalists@gmail.com> - 2013-02-05 18:14 -0800
                  Re: Opinion on best practice... Chris Angelico <rosuav@gmail.com> - 2013-02-06 17:16 +1100
                  Re: Opinion on best practice... rusi <rustompmody@gmail.com> - 2013-02-05 23:32 -0800
                  Re: Opinion on best practice... Grant Edwards <invalid@invalid.invalid> - 2013-02-06 15:18 +0000
                  Re: Opinion on best practice... Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2013-02-06 12:37 -0500
                    Re: Opinion on best practice... Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-02-07 10:46 +1100
                      Re: Opinion on best practice... Chris Angelico <rosuav@gmail.com> - 2013-02-07 16:28 +1100
                        Re: Opinion on best practice... Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-02-07 06:50 +0000
                          Re: Opinion on best practice... Chris Angelico <rosuav@gmail.com> - 2013-02-07 18:49 +1100
                            Re: Opinion on best practice... Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-02-08 09:49 +1100
                              Re: Opinion on best practice... Chris Angelico <rosuav@gmail.com> - 2013-02-08 17:54 +1100
                              Re: Opinion on best practice... Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2013-02-08 12:41 -0500
                          Re: Opinion on best practice... Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2013-02-07 13:54 -0500
                            Re: Opinion on best practice... Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-02-08 09:58 +1100
                              Re: Opinion on best practice... Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2013-02-08 13:29 -0500
                              Re: Opinion on best practice... Chris Angelico <rosuav@gmail.com> - 2013-02-09 11:28 +1100
                  Re: Opinion on best practice... John Ladasky <john_ladasky@sbcglobal.net> - 2013-02-08 19:10 -0800
              Re: Opinion on best practice... Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2013-02-06 00:33 -0500
                Re: Opinion on best practice... Anssi Saari <as@sci.fi> - 2013-02-06 15:30 +0200
          Re: Opinion on best practice... Grant Edwards <invalid@invalid.invalid> - 2013-02-05 22:59 +0000
            Re: Opinion on best practice... Ian Kelly <ian.g.kelly@gmail.com> - 2013-02-05 17:05 -0700
              Re: Opinion on best practice... Grant Edwards <invalid@invalid.invalid> - 2013-02-06 15:04 +0000
            Re: Opinion on best practice... Neil Cerutti <neilc@norwich.edu> - 2013-02-06 14:20 +0000
              Re: Opinion on best practice... Grant Edwards <invalid@invalid.invalid> - 2013-02-06 15:11 +0000
        Re: Opinion on best practice... Nobody <nobody@nowhere.com> - 2013-02-06 03:32 +0000
          Re: Opinion on best practice... Michael Torrie <torriem@gmail.com> - 2013-02-05 22:07 -0700

Page 1 of 2  [1] 2  Next page →


#38159 — Opinion on best practice...

FromAnthony Correia <akcorreia@gmail.com>
Date2013-02-04 20:14 -0800
SubjectOpinion on best practice...
Message-ID<207d17ce-4bc7-487c-acde-6a7b9f66002b@googlegroups.com>
I need to pick up a language that would cover the Linux platform.  I use Powershell for a scripting language on the Windows side of things.  Very simple copy files script.  Is this the best way to do it?  

import os

    objdir = ("C:\\temp2")
    colDir = os.listdir(objdir)
    for f in colDir:
        activefile = os.path.join(objdir + "\\" + f)
        print ("Removing " + activefile + " from " + objdir)
        os.remove(activefile)

In Powershell I would just do:

$colDir = gci -path "c:\temp2"
ForEach($file in $colDir)

[toc] | [next] | [standalone]


#38166

FromMichael Torrie <torriem@gmail.com>
Date2013-02-04 23:04 -0700
Message-ID<mailman.1352.1360044301.2939.python-list@python.org>
In reply to#38159
On 02/04/2013 09:14 PM, Anthony Correia wrote:
> I need to pick up a language that would cover the Linux platform. I
use Powershell for a scripting language on the Windows side of things.
Very simple copy files script. Is this the best way to do it?
>
> import os
>
>     objdir = ("C:\\temp2")
>     colDir = os.listdir(objdir)
>     for f in colDir:
>         activefile = os.path.join(objdir + "\\" + f)
>         print ("Removing " + activefile + " from " + objdir)
>         os.remove(activefile)
>
> In Powershell I would just do:
>
> $colDir = gci -path "c:\temp2"
> ForEach($file in $colDir)

Yes you could do something like that in Python.  I know on linux there
is a module called shutils that provides more shell file handling
abilities to python.  Your script as it is listed has a few bugs, though:
- os.listdir() walks the current working directory, not necessarily c:\temp2
- instead of using "\\" in the os.path.join, you can use os.path.sep to
get the current platform's separator character

While I do use python for shell scripting, by itself, it's not very good
at it.  I ended up writing my own wrapper function to run external
commands, feed them std-in, and capture standard out and standard error.
 I wrapped one of the subprocess module functions.  Not sure which.  I
can post the file to the list if anyone wants to see it.  Also as I
mentioned, on unix machines there is the shutils module.

Still, though, sometimes a proper shell like bash or zsh is going to
work out better for shell scripting than python.  Plus if you're going
to be proficient on the Linux command line you need to know their basics
anyway.

[toc] | [prev] | [next] | [standalone]


#38174

FromTerry Reedy <tjreedy@udel.edu>
Date2013-02-05 02:56 -0500
Message-ID<mailman.1359.1360051187.2939.python-list@python.org>
In reply to#38159
On 2/4/2013 11:14 PM, Anthony Correia wrote:
> I need to pick up a language that would cover the Linux platform.  I use Powershell for a scripting language on the Windows side of things.  Very simple copy files script.  Is this the best way to do it?
>
> import os
>
>      objdir = ("C:\\temp2")
>      colDir = os.listdir(objdir)
>      for f in colDir:
>          activefile = os.path.join(objdir + "\\" + f)
>          print ("Removing " + activefile + " from " + objdir)
>          os.remove(activefile)
>
> In Powershell I would just do:
>
> $colDir = gci -path "c:\temp2"
> ForEach($file in $colDir)

Python comes with a shutil module with multiple copy functions.


-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#38190

FromGrant Edwards <invalid@invalid.invalid>
Date2013-02-05 13:23 +0000
Message-ID<ker144$iii$2@reader1.panix.com>
In reply to#38174
On 2013-02-05, Terry Reedy <tjreedy@udel.edu> wrote:
> On 2/4/2013 11:14 PM, Anthony Correia wrote:
>> I need to pick up a language that would cover the Linux platform.  I use Powershell for a scripting language on the Windows side of things.  Very simple copy files script.  Is this the best way to do it?
>>
>> import os
>>
>>      objdir = ("C:\\temp2")
>>      colDir = os.listdir(objdir)
>>      for f in colDir:
>>          activefile = os.path.join(objdir + "\\" + f)
>>          print ("Removing " + activefile + " from " + objdir)
>>          os.remove(activefile)
>>
>> In Powershell I would just do:
>>
>> $colDir = gci -path "c:\temp2"
>> ForEach($file in $colDir)
>
> Python comes with a shutil module with multiple copy functions.

Most of the time when I find myself using the shutil module, it means
the program should have been written in bash. :)

-- 
Grant Edwards               grant.b.edwards        Yow! A shapely CATHOLIC
                                  at               SCHOOLGIRL is FIDGETING
                              gmail.com            inside my costume..

[toc] | [prev] | [next] | [standalone]


#38176

FromUlrich Eckhardt <ulrich.eckhardt@dominolaser.com>
Date2013-02-05 08:56 +0100
Message-ID<kiq6u9-r6o.ln1@satorlaser.homedns.org>
In reply to#38159
Am 05.02.2013 05:14, schrieb Anthony Correia:
> I need to pick up a language that would cover the Linux platform.  I use Powershell for a scripting language on the Windows side of things.  Very simple copy files script.  Is this the best way to do it?
>
> import os
>
>      objdir = ("C:\\temp2")

Drop the parens here.

>      colDir = os.listdir(objdir)
>      for f in colDir:
>          activefile = os.path.join(objdir + "\\" + f)

The point of os.path.join is exactly that you don't have to spell out 
the system-specific file separator. In this case, it gets called with a 
single string, which it return as-is.

>          print ("Removing " + activefile + " from " + objdir)

Instead of using + to concat strings, use the format() functionn:

    "removing {} from {}".format(activefile, objdir)

Also, if you are using Python 2, print is a statement, not a function, 
so you could drop the parens here, too. I would not recommend that 
though! Instead, "from __future__ import print_function" and keep using 
print() as a function, just like in Python 3.

In general, I would not have stored the result of os.listdir() in a 
separate variable but iterated over it directly. For large dirs, it 
could also be better to use os.path.walk(), because that doesn't first 
build a list and then iterate over the list but iterates over the single 
elements directly. This avoids the memory allocation overhead, although 
it is unlikely to make a difference in this case and a Premature 
Optimization(tm).

Welcome to Python!

Uli

[toc] | [prev] | [next] | [standalone]


#38180

FromPeter Otten <__peter__@web.de>
Date2013-02-05 11:35 +0100
Message-ID<mailman.1361.1360060534.2939.python-list@python.org>
In reply to#38176
Ulrich Eckhardt wrote:

> separate variable but iterated over it directly. For large dirs, it
> could also be better to use os.path.walk(), because that doesn't first
> build a list and then iterate over the list but iterates over the single
> elements directly. This avoids the memory allocation overhead, although
> it is unlikely to make a difference in this case and a Premature
> Optimization(tm).

Not true. os.walk() uses os.listdir() internally.

[toc] | [prev] | [next] | [standalone]


#38188

FromUlrich Eckhardt <ulrich.eckhardt@dominolaser.com>
Date2013-02-05 14:05 +0100
Message-ID<0lc7u9-mlp.ln1@satorlaser.homedns.org>
In reply to#38180
Am 05.02.2013 11:35, schrieb Peter Otten:
> Ulrich Eckhardt wrote:
>> [...] use os.path.walk(), because that doesn't first  build a list and
>> then iterate over the list but iterates over the single elements directly.
[...]
> Not true. os.walk() uses os.listdir() internally.

Oh. 8|

Thanks for proofreading what I wrote, I must have been confusing it with 
something else.

Thanks&sorry!

Uli

[toc] | [prev] | [next] | [standalone]


#38189

FromGrant Edwards <invalid@invalid.invalid>
Date2013-02-05 13:22 +0000
Message-ID<ker11p$iii$1@reader1.panix.com>
In reply to#38159
On 2013-02-05, Anthony Correia <akcorreia@gmail.com> wrote:

> I need to pick up a language that would cover the Linux platform.

Well, you haven't really described what it is you're trying to do, but
it looks to me like bash and the usual set of shell utilities (e.g.
find) is what you need rather than Python.  

> I use Powershell for a scripting language on the Windows side of
> things.  Very simple copy files script.  Is this the best way to do
> it?  

That depends.  What is "it"?

> import os
>
>     objdir = ("C:\\temp2")
>     colDir = os.listdir(objdir)
>     for f in colDir:
>         activefile = os.path.join(objdir + "\\" + f)
>         print ("Removing " + activefile + " from " + objdir)
>         os.remove(activefile)
>
> In Powershell I would just do:
>
> $colDir = gci -path "c:\temp2"
> ForEach($file in $colDir)

Sorry, I'm a Linux guy.  I have no clue what that means.

-- 
Grant Edwards               grant.b.edwards        Yow! Well, I'm INVISIBLE
                                  at               AGAIN ... I might as well
                              gmail.com            pay a visit to the LADIES
                                                   ROOM ...

[toc] | [prev] | [next] | [standalone]


#38229

FromWalter Hurry <walterhurry@lavabit.com>
Date2013-02-05 21:01 +0000
Message-ID<kers04$1gi$2@news.albasani.net>
In reply to#38189
On Tue, 05 Feb 2013 13:22:02 +0000, Grant Edwards wrote:

> On 2013-02-05, Anthony Correia <akcorreia@gmail.com> wrote:
> 
>> I need to pick up a language that would cover the Linux platform.
> 
> Well, you haven't really described what it is you're trying to do, but
> it looks to me like bash and the usual set of shell utilities (e.g.
> find) is what you need rather than Python.
> 
>> I use Powershell for a scripting language on the Windows side of
>> things.  Very simple copy files script.  Is this the best way to do it?
> 
> That depends.  What is "it"?
> 
>> import os
>>
>>     objdir = ("C:\\temp2") colDir = os.listdir(objdir)
>>     for f in colDir:
>>         activefile = os.path.join(objdir + "\\" + f)
>>         print ("Removing " + activefile + " from " + objdir)
>>         os.remove(activefile)
>>
>> In Powershell I would just do:
>>
>> $colDir = gci -path "c:\temp2"
>> ForEach($file in $colDir)
> 
> Sorry, I'm a Linux guy.  I have no clue what that means.

Hooray for common sense! Python is great, but it's silly to use Python 
(unless there is good reason) when a simple shell script will do the job.

I think he means (bash speak):

for file in <whateverdir>

[toc] | [prev] | [next] | [standalone]


#38232

FromNeil Cerutti <neilc@norwich.edu>
Date2013-02-05 21:39 +0000
Message-ID<andcgpFbac1U1@mid.individual.net>
In reply to#38229
On 2013-02-05, Walter Hurry <walterhurry@lavabit.com> wrote:
>> Sorry, I'm a Linux guy.  I have no clue what that means.
>
> Hooray for common sense! Python is great, but it's silly to use
> Python (unless there is good reason) when a simple shell script
> will do the job.

Python is an excellent option for writing shell scripts,
particularly if your shell is cmd.exe.

-- 
Neil Cerutti

[toc] | [prev] | [next] | [standalone]


#38237

FromEthan Furman <ethan@stoneleaf.us>
Date2013-02-05 14:07 -0800
Message-ID<mailman.1393.1360102601.2939.python-list@python.org>
In reply to#38232
On 02/05/2013 01:39 PM, Neil Cerutti wrote:
> On 2013-02-05, Walter Hurry <walterhurry@lavabit.com> wrote:
>>> Sorry, I'm a Linux guy.  I have no clue what that means.
>>
>> Hooray for common sense! Python is great, but it's silly to use
>> Python (unless there is good reason) when a simple shell script
>> will do the job.
>
> Python is an excellent option for writing shell scripts,
> particularly if your shell is cmd.exe.

I believe having your shell be cmd.exe qualifies as a "good reason"!

:)

~Ethan~

[toc] | [prev] | [next] | [standalone]


#38243

FromGrant Edwards <invalid@invalid.invalid>
Date2013-02-05 23:00 +0000
Message-ID<kes2u6$q6n$2@reader1.panix.com>
In reply to#38237
On 2013-02-05, Ethan Furman <ethan@stoneleaf.us> wrote:
> On 02/05/2013 01:39 PM, Neil Cerutti wrote:
>> On 2013-02-05, Walter Hurry <walterhurry@lavabit.com> wrote:
>>>> Sorry, I'm a Linux guy.  I have no clue what that means.
>>>
>>> Hooray for common sense! Python is great, but it's silly to use
>>> Python (unless there is good reason) when a simple shell script
>>> will do the job.
>>
>> Python is an excellent option for writing shell scripts,
>> particularly if your shell is cmd.exe.
>
> I believe having your shell be cmd.exe qualifies as a "good reason"!

Except the OP said he wanted to pick a language for Linux.  If he has
cmd.exe as his shell on Linux, then he's beyond help...

-- 
Grant Edwards               grant.b.edwards        Yow! I'm a GENIUS!  I want
                                  at               to dispute sentence
                              gmail.com            structure with SUSAN
                                                   SONTAG!!

[toc] | [prev] | [next] | [standalone]


#38244

FromChris Angelico <rosuav@gmail.com>
Date2013-02-06 10:35 +1100
Message-ID<mailman.1396.1360107343.2939.python-list@python.org>
In reply to#38243
On Wed, Feb 6, 2013 at 10:00 AM, Grant Edwards <invalid@invalid.invalid> wrote:
> On 2013-02-05, Ethan Furman <ethan@stoneleaf.us> wrote:
>> On 02/05/2013 01:39 PM, Neil Cerutti wrote:
>>> Python is an excellent option for writing shell scripts,
>>> particularly if your shell is cmd.exe.
>>
>> I believe having your shell be cmd.exe qualifies as a "good reason"!
>
> Except the OP said he wanted to pick a language for Linux.  If he has
> cmd.exe as his shell on Linux, then he's beyond help...

Python is not an "excellent option". It's a bad fit for shell
scripting, it just happens to be way better than a weak shell. Having
grown up on command.com, I found OS/2's cmd.exe to be a massive
improvement, and Windows's cmd.exe to be rather less impressive... but
both of them pale into insignificance compared to bash. OS/2 has a
better shell scripting language (REXX), but Windows doesn't, and
Python ain't it.

(Hmm. Google Chrome doesn't put its red squiggly lines under "ain't",
but it does complain about "virtualization". Seems to me something,
uhh, ain't right there.)

ChrisA

[toc] | [prev] | [next] | [standalone]


#38250

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-02-06 12:55 +1100
Message-ID<5111b826$0$29969$c3e8da3$5496439d@news.astraweb.com>
In reply to#38244
Chris Angelico wrote:

> Python is not an "excellent option". It's a bad fit for shell
> scripting, it just happens to be way better than a weak shell. Having
> grown up on command.com, I found OS/2's cmd.exe to be a massive
> improvement, and Windows's cmd.exe to be rather less impressive... but
> both of them pale into insignificance compared to bash.

I have to disagree with much of this. bash is a poorly designed language
which, in my opinion, is only good enough for short (under 20 lines)
throw-away scripts.

[begin rant]

bash has terse *and* cryptic syntax even less maintainable than Perl. E.g.
this is, apparently, the right way to get the length of an array called R:

rlen=${#R[@]}

(taken from here:

http://www.bashcookbook.com/bashinfo/source/bash-4.2/examples/functions/array-stuff

so I hope that they know what they're talking about.)

Note that sometimes # begins a comment, and sometimes it doesn't.

This is how you test whether something is not the name of a directory:

[[ -d $dir ]] || {
  echo "$FUNCNAME: $dir is not a directory" >&2
  return 2
}


http://www.bashcookbook.com/bashinfo/source/bash-4.2/examples/functions/emptydir

Arithmetic requires either calling an external program, or special magic
syntax:

z=`expr $z + 3`
i=$(( i + 1 ))

Spaces are magic -- these two lines do radically different things:

i = j
i=j

There's also a "let" command, but it's a kludge:

k=$(( i+2 )) 
let k=i+2

are equivalent, but 

k=$(( i*2 ))
let k=i*2

are not!

bash is even more weakly typed than Perl. As far as I can tell, bash is
completely untyped -- everything is text, all the time, even arrays.

[steve@ando ~]$ cat testarray.sh
colors=('Blue' 'Red')
echo $((colors + 2))

[steve@ando ~]$ sh testarray.sh
2

Quotation marks have magic powers, and the rules for them are so complicated
that working out how to correctly quote expressions is probably the single
most difficult part of bash scripting.

bash teaches bad programming habits, such as reliance on global and
environment variables, and lacks "modern" (30+ years old) features such as
exception handling, objects, and even proper functions that return a
result. Yes, that's right, bash functions communicate their result by
side-effect.

http://www.linuxjournal.com/content/return-values-bash-functions

Because bash scripts are mostly written by non-programmers, the culture as a
whole has a cargo-cult mentality about it. I'm sure that there are some
people who actually do know bash, it's strengths and weaknesses, well, but
in my experience most people just blindly copy code snippets and recipes
around without really understanding them. As a consequence, we have this:

http://partmaps.org/era/unix/award.html

Almost nothing in bash is portable. Because bash does so little, and relies
on external programs for so much, even if you write the bash parts portably
(which basically means writing for the Bourne shell, which is even more
lacking than bash), you *still* aren't portable because there's no
guarantee that the external programs exist or do what you expect on some
other system.

To do anything meaningful in bash, you need to be an expert on passing work
off to other programs, e.g. sed, awk, grep, tr, cut, ed, ps, dc, wc, ...
any of which may be missing, or have different semantics from what you
expect (ps in particular is notorious for the widely variable command
switches it takes), or output their results in unexpected ways.

Pretty much of all bash scripting is kludge on top of kludge, special
behaviour, small syntax differences making large differences in behaviour,
surprising gotchas, side-effects and magic. If you took the Zen of Python,
and pretty much reversed everything, you might have the Zen of Bash:

Implicit is better than explicit.
Complex is better than simple.
Complicated is better than complex.
Dense is better than sparse.
Readability doesn't count.
Special cases break the rules.
Errors should pass silently.
In the face of ambiguity, guess.
There should be many obscure ways to do it.
Namespaces are terrible, let's make everything global!

I would not hesitate to use Python, or some other high-level language like
Ruby, over bash for anything non-trivial that I cared about. It might not
be as terse and compact as a well-written bash script, but that's a *good*
thing, and a poorly-written bash script is likely to be even more verbose
and difficult to write than a poorly-written Python script.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#38251

FromDan Stromberg <drsalists@gmail.com>
Date2013-02-05 18:14 -0800
Message-ID<mailman.1400.1360116867.2939.python-list@python.org>
In reply to#38250

[Multipart message — attachments visible in raw view] — view raw

On Feb 5, 2013 6:00 PM, "Steven D&apos;Aprano" <
steve+comp.lang.python@pearwood.info> wrote:
>
> Chris Angelico wrote:
>
> > Python is not an "excellent option". It's a bad fit for shell
> > scripting, it just happens to be way better than a weak shell. Having
> > grown up on command.com, I found OS/2's cmd.exe to be a massive
> > improvement, and Windows's cmd.exe to be rather less impressive... but
> > both of them pale into insignificance compared to bash.
>
> I have to disagree with much of this. bash is a poorly designed language
> which, in my opinion, is only good enough for short (under 20 lines)
> throw-away scripts.

I agree that Python is usually a great option, but sadly I also have to
agree that bash has moved too far in the direction of Perl.

However, if you can stick to a Bournish subset of bash, it's really good
for some problems, being almost lispish and being very parallel.

Error checking in shell needn't be haphazard, even though that's how it's
usually done.

[toc] | [prev] | [next] | [standalone]


#38257

FromChris Angelico <rosuav@gmail.com>
Date2013-02-06 17:16 +1100
Message-ID<mailman.1404.1360131373.2939.python-list@python.org>
In reply to#38250
On Wed, Feb 6, 2013 at 12:55 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> Chris Angelico wrote:
>
>> Python is not an "excellent option". It's a bad fit for shell
>> scripting, it just happens to be way better than a weak shell. Having
>> grown up on command.com, I found OS/2's cmd.exe to be a massive
>> improvement, and Windows's cmd.exe to be rather less impressive... but
>> both of them pale into insignificance compared to bash.
>
> I have to disagree with much of this. bash is a poorly designed language
> which, in my opinion, is only good enough for short (under 20 lines)
> throw-away scripts.
>
> [snip rant]

Your points are valid, and yet I still can't push Python as a command
execution language better than bash scripting. "Nobody" was right: as
soon as you are actually *processing* data, you want something better
than bash.

If I want to make a simple command that pulls the latest project
changes and then shows me those changes, I'm going to write a bash
script that does this:

git pull --rebase
git log --oneline origin/master..master
gitk &

Actually the script's a bit more detailed than that (variable branch,
makes a tag 'lastsync' so that I can go back to it later, passes gitk
some args so it shows me the commit most likely to be of first
interest, etc), but it's still pretty much all command execution. Now
maybe if I were using Mercurial, I could script some of that using
Python; but that would be a special-case that stems from Mercurial
actually having been written in Python, and it doesn't help if you're
working with some other set of commands that don't happen to be
importable.

But what tends to happen at work is that a script like that grows
until it hits a couple dozen lines of code, and then it gets
transparently rewritten into some other language (change the shebang
at the top, nobody needs to know/care that it got a complete rewrite).
My weapon of choice for these rewrites is usually Pike, not Python,
mainly because we don't currently have any significant amount of
Python in our codebase, but either would most likely do. (I haven't
looked into subprocess and how portable my code would be across
2.6/2.7/3.3, though.) The fact remains, though, that an applications
language is definitely *second choice* to bash scripting when it comes
to tasks that involve lots of command execution.

It feels silly enough translating this OS/2 batch script:

@logon SOME_USER /pSOME_PASS /vl
@e:\rexx\load
@db2 start database manager
@exit

into this REXX script:

/* */
"@logon SOME_USER /pSOME_PASS /vl"
"@e:\rexx\load"
"@db2 start database manager"
"@exit"

And that's a change I've made myriad times (to \startup.cmd on many an
OS/2 boot drive) It's far far worse translating it into Python, Pike,
or any other "good language".

ChrisA

[toc] | [prev] | [next] | [standalone]


#38260

Fromrusi <rustompmody@gmail.com>
Date2013-02-05 23:32 -0800
Message-ID<0571c9fa-9c6c-4eb5-9f38-6beef5ff9a52@k8g2000yqb.googlegroups.com>
In reply to#38250
On Feb 6, 6:55 am, Steven D'Aprano <steve
+comp.lang.pyt...@pearwood.info> wrote:

> I would not hesitate to use Python, or some other high-level language like
> Ruby, over bash for anything non-trivial that I cared about. It might not
> be as terse and compact as a well-written bash script, but that's a *good*
> thing, and a poorly-written bash script is likely to be even more verbose
> and difficult to write than a poorly-written Python script.

Maybe you should look at scsh or rc http://paganbooks.eu/software/article/rc-duff

Heres the author of scsh (which would not be saying much were it not
for his uber-geek status)
(from http://www.scsh.net/docu/scsh-paper/scsh-paper-Z-H-1.html )
----------------
Shell programming terrifies me. There is something about writing a
simple shell script that is just much, much more unpleasant than
writing a simple C program, or a simple COMMON LISP program, or a
simple Mips assembler program. Is it trying to remember what the rules
are for all the different quotes? Is it having to look up the multi-
phased interaction between filename expansion, shell variables,
quotation, backslashes and alias expansion? Maybe it's having to
subsequently look up which of the twenty or thirty flags I need for my
grep, sed, and awk invocations. Maybe it just gets on my nerves that I
have to run two complete programs simply to count the number of files
in a directory (ls | wc -l), which seems like several orders of
magnitude more cycles than was really needed.

[toc] | [prev] | [next] | [standalone]


#38287

FromGrant Edwards <invalid@invalid.invalid>
Date2013-02-06 15:18 +0000
Message-ID<kets7h$4j9$3@reader1.panix.com>
In reply to#38250
On 2013-02-06, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote:
> Chris Angelico wrote:
>
>> Python is not an "excellent option". It's a bad fit for shell
>> scripting, it just happens to be way better than a weak shell. Having
>> grown up on command.com, I found OS/2's cmd.exe to be a massive
>> improvement, and Windows's cmd.exe to be rather less impressive... but
>> both of them pale into insignificance compared to bash.
>
> I have to disagree with much of this. bash is a poorly designed
> language which, in my opinion, is only good enough for short (under
> 20 lines) throw-away scripts.

And the OP wanted to write someting that was what, about 3 lines?

> This is how you test whether something is not the name of a directory:
>
> [[ -d $dir ]] || {
>   echo "$FUNCNAME: $dir is not a directory" >&2
>   return 2
> }

It can be written more clearly.

> http://www.bashcookbook.com/bashinfo/source/bash-4.2/examples/functions/emptydir
>
> Arithmetic requires either calling an external program, or special magic
> syntax:
>
> z=`expr $z + 3`
> i=$(( i + 1 ))

Agreed: Bash is not good at math.  It should not be used for numerical
analysis.

> Spaces are magic -- these two lines do radically different things:

So?  Leading spaces are magic in Python.

> bash is even more weakly typed than Perl. As far as I can tell, bash
> is completely untyped -- everything is text, all the time, even
> arrays.

Correct.  In bash, everything is a string.

If you're doing something other than manipulating files (and therefore
filenames and paths), then bash is probably the wrong language to use.

-- 
Grant Edwards               grant.b.edwards        Yow! Are we wet yet?
                                  at               
                              gmail.com            

[toc] | [prev] | [next] | [standalone]


#38298

FromDennis Lee Bieber <wlfraed@ix.netcom.com>
Date2013-02-06 12:37 -0500
Message-ID<mailman.1423.1360172253.2939.python-list@python.org>
In reply to#38250
On Wed, 6 Feb 2013 17:16:04 +1100, Chris Angelico <rosuav@gmail.com>
declaimed the following in gmane.comp.python.general:

> 
> It feels silly enough translating this OS/2 batch script:
> 
> @logon SOME_USER /pSOME_PASS /vl
> @e:\rexx\load
> @db2 start database manager
> @exit
> 
> into this REXX script:
> 
> /* */
> "@logon SOME_USER /pSOME_PASS /vl"
> "@e:\rexx\load"
> "@db2 start database manager"
> "@exit"
> 
> And that's a change I've made myriad times (to \startup.cmd on many an
> OS/2 boot drive) It's far far worse translating it into Python, Pike,
> or any other "good language".
>
	Though that is the nice feature of REXX*... Anything that wasn't
parsable as a REXX statement was automatically sent to the current
command processor.

	Converting such to Python turns into a mishmash of (pick your
favorite) os.system(), subprocess.Popen(), etc. with their particulars
of how to pass command line arguments.

*	{the Amiga variant was really powerful as it didn't take much to
code an application so that it could be a command processor, including
another ARexx script}


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
        wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

[toc] | [prev] | [next] | [standalone]


#38316

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-02-07 10:46 +1100
Message-ID<5112eb4a$0$29965$c3e8da3$5496439d@news.astraweb.com>
In reply to#38298
Dennis Lee Bieber wrote:

> On Wed, 6 Feb 2013 17:16:04 +1100, Chris Angelico <rosuav@gmail.com>
> declaimed the following in gmane.comp.python.general:
> 
>> 
>> It feels silly enough translating this OS/2 batch script:
>> 
>> @logon SOME_USER /pSOME_PASS /vl
>> @e:\rexx\load
>> @db2 start database manager
>> @exit
>> 
>> into this REXX script:
>> 
>> /* */
>> "@logon SOME_USER /pSOME_PASS /vl"
>> "@e:\rexx\load"
>> "@db2 start database manager"
>> "@exit"
>> 
>> And that's a change I've made myriad times (to \startup.cmd on many an
>> OS/2 boot drive) It's far far worse translating it into Python, Pike,
>> or any other "good language".
>>
> Though that is the nice feature of REXX*... Anything that wasn't
> parsable as a REXX statement was automatically sent to the current
> command processor.

Nice? Are you being sarcastic? What you're describing sounds like a
classic "Do What I Mean" system, which invariably end up being followed by
anguished shouts of "Noooo, I didn't mean that!!!".

The Zen of Python is not just design principles for *Python*. They hold for
other languages as well. Having to explicitly send a command to an external
command processor (say, the shell) is much better **and safer** than
implicitly doing so on SyntaxError, even if such a requirement makes your
program more verbose.


> Converting such to Python turns into a mishmash of (pick your
> favorite) os.system(), subprocess.Popen(), etc. with their particulars
> of how to pass command line arguments.

Why on earth would anyone use a "mismash" within the one script? Pick one
and stick to it. If you have only wish to give a few commands, and don't
care about getting data back from them, use os.system which is
embarrassingly easy and almost as concise as the REXX script above:

from os import system as s
s("@logon SOME_USER /pSOME_PASS /vl")
s("@e:\rexx\load")
s("@db2 start database manager")
s("@exit")


If you find yourself needing complicated string escapes, use subprocess.call
instead.

If you do care about getting data back from the external system, then you
need to integrate the external code with your Python (or REXX) code, and
that requires more than just firing off a few system commands and
forgetting about them. That's inherently complicated, because there are
many possible factors to care about:

- do you care about stdout, stderr, stdin?
- start a new subshell?
- deal with shell metacharacters?
- deadlocks?

etc. Lack of terse syntax is the least of your worries here, doing these
things *correctly* is hard in the shell. Having to type a few extra symbols
doesn't make it any harder in any meaningful way, and readable syntax can
actually make it simpler to reason about the code.


If you say "Anything that isn't parsable is automatically sent to the
shell", it doesn't sound too bad. But when you say "Unparseable junk is
implicitly treated as code and sent off to be executed by something which
traditionally tends to be forgiving of syntax errors and has the ability to
turn your file system into so much garbage", it sounds a tad less
appealing.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.python


csiph-web