User: Password:
|
|
Subscribe / Log in / New account

Shell programming

Shell programming

Posted Dec 8, 2012 19:05 UTC (Sat) by nix (subscriber, #2304)
In reply to: Shell programming by davidescott
Parent article: Quotes of the week

In most cases you're trying too hard. Rather than 'looking up' what xargs -L does, just do 'xargs --help' and it tells you (not that that is much harder than 'man xargs'. Rather than agonizing over what factor does, try 'factor 16' and 'factor 17' (one obvious prime, one obvious non-prime) and it is instantly obvious.


(Log in to post comments)

Shell programming

Posted Dec 8, 2012 19:09 UTC (Sat) by Cyberax (✭ supporter ✭, #52523) [Link]

>cyberax@cybmac:~$ factor 16
>bash: factor: команда не найдена [command not found]
Kinda fails.

Let's try "port search factor" - again it fails. There's no 'factor' utility in Mac OS X's ports.

On the other hand, Ruby version works perfectly even with the bundled Ruby interpreter.

And THAT is the problem with shells.

Shell programming

Posted Dec 8, 2012 20:01 UTC (Sat) by man_ls (guest, #15091) [Link]

I'd say that is a problem with the Mac OS X shell: it lacks the factor command.

Shell programming

Posted Dec 8, 2012 20:04 UTC (Sat) by Cyberax (✭ supporter ✭, #52523) [Link]

And Linux's shell lacks some SunOS's shell's tar options.

I've checked and it doesn't seem that the 'factor' command is mentioned anywhere in the POSIX spec.

Shell programming

Posted Dec 8, 2012 22:52 UTC (Sat) by man_ls (guest, #15091) [Link]

Neither does the POSIX spec mention ssh, rsync, wget, curl, less or a myriad of other commands in widespread use. Yet using them in scripts is easily forgiven; each command maintains excellent backwards compatibility on its own.

For your Mac OS X, I believe that brew install coreutils will get you a nice local copy of factor.

Shell programming

Posted Dec 8, 2012 23:26 UTC (Sat) by davidescott (guest, #58580) [Link]

What is this "less" you speak of? Maybe you are confused, the proper command is "more." Also what is this "ssh" do you mean "rsh?"

GNU has done an impressive job of unifying the *nix with a set of common tools, and the fact that someone can "brew install coreutils" and get a bunch of useful binaries is a testament to the value of the work GNU has done. BUT...

That does not mean that "shell" is the best language, it just means that shell is the least common denominator for interacting with a diverse set of programs (and it has served *nix well). Text input/output, flags for program options, silence is success, integer return codes, etc... As programs mature they get split into libraries, and those libraries get external interfaces to other languages like python/ruby/etc...

Shell programming

Posted Dec 8, 2012 23:10 UTC (Sat) by davidescott (guest, #58580) [Link]

I would go further and suggest that /usr/bin/factor is not something that should be in coreutils, and that OSX/BSD is far more sensible than GNU in excluding it. It just ends up polluting /usr/bin with functionality that would make more sense in a basic calculator like "bc" (which I curse out every time I start it because its so much easier to do basic arithmetic in python, ruby, R or octave).

If you look at what else is in coreutils factor seems completely out of place. There is not a single other tool in coreutils to do basic arithmetic. Where is there a /usr/bin/factor but not a /usr/bin/factorial, /usr/bin/exponent, /usr/bin/log or for that matter a /usr/bin/prime or /usr/bin/primes. In fact a good multi-function random tool (to generate random numbers or strings) would seem to be a far far far more useful thing to add to coreutils than "factor."

I'm really curious what considerations lead to "factor" being included into coreutils, is there an init script that really needs to factor a number before it can continue?

I don't mean this as a criticism of the developers of bc or coreutils or of GNU in general. Tools like "bc" were advanced and useful for their day. Thankful we have better alternatives for many use cases, and with 8 cores and 16GB of RAM I'm happy to waste a bit of each to get a more use friendly tool to do basic arithmetic and really don't need "bc" or "factor" anymore.

Shell programming

Posted Dec 9, 2012 17:39 UTC (Sun) by nix (subscriber, #2304) [Link]

I suspect only Roland McGrath can tell you why factor is in coreutils. It's been there since before it had an RCS repository (1992).

Shell programming

Posted Dec 8, 2012 22:44 UTC (Sat) by davidescott (guest, #58580) [Link]

> Rather than 'looking up' what xargs -L does, just do 'xargs --help' and it tells you (not that that is much harder than 'man xargs').

In what way is "xargs --help" not "looking it up"?

> Rather than agonizing over what factor does, try 'factor 16' and 'factor 17' (one obvious prime, one obvious non-prime) and it is instantly obvious.

Again I know what factor does (its in the name), what I don't know is that the output format is "INPUT: N1 N2 ... Nk". So I did exactly as you described (except I used 4 and 7).

There is nothing particularly complex about looking things up like this, and I had to look some things up for ruby as well (its been a few years since I have used it heavily). The key difference is that ruby has functions like "numeric.prime?" which (following standard naming convention) is a test if the numeric is prime, and has a standard obvious boolean return value.

The shell variant of this was a rather convoluted test if the output of "factor" was "N: N" which is a rather indirect way of testing if a number is prime. One could reasonably suspect that "factor" 7 would output "7: 1 7" or that factor 8 would output "2^3" or "2,2,2". There is no apriori reason to believe that factor should output the input number followed by the non-unit factors in increasing order (and separated by ":" and " ").

That is one of the advantages of a programming language. Real datatypes make it easier to guess what a function might return (factor() should return an array of prime factors [sorting and the unit are open questions]), and the subsequent manipulation of those objects is usually sufficient to say what kind of object was returned. If my test for primality of x was:
> (x.factor().length()==1)
Then it is clear that factor() returns an array of factors not including 1. In addition the standardized syntax makes it easier to guess what the functions might be.

Now at the expense of portability I could write a program /usr/bin/prime and simplify the shell script. I might even be able to write something like ruby's group_by in shell but it stretches the meaning of "shell" to say that such a script is "standard *nix shell."

Shell programming

Posted Dec 9, 2012 17:44 UTC (Sun) by nix (subscriber, #2304) [Link]

Hm. I hate to point it out, but your 'easy to read' Ruby one-liner was and remains utterly incomprehensible to me, full of thoroughly opaque punctuation, probably just as incomprehensible as the shell equivalent was to you: the presence of the occasional comprehensible word does not help much. The last time I saw that much nested foo().bar().baz().quux() was when building menus using Borland's Turbo Vision library. It is very much not intrinsically easier to follow than pipelines: at least with pipelines you know that what is being transported is text with a print syntax that you can easily examine, rather than some intricate datatype which you have to look up the various functions to figure out.

Your entire argument boils down to 'things that are familiar to me are intrinsically easier to read for everyone than things that are not familiar to me', which is not at all valid.

I'd agree that for larger programs, the shell is hardly ideal: datatyping is worthwhile -- but for quick one-liners to answer quick questions, it's exactly as valid as a bunch of other vaguely-scripty languages. Ruby is not magically better just because you know it better than the shell (and your claim that more people know Ruby than know the shell is unsupported, and to me sounds dubious in the extreme).

Shell programming

Posted Dec 9, 2012 19:01 UTC (Sun) by davidescott (guest, #58580) [Link]

> Ruby is not magically better just because you know it better than the shell

Never wrote that. In fact wrote something much the opposite of that

> (and your claim that more people know Ruby than know the shell is unsupported, and to me sounds dubious in the extreme).

Never wrote that.

> but for quick one-liners to answer quick questions

Not what this discussion was about.

> Your entire argument boils down to 'things that are familiar to me are intrinsically easier to read for everyone than things that are not familiar to me', which is not at all valid.

Your entire argument seems to be based on making up stuff and attributing it to others. There seems little reason to respond.

Shell programming

Posted Dec 9, 2012 23:20 UTC (Sun) by nix (subscriber, #2304) [Link]

No, it's based on not looking upthread to see who wrote what. Feel free to interpret 'you' as 'collective you' if you wish :)

Shell programming

Posted Dec 10, 2012 0:12 UTC (Mon) by Baylink (guest, #755) [Link]

> Your entire argument boils down to 'things that are familiar to me are intrinsically easier to read for everyone than things that are not familiar to me', which is not at all valid.

Exactly.

But the point you make immediately above, which was essentially: debugging is easier because you can merely lop off the end of the pipeline and *look at the data on the terminal*, is the really important one to me.

The best language for anything is very often *the one your programmer understands best*, as that is the one in which s/he'll be most efffective.

Shell programming

Posted Dec 18, 2012 12:25 UTC (Tue) by wookey (subscriber, #5501) [Link]

I think this is the nub of it.

I write stuff in shell because I know how to. After many years I've learned how to deal with many of the horrible things that go wrong, and with a couple of hours of dicking about can usually get what I wanted.

As with others if I know there will be a lot of data manipulation then I'll use perl instead, and know just enough to do that. I avoid writing in python because I don't know how, and worse don't know how to fill in the gaps.

If I'd started writing python 20 years ago things might be different (and I might be more productive - I like shell but I'm not going to claim that it's a _nice_ language)

Shell programming

Posted Dec 10, 2012 0:47 UTC (Mon) by dlang (subscriber, #313) [Link]

the pipe based approach has the wonderful property that it's trivial to truncate the 'program' at any point and see the output at that stage (with normal tools like head/less/wc/etc)

In fact, I normally build up the monster pipe shell programs iteratively this way, one chunk at a time.

Shell programming

Posted Dec 10, 2012 2:17 UTC (Mon) by davidescott (guest, #58580) [Link]

> it's trivial to truncate the 'program' at any point and see the output at that stage

So will interactive ruby (or python for that matter).

> In fact, I normally build up the monster pipe shell programs iteratively this way, one chunk at a time.

Same way I write long ruby chains.

The only difference is that Ruby passes objects and shell passes text.


Copyright © 2018, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds