Skip to content
shellhacks.dev
Performance

Read the first line without head

Read the first line of a file with read -r line < file, a builtin, instead of head -n 1. The shell does it without starting a process.

1 min read
Summarize in AI

A script wants the first line of a file, such as a version string, and calls head -n 1 for it each time.

Shell
printf '1.4.2\nsecond line\n' > VERSION
read -r first < VERSION
echo "[$first]"
TIMEFORMAT='%3R seconds'
echo "head:"
time (for i in {1..5000}; do x=$(head -n 1 VERSION); done)
echo "read:"
time (for i in {1..5000}; do read -r x < VERSION; done)
Text
[1.4.2]
head:
7.108 seconds
read:
0.037 seconds

read is a shell builtin, and it reads a single line from its standard input, which the redirection connects to the file. The -r option stops it treating a backslash as an escape, as the read builtin documentation says. No process starts, so the loop is faster by a large factor on this run (5,000 iterations, Debian 12 container, arm64 laptop).

read strips leading and trailing blanks unless you set IFS= for it, and it returns status 1 on a last line without a newline, although the variable is still set. Add || [[ -n $x ]] in a loop that must handle that. Only the first line is read, so the rest of the file is untouched.

Share

More snippets

Performance

Count lines in a huge file fast

Count the lines of a big file with wc -l, which is the fastest of the usual tools. It counts newlines, so a last line without a newline is not counted.

2 min read
Performance

Find syscalls that take time

Show how long each system call takes with strace -T. The figure in angle brackets is the time spent inside the call, so a slow write or sleep stands out.

1 min read
Performance

Trace file opens of a command

Find which files a command opens with strace -e trace=openat, and add -e status=failed to see the config files it looked for and did not find.

2 min read

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.