1

mapfile -t -u 7 arr < textfile gives me bash: mapfile: 7: invalid file descriptor: Bad file descriptor Other, more verbose, methods of reading files line-by-line do allow for such descriptor, e.g.

read_w_while() {
while IFS="" read -u 7 -r l || [[ -n "${l}" ]]; do
  echo "${l}"
done 7< textfile

The standard descriptor, 0, is used quite a lot. Does using such descriptor make scripting more secure from interference? My experience is that so far I only witnessed, I am a Ubuntu Desktop user, such interference when using while IFS="" read -u 7 ... with the descriptor 7. What might be the reasons of such interference.

ilkkachu
  • 138,973
  • I'm confused by what you want to achieve with mapfile -t -u 7 arr < textfile: this is self-contradictionary. On one hand, you clearly want to read textfile into arr by opening it and passing it as stdin file descriptor, as stated by < textfile, on the other hand, you clearly want to ignore stdin as input and instead read from file descriptor 7, as stated by -u 7. – Marcus Müller Jan 01 '24 at 14:06
  • 1
    "so far I only witnessed ... such interference when using while IFS="" read -u 7 ..." -- umh, can you elaborate on that? Exactly what sort of interference have you witnessed? I'm not even exactly sure if you mean active (malicious) interference, or e.g. software bugs or such. – ilkkachu Jan 01 '24 at 15:09
  • @ilkkachu trimmer_conc_after() { of=$(echo "${if}"|sed -E "s/(\.)([abBevVimpoO4kw]{3,4}$)/\1trimmed\.$p_no.\2/") ffmpeg -loglevel warning -hide_banner -ss ${l} -i "${if}" -c copy "${of}" && echo "${of}">>list_of_fragments } This function is the culprit. On second thought it must be sed that is inserting sometimes(in about 10-30% of executing this function) many lines of textual input that seemingly has nothing to do with the names of files. The issue seems to be unrelated to read -r -u 7. – John Smith Jan 01 '24 at 19:57

2 Answers2

3

As pointed out in comments, -u 7 and < textfile do not match. You need to either omit -u 7 or you need to change the redirection to 7< textfile as in your second example to make this work. The error is because file descriptor 7 is not open (yet).

As to security issues, I don't see how using file descriptor 7 will change security in any way. The only reason to use another file descriptor like this would be if you want to preserve the pre-existing stdin for some other use within that pipeline. And as this is a single command (mapfile) rather than a complex pipeline, this is moot.

user10489
  • 6,740
3

mapfile -t -u 7 arr < textfile gives me.
bash: mapfile: 7: invalid file descriptor: Bad file descriptor

Yes, it would, if fd 7 isn't open. -u 7 only tells it to read from fd 7, it says nothing about how or where that fd should come to be.

In your second snippet, there's an input redirection 7< textfile that opens a file on fd 7, so it should be quite natural that there, reading from fd 7 works.

You'd usually use another file descriptor for read if you have a need to use the original stdin at the same time, e.g. if you read from a file with a while read ... loop but also run something that reads from the terminal (stdin) within the loop.

Now, strictly speaking, the -u fd option is unnecessary, since the equivalent could be achieved with e.g. read ... 0<&7, but that has the downside that the shell needs to do some juggling to arrange the file descriptors in the correct places:

  • first, duplicate fd 0 to some other number for safekeeping, say fd 9
  • duplicate fd 7 to fd 0 (closing the old fd 0)
  • run read, which reads from fd 0
  • duplicate the original fd 0 from fd 9 (closing the current fd 0)
  • close the now unnecessary copy in fd 9

All that, instead of just

  • run read -u 7, which reads from fd 7

(I originally wrote "close fd 0" as an explicit step, but dup2() does close the destination fd automatically)

ilkkachu
  • 138,973
  • Thanks for your answer. Yes, it would, if fd 7 isn't open. -u 7 only tells it to read from fd 7, it says nothing about how or where that fd should come to be. exec 7<textfile before proceeding with mapfile solved the issue. – John Smith Jan 01 '24 at 20:22