Op Wed, 25 Jan 2006 07:41:45 -0700 schreef Eric Blake in <43D78E29.4060504<at>byu.net>: : : According to Bas van Gompel on 1/24/2006 10:11 PM: [script]
: 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. So far so good... : 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. I (now) understand what's happening. I think it's undesirable, though. I think the shells should redirect the input for the executed programs, /not/ for itself. (Could this be an exploitable vulnerability?) [...] : > In ash it prints '' : > First exec: Done. : > Second exec: Done. : > '', as I expected. Compare p.e. : Your expectation was wrong. Apparently. : > === 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." Right, my bad. Following shows the same (odd, IMO) behavior. === begin testexec2b.sh === #!/bin/bash exec 5<&0 echo 'echo "First exec: Done." exec 0<&5 echo "Second exec: Done." exit 0' |exec /bin/bash ==== end testexec2b.sh ==== I can work around this effect using -c, but thought it best to report anyway... L8r, Buzz. -- ) | | ---/ ---/ Yes, this | This message consists of true | I do not -- | | / / really is | and false bits entirely. | mail for ) | | / / a 72 by 4 +-------------------------------+ any1 but -- \--| /--- /--- .sigfile. | |perl -pe "s.u(z)\1.as." | me. 4^re -- 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/