What does the following script mean?
exec 4<&0 0</etc/XX/cfg read line1 exec 0<&4
It redirects fd0 to fd4, and "/etc/XX/cfg" to fd0.
So why does
read still work, shouldn't that be empty?
It redirects stdin (FD0) to FD4, redirects from
/etc/XX/cfg to FD0, reads a line from FD0, and then moves FD4 back to FD0. In short, it saves, replaces, and restores stdin, while reading a line from a file in between.
read line1 < /etc/XX/cfg would be so much easier, but it's impossible to tell if it's a valid replacement based only on the code shown.
To recast this in syscalls (using C):
exec 4<&0 0</etc/XX/cfg
/* Duplicate fd0 as fd4. */ dup2 (0, 4); /* Open file on fd0. "open" always uses lowest available descriptor, so we don't need to check it. */ close (0); open ("/etc/XX/cfg", O_RDONLY);
/* Close fd0 and duplicate fd4 as fd0. */ dup2 (4, 0);
The way I read this - based on the bash manpage section on REDIRECTION - is that
stdin (fd0) is redirected into fd4, then input is taken from
stdin - which will end up on fd4.
read line1 should then take from fd4 which is then put back to fd0.
A demo might show my meaning a little better and answer "why" you might do this. By adding another line and putting it in a wrapper:
$ vim ./test.sh #!/bin/bash exec 4<&0 0</etc/XX/cfg read line1 # reads from fd4 exec 0<&4 read line2 # reads from fd0 echo $line1 echo $line2
You can pipe or redirect
stdin via test.sh but also read in configuration by redirection, so in the code above I've pulled in values from the "config" (assumption on my part based on the filename - bad :) ), but I can process via stdin as well.
$ ./test.sh < somefile $ cat somefile | ./test.sh
Hopefully this explains it.
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?