It seems as though Ben has a good approach (in the separate thread). But to follow up on questions from others, let me be a bit more detailed about the problem setting:
We deploy python based web-sites and web applications (Django, Twisted or -- shudder --Plone) to various *nix servers. Could be Linux. Could be some BSD. Maybe even something else. We usually have the ability to install general stuff on these boxes, even if we don't have full root privileges, but sometimes we are limited to a sampling. I can count on Python because it has to be there for the deployed product (or we wouldn't be deploying there). I can almost certainly count on bash, sh for sure. The deployed code is a checkout from a revision control system (usually mercurial, in the past subversion, now we're seeing a requirement to use git, with a github repository), so I can count on the VCS tool suite. And I can count on being able to ssh into the box, though I can't be assured of being able to tweak the sshd configuration. Several developers, including some potentially non-programmer developers, work on these products. While I generally try to edit on my personal machine, commit and push to the central repository, then pull from it onto the deployment server in an ssh session, I sometimes, and other even more frequently, do editing on the deployment server, and need to commit and push from there. We generally want the commits credited to the correct developer for all the obvious reasons. But we typically only get one account on these boxes, so even if several of us are connected, it is always as the same user. We can certainly have scripts to run or source that arrange for the VCS credentials to be set, with the problem of having to remember to run them. Thus I typically adjust ~/.bash_profile to (source a file to) define a shell function and to invoke the function. The function prompts the user to enter a number, choosing from a displayed menu, indicating who he is, which, for mercurial, is used to set a single environment variable, HGUSER, which mercurial uses to identify the committer. Thus the problem of remembering to set your credentials is gone. Not having a lot of shell-fu, it took me a long time to get that script right. Now I want to do something similar for a site where we must use git. While one could use the approach of modifying the .git/config file (either the user's or the repository clone's), and git even provides a tool to do this, that leads, when several developers are ssh'ed in, to a case of last to connect wins. Git is also willing to listen to environment variables (if you haven't done the other stuff), so that seems the better choice (though folks should still coordinate what they're committing when, do they don't do overlapping "git add" commands before one of them commits). But I have to provide two different values, for four different environment variables to get the job done. I was thinking about how to pack two values into one table (displayed in the menu), and doing the splitting of stuff in bash, when I said to myself "why should I struggle with this in bash when python is there?". Except, of course, the environment variables need to be set in the login shell, the shell sourcing ~/.bash_profile, if subsequent invocations of git over the terminal are going to see them. I can't count on any X client tools being installed on the deployment server, and anyway I can't count on the developers to invoke ssh with -X or -Y (it's hard enough to get them to use ssh-add before connecting). I can't even count on an X server at the developer end. So there is no magically available other means of displaying a UI. Thus the approach of printing a selection list and accepting a number from stdin seems the most bullet proof. I'll be looking harder at Ben's work, but what I've been thinking about most recently is as follows. 1. During the time I care about (logging in) it's pretty certain that both fd 1 and fd 2 are open for writing on /dev/tty (or whatever the OS calls the generic for the session's controlling terminal) and fd 0 is open for input on same. 2. When the shell runs a sub command, it opens any files specified by simple redirections and creates any pipes needed for chaining the commands of a pipe (all of which appear on fds between 3 and 10, which is probably why the {NAME}> syntax specifies an fd above 10) - including that used for capturing output with back tick or $() notation, and then it forks. 2a. The child process, if there was any redirection, does suitable dup2 operations to place the files open on some of those 3 to 10 fds onto fd 0, 1, and/or 2, then closes the fds they came from, and also the other end of any pipes, so, normally, only 0, 1, and 2 are open, then execs the sub command, which inherits the child shell's fds. 2b. The parent shell closes the fds for the files used in redirection and the child's ends of the pipes. If a pipeline is being built the output end of one of those pipes will be used for execing the next subcommand instead of opening a new pipe for the next subcommand's stdin. In the case of back ticked or $()ed commands (pipelines?) the (final) output pipe is kept, and the shell reads from it until the command exits and the pipe is empty. 3. Redirecting stdout does not redirect stderr, including stderr from a command in back ticks or $() leaves stderr connected to the tty. 4. Therefore, if my python script gets invoked in back ticks or $(), I should be able to count on: 4a. stdin (fd 0) and stderr (fd 2) have the tty open for reading and writing respectively. 4b. stdout (fd 1) will be the input end of a pip back to the parent shell. Thus I can either be sure to send all UI output to fd 2 (be careful not to redirect it to a log or something in the shell), or I can dup2 to make a copy of fd1 on, say, fd3 (for my pipe back to the parent shell) and then dup2 to make a copy of fd2 on fd1, so stdout of the child python is now the tty (and I can use, say, python-dialog, without worrying about finding all the places in which it might assume that it should talk to the user on stdout). Probably that last set of redirections could be done inside the back ticks. _______________________________________________ gnhlug-discuss mailing list gnhlug-discuss@mail.gnhlug.org http://mail.gnhlug.org/mailman/listinfo/gnhlug-discuss/