This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Shell (bash, (pd)ksh, zsh, /not/ ash) + exec + here-doc + redirect == trouble!


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Bas van Gompel on 1/24/2006 10:11 PM:
> Hi,
> 
> Try the following script:
> 
> === begin testexec.sh ===
> #!/bin/ksh
> 
> exec 5<&0 /bin/ksh <<EOSH
> echo "First exec: Done."
> exec 0<&5
> echo "Second exec: Done."
> exit 0
> EOSH
> ==== end testexec.sh ====

First line: This could be rewritten "exec /bin/ksh 5<&0 <<EOSH".  Either
way, you are replacing the current shell with an invocation of /bin/ksh,
and with fd 5 set to your current stdin, and then with fd 0 set to a pipe
supplied by the contents of the here-doc.

Now ksh gets through the following input on stdin:
echo "First exec: Done."
exec 0<&5

At which point, the second exec says take fd 5 and dup it into fd 0 (in
other words, restore your original stdin from before the first exec back
to ksh's stdin).  POSIX requires that ksh reads its input from stdin a
line at a time, so the very next line it reads will be whatever you type
(if the original stdin happened to be a terminal).  Only ash is buggy here
(no big surprise, ash is usually the least POSIX-compliant of the shells);
ksh, zsh, and bash are all doing what is required of them.

> 
> (Replace ksh with bash or zsh at will, above.)
> 
> For me, this prints ``First exec: Done.'', then leaves me to type
> shell-commands, _which are executed_, until I press EOF (^D).
> 
> In ash it prints ''
> 
>   First exec: Done.
>   Second exec: Done.
> 
> '', as I expected. Compare p.e.

Your expectation was wrong.

> 
> === begin testexec2.sh ===
> #!/bin/bash
> 
> echo 'echo "First exec: Done."
> exec 0<&5
> echo "Second exec: Done."
> exit 0' |exec 5<&0 /bin/bash
> 
> ==== end testexec2.sh ====

Here, you are doing something slightly different.  The last line is a
pipeline, which must be applied before redirections.  Which means that you
are exec'ing /bin/bash, with fd 0 set to the pipeline from the echo, then
fd 5 copied from fd 0.  When the second "exec 0<&5" is reached, you copy
fd 5 back to fd 0, but since it was the same fd, it was effectively a
no-op.  Therefore, /bin/bash continues to read the next line from fd 0,
and successfully prints "Second exec: Done."

> 
> , which also performs as expected.
> 
> Has anybody got a clue?
> 
> Is this cygwin-specific?

No.

> 
> Are all these shells borrowing code from eachother?

No.

- --
Life is short - so eat dessert first!

Eric Blake             ebb9@byu.net
volunteer cygwin bash maintainer
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFD144p84KuGfSFAYARAk9wAKCsfgwDH6yg/TVIqprI7mhpnfQxxgCgvpi+
JkYBe7wXat74LuBY6fedRvI=
=JX9+
-----END PGP SIGNATURE-----

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]