Further Reading edit
- Xonsh, a Python-ish, Bash-compatible shell language and command prompt (xonsh.org), Hacker News, 2015-03-16
- A conversation about interactive shells. Useful reading for those interested in designing an interactive Tcl shell.
Description edit
tclsh/wish was not designed as an interactive login shell. The short-comings below are not intended as a criticism of tcl as a language, per se. Instead, what is hoped to evolve here are a series of user interface issues one might consider addressing in a sibling interpreter intended to be an interactive login shell with Tcl as the programming language, rather than with the various existing shell languages.A common complaint from users is that tclsh has no input history, and they typically request that someone add a readline or other interface to the shell.The typical comp.lang.tcl response is to suggest the user use tkcon.However, use of tclsh/wish or even tkcon as a login shell is likely to have more issues than command history.LV, for instance, finds that his daily use of ksh/sh involves a lot of piping output chains of 2, 3, sometimes a dozen commands, with shell constructs as well. Trying to convert these into an easy to use notation in tcl has been a daunting task to date.Lars H: It could be argued that this is because Tcl mostly employs an algebraic style - f(g(x,y),h(z,w)) - of operation composition using [command substitution]. Unix shells support this too, via backquotes, but rather poorly. Instead they are very good at forming pipes, which is more a (function composition) way of working - more akin to the native mode of operation in forth or perhaps APL than Tcl or C - although the shell pipes are even coalgebraic.What other issues exist? For instance, does tclsh and family support suspending commands and placing them into the background?Many times people use exec expecting the syntax to be the same as either a Bourne / C shell, or some other favorite invocation interface, or at the very least the same as typing commands at an interactive tcl console prompt.They discover quickly they are wrong.First difference - a concept often referred to as wild cards. Tcl does not automatically expand wild cards. So where as in shell you might type
set a [exec ls *.txt]in Tcl, you would type
eval exec ls [glob *.txt](LV says "Yes, very ugly. One of several things about Tcl that prevents me from considering tclsh as a usable interactive shell environment." Arjen Markus: see below)
(SS: note about the above example involving ls, what would it take to allow something like:
set a [ls *.txt]that is: for tclsh to search for commands in PATH not only in interactive mode, but at any level, if there isn't a TCL command with that name.)
Arjen Markus proposed the following solution:
- Adjust unknown to translate well-known commands like ls that will typically take such patterns as *.txt so that the correct shell invocation is used
- For instance: "ls *.txt" translates into "exec sh -c {ls *.txt}"
With regards to piping :Arjen Markus Well, some experimentation:In tclsh/wish on UNIX:
- "ls |more" causes execution of "ls" with a file "|more"
- "ls | more" causes execution of "ls" and produces one page only
- "ls -l | more" ditto, but it failed with a pipe error (no readers)
- "vi aa" did work without a fuss
- "ls" is a Tcl command, so I did not inspect this
- "vi aa" caused the script to hang
- Programs that require no interaction work splendidly, as long as wild cards are taken care of, either via the UNIX shell, or by the programs themselves (under Windows).
- Programs that simply read a line of input, your basic C or Fortran program reading from stdin, will work when you use the open command to set up the communication properly.
- Programs that require access to the keyboard, like "more", will require more sophisticated tricks, I would suggest using expect's capabilities.
- Programs like vi will require a terminal of their own and will never work from a command window.
ls *.txt --> exec /usr/bin/sh -c {ls *.txt} set myfile "todo_today.txt" vi $myfile --> exec xterm -e vi todo_today.txtand so on.This will require a lot of work though and is it worth it? You could distinguish categories of commands (and programs), so not every command would need its own Tcl interfacing.Perhaps a general proc, called | for syntactical sugar, can take care of the pipe mechanism (exec and open are the basic commands that will play a role in it). Another one is incrfilter, as LV suggested on the Tcl chat.LV Actually, incrfilter is just a prototype for a replacement of more. It provides the ability to display subsets of data based on constant strings. I didn't mean for incrfilter to cross over into this discussion - just was mentioning to arjen a toy to play with instead of using more.I think the above shows me that there is a LOT of work that is needed before someone could comfortably replace use of ksh/sh/bash/etc. with a tcl based shell.Note however that dtksh has the ability to invoke Tcl functions. A hybrid solution is easiest.
Arjen Markus Some of the limitations of exec with respect to handling pipelines may have been solved by RS - see his page on Streams - RS disclaims: That page offers nice sugar which looks like OS pipes, but in fact are only nesting relations between procedures (cat, grep and more were just few-liner Tcl substitutes..)
SS: some random point about this subject:I don't think that to use directly tclsh as login shell is worth the effort; I like the idea to exploit the fact that TCL is AFAIK the only language available that can be used to create a shell that mimics the model of the unix shell we have today, but with a real language built-in. My point is, most people don't like the shell as programming language, but most like the basic functionalities it provides, and especially how this functionalities are provided:
- the syntax for commands is just <command> <arg1> <arg2> and so on; there is no shorter notation than this.
- commands can be used in pipe in a simple way; that is: |
- it supports file redirection in a simple way; that is: > < and so on
- shell globbing features
ls | lessand type very little :), so in the command line, | can be considered as syntactical sugar that expands to something more complex in TCL to get the functionality of pipe. The same is true for > and <. Of course the prompt will not be 100% TCL compatible, but there is something to pay to integrate a language with a human interface in such a direct way.Shell globbing seems like to be more tricky, a solution can be to just handle it like the shell does... breaking more with TCL.BTW, at the end your command line is quite TCLish if you write TCL, but at the same time you can use it almost like an old shell. Probably some kind of quoting should allow to pass TCL code where |, >, * and so on have no special meanings, so to get 100% TCL one can start a line with a ' character (just an example), and what follows is taken as it is.Probably it is much more simple to get all this starting from BASH, putting TCL inside, then starting from tclsh. Using a good shell as starting point it is possible to reuse all the job controls code, history, completion, ... As usually the problem is to find the spare time to try it.
Take a look at tksh, where some work was done linking tcl and ksh. Alas, the author has ceased work on the effort - it had some nice potential.
From the chatroom:GPS Tcl shell:
- add signal handling to prevent Ctrl-c from closing the shell (TclX or custom extension)
- implement a frontend to open | for piping/plumbing (investigate Plan9's plumbing system)
- write procs for controlling the terminal
- write procs for processing input and/or dealing with readline
- implement a read-eval-print loop that handles errors properly with catch
- job control
CGM See gush for an attempt to build a usable Unix shell / "dumb" terminal on top of Tcl.
ZB And I'm wondering, could it be possible to have such shell equipped with screen-oriented editor, instead of usual command line. I think that everyone, who had Commodore 64 (or similar 8-bit machine) knows, what I mean: a quarter of century ago shells were more comfortable, than these of today.
ZB 2010-01-03 Recently discovered, that Fish shell is a little bit "ticklish"; for example, to have a file containing a list of files in current (sub)dir, one should type in its scripting language: for i in (ls -S); echo $i; endIt's even aware about events:
function event_test --on-event test_event echo event test!!! end emit test_eventIts homepage: http://fishshell.org/
slebetman: Check out Pure-tcl readline and Pure-tcl readline2 for a really nice and usable tcl shell, at least on Unix-like systems with VT100 compatible terminals.ZB If I properly understood, it's about shell's usability as day-to-day login shell - not just about the interaction with user. IMHO tclsh isn't too great as login shell, being rather programming environment - while Fish (bash, zsh, ksh etc.) is exactly the opposite. BTW: I was using readline quite a few months, but it had some issues, which rlwrap is free of.slebetman: That's what I mean. On my web server I use the pure-tcl readline script as my login shell (note:not the second version but my original version since I prefer history handling my way and other shells like bash, zsh etc don't handle history the way I like). Also, what issues did it have? Bug reports are welcome.ZB If I only can recall today... I can remember, that it was problem caused by the fact, that readline is "pure-TCL" solution (didn't make any notes, unfortunately, not being aware, that readline is actively maintained). But I was in a need for "history" in tclsh - it wasn't login shell, which I was looking for. It was over half a year ago, and I'm using rlwrap for adding "history"-ability to tclsh since, with no problems at all.ZB Wait, I was wrong! Just realized, that I had problems with tclreadline - not with your solution. The name is so similar...