tail -f and -F: Follow a Growing File
tail -f keeps the file open and prints new lines as they are appended; -F also re-opens it after rotation.
tail -f is how you watch a log live. In CI you almost always need --pid or a timeout so the job does not hang forever.
What it does
tail -f prints the last lines and then blocks, emitting new data as it is appended to the same file descriptor. tail -F (capital) follows by name, re-opening the file if it is rotated or recreated, which -f does not do. Neither exits on its own.
Common usage
tail -f app.log
tail -F /var/log/app.log # survive logrotate
tail --pid=$PID -f app.log # stop when process PID exits
timeout 30 tail -f app.log # bound the wait in CIOptions
| Flag | What it does |
|---|---|
| -f | Follow by descriptor; print appended data |
| -F | Follow by name; re-open after rotation/truncation |
| --pid=PID | Exit when process PID dies (GNU) |
| -n N | Lines to show before following starts |
| --retry | Keep trying to open a not-yet-existing file |
In CI
tail -f never returns by itself, so a CI step that uses it will hang. Always bound it: timeout 30 tail -f, tail --pid=$PID -f, or kill the tail after the work it watches finishes. Use -F for logs that rotate during the run.
Common errors in CI
The most common failure is a job that hangs until the runner timeout because tail -f never exits; add timeout or --pid. --pid and --retry are GNU; BSD/macOS tail lacks --pid, so use timeout instead there. -f alone keeps reading the old, rotated file and shows nothing new; use -F when rotation is possible.