On Sun, Nov 03, 2019 at 08:17:30AM -0500, Theodore Y. Ts'o wrote: > On Sun, Nov 03, 2019 at 05:07:22AM +0100, gregor herrmann wrote: > > > > Cron sends me the following mail once per week: > > > > /sbin/e2scrub_all: line 173: /proc/8234/fd/pipe:[90083173]: No such file or > > directory > > Gregor, thanks for the bug report! This is coming from: > > stdin="$(realpath /dev/stdin)" > ... > ${DBG} "@root_sbindir@/e2scrub" ${scrub_args} "${tgt}" < "${stdin}" > > I'm not sure why this hack is there at all. Darrick, can you shed any > light? What was the original intent of redirecting stdin to the > realpath of /dev/stdin?
Because if you don't do that, the e2scrub process gets started with fd 0 mapped to stdout of ls_targets on account of the "ls_targets | while read tgt" loop. Yay bash. I guess the problem here is that e2scrub_all's stdin is itself a pipe, so /dev/stdin maps to /proc/self/fd/0, is a symlink to "pipe:[XXXX]" which doesn't help us any. We could amend the e2scrub_all script to do: stdin="$(realpath /dev/stdin)" test -w "${stdin}" || stdin=/dev/null So at least you won't get that complaint from the cron job... I don't know of a good way to work around the "ls_targets | while loop" idiom. for i in $(ls_targets); do ... done doesn't escape spaces at all, and if there are a lot of LVs on the system we can potentially exhaust bash's command line length maximum. I guess one could restructure the script so that "ls_targets" has the side effect of generating a bash array containing all eligible targets and then change the loop to "for tgt in "${targets[@]}"; do ... done". Pretty gross of a coding strategy but ... it's bash. --D > Thanks, > > - Ted