views:

828

answers:

5

What are the differences between shell languages like bash, zsh, fish and the scripting languages above that makes them more suitable for the shell?

When using the command line the shell languages seem to be much easier. It feels for me much smoother to use bash for example than to use the shell profile in ipython, despite reports to the contrary. I think most wil agree with me that a large portion of medium to large scale programming is easier in Python than in bash. I use Python as the language I am most familiar with, the same goes for Perl and Ruby.

I have tried to articulate the reason but am unable to, aside from assuming that the treatment of strings differently in both has something to do with it.

The reason of this question is that I am hoping to develop a language usable in both. If you know of such a language, please post it as well.

Edit: As S.Lott explains, the question needs some clarification. I am asking about the features of the shell language versus that of scripting languages. So the comparison is not about the characteristics of various interactive (REPL) environments such as history and command line substitution. An alternative expression for the question would be:

Can a programming language that is suitable for design of complex systems be at the same time able to express useful one-liners that can access the file system or control jobs? Can a programming language usefully scale up as well as scale down?

+2  A: 

I think it's a question of parsing. Shell languages assumes by default $ command means you mean a command to run, Python/Ruby need you to do system("command") or what not. It's not that they're unsuitable, just that nobody has really done it yet, at least I think so. Rush http://rush.heroku.com/ is an example attempt in Ruby, Python has "iPython" or something like that.

rogerdpack
Thanks for the link. I have used ipython, and my first impression is that Rush looks a bit better, probably because of the fluent interface. I need to look at it a bit more.
Muhammad Alkarouri
+5  A: 

A shell language has to be easy to use. You want to type one-time throw away commands, not small programs. I.e. you want to type

ls -laR /usr

not

shell.ls("/usr", long=True, all=True, recursive=True)

This (also) means shell languages don't really care if an argument is an option, a string, a number or something else.

Also, programming constructs in shells are an add-on, and not even always build-in. I.e. consider the combination of if and [ in (ba)sh, seq for generating sequences, and so on.

Finally, shells have specific needs that you need less, or differently in programming. I.e. pipes, file redirection, process/job control, and so on.

Ivo van der Wijk
Thanks for the answer, but these differences do not seem to me to be intrinsic to the language. It is very easy to design a library so in Python you say `shell.ls('usr', flags='laR')`. Even the `shell` bit and the `flags=` bit can be removed. I agree that things like redirection and process control are optimised in shells because of their relevance there.
Muhammad Alkarouri
+6  A: 

If you know of such a language, please post it as well.

Tcl is one such language. Mainly because it is designed to primarily be a shell interpreter for CAD programs. Here's one hardcore Python programmer's* experience of realising why tcl was designed the way it was: http://www.yosefk.com/blog/i-cant-believe-im-praising-tcl.html

For me, I've written and have been using and improved tcl shell (written in tcl of course) as my main Linux login shell on my homebrew router: Pure tcl readline

Some of the reasons I like tcl in general has everything to do with the similarity of it's syntax to traditional shells:

  1. At its most basic, tcl syntax is command argument argument.... There's nothing else. This is the same as bash, csh or even DOS shell.

  2. A bareword is considered a string. This is again similar to traditional shells allowing you to write: open myfile.txt w+ instead of open "myfile.txt" "w+".

  3. Because of the foundations of 1 and 2 tcl ends up with very little extraneous syntax. You write code with less punctuation: puts Hello instead of printf("Hello");. When writing programs you don't feel the hurt so much because you spend a lot of time thinking about what to write. When you use a shell to copy a file you don't think you just type and having to type ( and " and , and ) and ; again and again gets annoying very quickly.

*Note: not me, I'm a hardcore tcl programmer

slebetman
Very good! I forgot all about Tcl. I had a short introduction to it a long while ago, and I simply forgot that it was a perfectly good shell interface for some Cisco routers that I used a long time now. It looks like Tcl is the nearest to the sweet spot between them. I will switch to tclsh for a couple of days to see how it goes.
Muhammad Alkarouri
Now the slightly unflattering bit. Tcl is not as successful as other languages, can you say why? I remember not being happy with the `math` command, and probably OOP, but that was a long time ago.
Muhammad Alkarouri
For the first bit, I'd like to point out that tclsh is a really-really basic shell: no up-down-arrow history, no tab completion etc.. I would recommend you at least use `rlwrap tclsh` to wrap it in readline. Or even better, use my code linked above as your shell. For the second bit, I think it's because most programmers are uncomfortable with anything that doesn't look like C. Fun fact, Netscape originally implemented Tcl as the browser scripting language but management wanted something that looks like Java syntax (which is, again another C-like syntax).
slebetman
I did look at your code after I posted my comment, and I am going to use that. Speaking about insufficiently C-like languages, you have probably come across [this](http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html) before.
Muhammad Alkarouri
+5  A: 

Who says they aren't? Take a look at Zoidberg. REPLs (Read Eval Print Loops) make crappy shells because every command must be syntactically correct, and running a program goes from being:

foo arg1 arg2 arg3

to

system "foo", "arg1", "arg2", "arg3"

And don't even get me started on trying to do redirection.

So, you need a custom shell (rather than a REPL) that understands commands and redirection and the language you want to use to bind commands together. I think zoid (the Zoidberg shell) does a pretty good job of it.

Chas. Owens
Going to give zoid a try. Do you know, is there any amount of a base of people using as their primary shell?
Joel
@Joel I doubt it. It was last updated on CPAN in 2006. It is hard to beat `bash`. It is ubiquitous, feature complete, and maintained. Shells like `zoid` are fun to play with, but I always return to `bash` or `ksh`.
Chas. Owens
Yeah, I also saw that it hasn't been maintained. I wonder what kind of brushing up it might need, I would be interested using a shell with that kind of power.
Joel
+12  A: 
Jörg W Mittag
A very good answer to both sections of the question. About points 2 and 4: Is that because of static typing as such, or is it because of a casting operation? In most non-shell languages (static or dynamic) that I know of, `123` cannot define two different types. Also do you have a link explaining Powershell's Adaptive Type System? Google doesn't seem to throw at me anything I could understand.
Muhammad Alkarouri