🎓 A1Learner
🔍
0 of 45 lessons completed

Bash File Descriptors in Functions

File descriptors in functions are numbered channels that a function shares with its caller. Careful handling lets a function use its own channel without clobbering the caller's.

A function writes through the caller's descriptor

The script opens descriptor 3 on a log file. The function writes through descriptor 3, and the log file proves it.

exec 3>log.txt
write_log() {
  echo "entry one" >&3
}
write_log
exec 3>&-
cat log.txt

A redirection on a call ends with the call

The function is called with its output redirected to a file. The caller's own output is normal again right after.

show() {
  echo "inside function"
}
show > captured.txt
echo "outside function"
cat captured.txt

Let Bash allocate the descriptor number

The script lets Bash pick a free number and stores it in a variable. The function writes through that variable, so no fixed number is guessed.

exec {logfd}>second.txt
write_to_log() {
  echo "logged line" >&$logfd
}
write_to_log
exec {logfd}>&-
cat second.txt

Example

open_log() {
  exec {logfd}>app.txt
}
write_log() {
  echo "$1" >&$logfd
}
close_log() {
  exec {logfd}>&-
}
open_log
write_log "start ok"
write_log "work done"
close_log
cat app.txt
echo "log closed"

Key points

  • Shared channels: a function inherits the caller's open descriptors, so it can write to them directly.
  • Call-only redirection: a redirection on a function call applies only while that call runs.
  • Allocated numbers: use exec {name}>file to let Bash pick a free descriptor number.
  • No clobbering: an allocated number cannot silently overwrite a descriptor the caller already uses.
  • Shared position: reading from a passed descriptor moves the shared read position for the caller too.
  • Close what you open: close an allocated descriptor when done so its number can be reused safely.

In this example, open_log lets Bash allocate a free descriptor on app.txt. Each write_log call sends one message through that descriptor. close_log closes the allocated descriptor, then cat shows both logged lines and the final line confirms the log is closed.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

Why should a function use an allocated descriptor instead of a fixed number like 3?