Read a file without cat in Bash
Read a whole file into a variable with $(<file) in Bash. It runs without a cat process and returns the same text, with the trailing newlines removed.
A script reads a small config file into a variable thousands of times, and $(cat file) forks a process on each one.
echo "token-value" > secret.txt
a=$(cat secret.txt)
b=$(<secret.txt)
[[ $a == "$b" ]] && echo "same: [$b]"
TIMEFORMAT='%3R seconds'
echo "cat:"
time (for i in {1..5000}; do x=$(cat secret.txt); done)
echo "redirect:"
time (for i in {1..5000}; do x=$(<secret.txt); done)same: [token-value]
cat:
6.776 seconds
redirect:
0.034 secondsA command substitution of the form $(<file) is a special case in Bash: the shell reads the file itself, with no cat, as the command substitution section of the manual says. Both forms remove trailing newlines, so the two variables are equal. The timings are for 5,000 reads in a Debian 12 container on an arm64 laptop.
The shortcut is a Bash and ksh feature, and in dash it expands to nothing, so keep $(cat file) in a script with a #!/bin/sh line. Both forms drop trailing newlines, and a NUL byte in the file is dropped with a warning in Bash. For a file with many lines, mapfile -t lines < file is the way to get them into an array.