[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: [ in /usr/bin Question



Douglas Allan Tutty wrote:
On Wed, May 09, 2007 at 05:08:33PM -0700, Bob McGowan wrote:
Douglas Allan Tutty wrote:
No wonder I can never figure out what a shell script is trying to do,
either way it looks like a cat on a keyboard.  Give me python and
fortran77 any day.

As I don't use python, I have no direct experience here. I do use Perl, however. It is also 'easier' than the shell, assuming you put the script in a file.

So, a question: Can python 'run' code directly from the command line, as Perl does with the -e option?

   perl -e 'while(<>){print}'

Yes, to some extent.  Python uses the indentation of the program to
indicate flow.  Therefore, if your command is just a string of commands
to run, it works.  However, if it involves looping or decision it won't
since python (by design I think) will not do the perlish and bashish
one-liners.

So:
	python -c "a=5; print a; b=10/5; print b; print a * b"

works.

OK, python has a switch that lets you do this. So, since shell quoting can also be used to escape newlines, you can do:

python -c "a=5
print a
b=10/5
print b
print a * b"

Which means that you could also, if you *really* wanted/needed to, write a short (several lines) script with proper indentation, looping, etc.

Or, as Ron Johnson suggested, use a 'pseudo file' (in UNIX shell language, these are called 'here documents, I suppose because the standard input is redirected from 'here'). But even with them, care is needed to prevent (or allow) shell interpretation of the contents.

In any case, though interactive processing is possible, putting the code in a file is much more useful, even for so called 'throw away' one liners, which I've often found I needed to use again and end up having to re-write.


for example. If so, you'd have the same quoting issues you have with a shell script, since you would need to protect the python part of the input from shell interpretation.


Yes, understandable, but since such use is literally throw-away code,
there is no future maintenance to consider.

On the other hand, there's no reason to submit to the limits of a
one-liner when you can just as easily type:

	python

This is also true for Tcl/Tk and can be done with Perl, using the right options (though in Perl, multi-line input is harder).


and enter the python shell where you can do anything you want in python,
indents, import modules, whatever.  If you really want, you can operate
the whole system from within the python shell as you would the bash
shell.  To make that easier, issue
	from os import *
	from os.path import *

So that, to run a program, you issue a system call:
	system('lynx')

But, these are intended for prototyping and testing code. They're not generally considered 'command interpreters'. This is what the shell is for, with the intent of making interactive use and command execution easy (no 'system' call, no parens, no quotes, just type the command name and go).

That the shells became programming languages too only means there was a need that could be handled that way.

The other scripting languages followed, as the need (and power requirements, as in speed, control structures, and so on) for them increased.


The joy of python is that absolutly nothing is cryptic unless you
want it to be.


I understand that some languages tend toward being cryptic. But some (most of, I think) of that crypticness is due to programmers trying to be 'cute' or showing off or ... (as you said: "...unless you want it to be.")

I am a firm believer in commenting code, and in being as 'obvious' as possible in the code itself. Some might call it compulsive but it's sure saved me a lot of heartache, not to mention sweat, blood, tears and time.

This is true, regardless of the language used.

Since the shell is both a command interpreter (runs other applications) and a programming language, it gets very complicated when it is working with another program that also uses wild cards or regex or simply general programming language constructs like parens or braces.

I think that the only such program I use is ls.  I don't do sed, awk,
etc, for the same reason I don't program in bash or perl.  Its too
cryptic.  There is no doubt that regex is very powerful but I just can't
remember it long enough for any code that contains it to be meaningful
and therefore maintainable.

I'm not sure what you mean by '...the only such program I use is ls.'? The 'ls' does no regex or wild card processing, anything of this type is interpreted by the shell, first. For example, assuming no file name ending in 'x' is in the current directory:

ls *x
ls: *x: No such file or directory

This assumes you're using a Bourne compatible shell. C shell error is from the shell (ls never gets run, even though the shell prints the name as part of the message):

ls *x
ls: No match.


On the other hand, in my __Python_2.1_Bible__ is an example: rgrep.py
that implements the full rgrep utility in 22 lines of python code (plus
comments and doc strings).  That code itself is clear and easy to
follow.  The user of the program can use regrex if appopriate.

Putting things in a file makes things even easier, assuming the program in question will read files (as Perl, python, awk, C, Fortran, Pascal ..., do). Unfortunately, this doesn't help a lot with the shell, the same problems exist in the shell script file as exist on the command line.


The only thing that sh has going for it as a scripting language (other
than its ubiquitousness) is that it is smaller than python.  That was
and is a good thing in some situations.  However, the difference isn't
that great.  /bin/bash is 770k vs python's 1.2m.  Python brings in the
pthread library, in addition to those brought in by bash, but that is
once for as many instances as you like.  If I were wanting to create my
own NIX distribution, I'd have sh available for compatibility, but all
system scripts would be done in python.

But bash/sh is not the shell used during system initialization. The initrd image file for current kernels has 'dash' (I believe 'ash' used to be used?). In any case, dash is 84008 bytes, significantly smaller. For system booting, size can be a significant issue. And having only one program for both possible interactive use (if the initrd sequence detects hard errors of some sort) and for scripting also keeps the size down as only one file needs to be present.


The other nice thing about python is that it is great for prototyping.
My python code looks very similar to Fortran since for reminders I list
(in comments) all the variables I use, its a simple matter to turn them
into declarations.  Then its just undoing the indentation, changing
comments, and final touchups.

I have no experience in this sort of conversion, as my Perl code is fast enough to do what needs doing without converting to a compiled language. It's easier to fix problems for interpreted languages, generally, than for compiled one.

I suppose the same is true for python (Tcl/Tk as well), which is why so many utilities are kept as scripts rather than converted.


Doug.


Attachment: smime.p7s
Description: S/MIME Cryptographic Signature


Reply to: