32

That is literal, {fd} isn't a placeholder. I have a script that does this, and does not source in anything, nor does it reference {fd} anywhere else. Is this valid bash?

exec {fd}</dev/watchdog

Jeff Schaller
  • 66,199
  • 35
  • 114
  • 250
Gregg Leventhal
  • 7,480
  • 19
  • 65
  • 100

3 Answers3

44

Rather than having to pick a file descriptor and hope it's available:

exec 4< /dev/watchdog  # Was 4 in use? Who knows?

this notation asks the shell to pick a file descriptor that isn't currently in use, open the file for reading on that descriptor, and assign the number to the given variable (fd).

$ exec {fd}< /dev/watchdog
$ echo $fd
10
chepner
  • 7,341
  • 1
  • 26
  • 27
  • I'm sure that you're right, because (1) I recall reading it somewhere, and (2) I just tried it (and it works).  But I couldn't find it documented anywhere.  (Of course, I had less than ten minutes to search before you posted your answer.)  Can you provide a reference to where it is documented? – Scott - Слава Україні Aug 28 '15 at 20:01
  • 2
    See the man page, 2nd paragraph of the section `REDIRECTIONS`. It doesn't really jump out at you, since they don't give an explicit example. – chepner Aug 28 '15 at 20:04
  • You are right, I missed it in man bash, but it's there where you said. It should be noted that any word, not just fd will work in the braces, and that it assigns an fd >= 10. – Gregg Leventhal Aug 28 '15 at 20:27
  • @chepner: Thanks.  D’oh!  Hidden in plain sight.  I’ve been eating Unix man pages for breakfast for a longer time than I choose to admit, and I still occasionally choke on one.  It sometimes seems as though the authors were writing for some target demographic other than human beings.  P.S. I can’t find it in [POSIX](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_07), so it may be available only in bash. – Scott - Слава Україні Aug 28 '15 at 20:27
  • 4
    @Scott, not only is it only in bash, but it's only in bash 4.1 or newer (thus not available on the 3.2 releases still used on MacOS). – Charles Duffy Aug 28 '15 at 22:03
  • It's also available in `ksh` and `zsh`. I couldn't tell you the minimum versions necessary. – chepner Aug 28 '15 at 22:14
  • 2
    @CharlesDuffy `/dev/watchdog` doesn't exist on Mac OS X either, though; it's a Linux-specific device. –  Aug 28 '15 at 22:32
  • @duskwuff, sure, but there are still Linux distros that aren't shipping 4.1+; such is the outcome of having "enterprise" distros with support cycles that last the better part of a decade. Anyhow, I think it's reasonable to assume that the larger question is about the shell idiom, not the specific application. – Charles Duffy Aug 28 '15 at 22:34
13

The form:

{var}<filename

made the shell open file filename for reading and store file descriptor number in variable var. There's no space allowed between {var} and redirection operators, and the file descriptor number will be greater than or equal 10.

This feature was original from ksh (from version ksh93r in 2006), bash copied it a lot later in bash-4.1-alpha from 2010. zsh also made the change earlier than bash from zsh 4.3.4 in 2007.

cuonglm
  • 150,973
  • 38
  • 327
  • 406
5

This is explained in the Bash manual section on Redirections.

Each redirection that may be preceded by a file descriptor number may instead be preceded by a word of the form {varname}. In this case, for each redirection operator except >&- and <&-, the shell will allocate a file descriptor greater than 10 and assign it to {varname}. If >&- or <&- is preceded by {varname}, the value of varname defines the file descriptor to close.

Barmar
  • 9,648
  • 1
  • 19
  • 28