Bill Freeman <ke1g...@gmail.com> writes:
>
> I'm not following.  Perhaps I just don't understand process
> substitution.  Just in case I'm being misheard, let me try again.

Yeah, I think I didn't understand exactly what you wanted to do.

So..., what you want is for the parent shell to end up just making
a call to pipe() to allocate a pair of FDs, and giving you the FDs
so that one of them can pass through the fork() to the child process?

Because you can't have the child pass one up to the parent..., and...,
you're right--you can't use the shell redirection-operators
to specifiy which FDs will be used in the child process
(both of the sides (parameters) of the redirection-operators are
 already dedicated to specifing FDs in the parent's space...).

I'm not sure how you can do that with just bash. I mean,
there's a reason they're called the "*standard* input"
and "*standard* output" descriptors, right? Though...:

You could use socat (which is a pretty fantastic tool, in case
anyone hasn't heard of it!), but then I think you'd have to
have socat exec your shell.

You could just have bash open /dev/ptmx, but then I have no idea
how to find the corresponding /dev/pts/ node in either bash or Python--
only in C.

If your subordinate script is going to be interacting with the user
via the controlling TTY, you can dig out the path to *that*
using the "tty" command--then pass the tty path explicitly
to this child script as an argument, so that you can safely
just use the stdio descriptors for their standard purposes.

e.g., if your environment-generating script is named "genenv",
you could call it like so:

    eval $(genenv $(tty))

Or, actually..., you could just have the child script
operate on /dev/tty. That's probably what you want:

    TTY(4)      Linux Programmer's Manual     TTY(4)

    NAME
           tty - controlling terminal

    DESCRIPTION
           The  file  /dev/tty  is  a character file
           with major number 5 and minor  number  0,
           usually  of  mode  0666  and  owner.group
           root.tty.  It is a synonym for  the  con‐
           trolling terminal of a process, if any.


> There are two processes:
>
> 1. The parent, a login shell, I'll stipulate bash, running stuff I add
> to .bash_profile
> or possible source from there.  The desired end result is that *THIS* process
> export some environment variables (GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL,
> GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL), but that it set them to values that it got
> from the other process (because I don't want to learn to do the string
> processing in
> bash that it would require to come up with the values in this process itself).
>
> 2. A child process, written in the language of my choice (Python),
> which interacts
> with the user who is logging in, and thus needs for the shell to NOT
> redirect fds 0,
> 1, and 2, that is, they must still be connected to the tty.  Therefore
> the parent process
> needs somewhere else from which it can read the result.
>
> I know how to do this with a temporary file (thereby becoming
> dependent on having
> mktemp or tempfile and write permission in the directories they return), and 
> the
> shell will even help ( clientprog 3> $MYTEMPFILE ), though at this
> point, the client
> may as well open and write the temporary file.
>
> But *nix has these wonderful things called pipes.  In fact, if I run a
> command inside
> back ticks, or the equivalent modern syntax, it creates one, with the
> forked shell
> dup2'ing the input end of the pipe onto fd1  before exec'ing the desired 
> target
> child program, with the original shell process waiting to read from
> the output end
> of the pipe.  I just want the forked shell to dup2 the input of the
> pipe to fd 3 (if it
> isn't already there, in which case I need it not to close fd3) and
> leave fd 1 alone.
>
> Perhaps I'll just have to count on fd 2 being the tty, and do UI on
> that (I could do
> some dup2'ing of my own in the child so that its code would look more normal).
>
> Bill
>
> On Tue, Jun 19, 2012 at 5:07 PM, Joshua Judson Rosen
> <roz...@geekspace.com> wrote:
> > Two thoughts:
> >
> >    * Use Bash's `process substitution' syntax: "<(...)" and/or ">(...)"
> >      to pass the auxiliary process' stdin and/or stdout fd as an argument.
> >      If you don't want to have two script-files rather than one, then
> >      you may have to do something like...:
> >
> >          bash -c 'while read pipe_in < $1
> >                   do
> >                       read -p "input for $pipe_in: " user_in
> >                       echo $pipe_in:$user_in
> >                   done' -- <(ls)
> >
> >      (there may be a prettier way of doing that--not sure what it'd be,
> >       of the top of my head)
> >
> >    * Do something with djb's `multitee' command.
> >
> > Bill Freeman <ke1g...@gmail.com> writes:
> >>
> >> I really hate string processing in bash.  So I'd like to write a
> >> script in another language that 1. interacts with the user; 2.
> >> calculates the desired values of some environment variables; and 3.
> >> communicates those settings to the shell from which it was invoked
> >> (since the environment variables are for other programs to be started
> >> by that shell in the future).
> >>
> >> I can't just use back-tick and print the information because I need
> >> standard out so that I can print a menu and other prompts to the user.
> >>  (I suppose that I could use stderr to talk to the user, but that
> >> feels nasty.)
> >>
> >> What occurred to me is to send the final result to fd 3, which the
> >> shell would have to have opened before forking.  So, this works:
> >>
> >>     $ script 3> some_file_name
> >>     $ source some_file_name    # assume the output is an "export" command 
> >> line
> >>     $ rm some_file_name
> >>
> >> This does have to be gussied up to use mktemp or tempfile, since it
> >> could be being invoked on the same account simultaneously from other
> >> terminals (the whole reason for wanting to use environment variables,
> >> rather than "git config user.name" in the first place).
> >>
> >> But I'd really like to get away from the separate file altogether and
> >> get bash(sh) to build a pipe (unnamed)  to the child process's fd 3,
> >> and either exec that (when it comes) or stuff it in a shell variable
> >> (which I can then exec), all without redirecting stdin, stdout, or
> >> stderr for the child.  (I got excited about the -u option to read, but
> >> that's referring to the shell's fd 3, not the child's.)
> >>
> >> Any thoughts?
> >>
> >> Bill

_______________________________________________
gnhlug-discuss mailing list
gnhlug-discuss@mail.gnhlug.org
http://mail.gnhlug.org/mailman/listinfo/gnhlug-discuss/

Reply via email to