On Wed, Apr 25, 2012 at 02:54:07PM -0400, Chet Ramey wrote: > On 4/25/12 2:04 PM, Greg Wooledge wrote: > > > Maybe it only works on boxes with a very large "open files" resource > > limit. Perhaps the hard-coded 255 should be replaced with something > > involving getrlimit() or similar? > > I see two potential fixes here. First, try changing the 255 to -1 and > see what happens.
That broke something pretty badly. cyclops:/var/tmp/bash/bash-4.2$ cat ~/foo #!/bin/bash shopt -s lastpipe echo hi | read foo echo "<$foo>" cyclops:/var/tmp/bash/bash-4.2$ ./bash ~/foo cyclops:/var/tmp/bash/bash-4.2$ ./bash -c 'shopt -s lastpipe; echo hi | read foo; echo "<$foo>"' <hi> So it seems to work with -c but not when reading from a file. I'm guessing the file descriptor move somehow made bash lose track of the file it was reading commands from. The move_to_high_fd part looks happier: Breakpoint 2, move_to_high_fd (fd=0, check_new=0, maxfd=-1) at general.c:444 444 if (maxfd < 20) (gdb) n 446 nfds = getdtablesize (); (gdb) n 447 if (nfds <= 0) (gdb) n 449 if (nfds > HIGH_FD_MAX) (gdb) n 455 for (nfds--; check_new && nfds > 3; nfds--) (gdb) n 459 if (nfds > 3 && fd != nfds && (script_fd = dup2 (fd, nfds)) != -1) (gdb) n 461 if (check_new == 0 || fd != fileno (stderr)) /* don't close stderr */ (gdb) n 462 close (fd); (gdb) n 463 return (script_fd); (gdb) print script_fd $1 = 127 (gdb) n 469 } (gdb) n But after that I have no idea what's happening (or failing to happen): execute_pipeline (command=0x209d2c260, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x202b8ca10) at execute_cmd.c:2209 2209 if (lstdin > 0) (gdb) n 2211 do_piping (prev, pipe_out); (gdb) n 2212 prev = NO_PIPE; (gdb) n 2213 add_unwind_protect (restore_stdin, lstdin); (gdb) n 2214 lastpipe_flag = 1; (gdb) n 2215 freeze_jobs_list (); (gdb) n 2216 lastpipe_jid = stop_pipeline (0, (COMMAND *)NULL); /* XXX */ (gdb) n 2217 add_unwind_protect (lastpipe_cleanup, lastpipe_jid); f (cmd) (gdb) n 2220 cmd->flags |= CMD_LASTPIPE; (gdb) n 2222 if (prev >= 0) (gdb) n 2226 exec_result = execute_command_internal (cmd, asynchronous, prev, pipe_out, fds_to_close); (gdb) n 2229 if (lstdin > 0) (gdb) n 2230 restore_stdin (lstdin); (gdb) n 2233 if (prev >= 0) (gdb) n 2237 UNBLOCK_CHILD (oset); (gdb) n 2240 QUIT; (gdb) n 2242 if (lastpipe_flag) (gdb) n 2245 append_process (savestring (the_printed_command), dollar_dollar_pid, exec_result, lastpipe_jid); (gdb) n 2247 lstdin = wait_for (lastpid); (gdb) n 2249 exec_result = job_exit_status (lastpipe_jid); (gdb) n 2251 unfreeze_jobs_list (); (gdb) n 2254 discard_unwind_frame ("lastpipe-exec"); (gdb) n 2256 return (exec_result); (gdb) n 2257 } (gdb) n execute_connection (command=0x209d2c260, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x202b8ca10) at execute_cmd.c:2338 2338 if (was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS) (gdb) cont Continuing. Program exited normally. (gdb)