Skip to content
Linux Basics: Pass Difficult Filenames from find to xargs

Linux Basics: Pass Difficult Filenames from find to xargs

October 29, 2026

A filename can contain spaces, quotes, and even newlines. A pipeline that splits paths on whitespace can accidentally turn one file into several arguments. NUL separators preserve the path boundaries through every stage.

Prepare a scratch directory

Tested on Linux with GNU coreutils 9.7, GNU findutils 4.10.0, and GNU Bash 5.2.37. You need Bash, a text editor, and the utilities used below. The script creates its own temporary fixture directory and removes only that directory on exit.

Keep the same terminal open. Stop if setup fails, before saving the source:

start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1

Run the example

Save this as demonstrate-find-xargs-null-paths.sh:

#!/usr/bin/env bash
set -euo pipefail
export LC_ALL=C
fixture_dir="$(mktemp -d)"
trap 'rm -rf -- "$fixture_dir"' EXIT
cd -- "$fixture_dir"
mkdir inputs empty
touch -- 'inputs/alpha beta.txt' $'inputs/line\nbreak.txt' 'inputs/-leading.txt'
printf 'Escaped arguments received by Bash:\n'
find inputs -type f -print0 | sort -z | xargs -0 -r bash -c 'printf "%q\n" "$@"' show-paths
printf 'An empty match set runs no command:\n'
find empty -type f -print0 | xargs -0 -r printf 'UNEXPECTED\n'
printf 'Done\n'

Run it:

bash demonstrate-find-xargs-null-paths.sh

Observed output:

Escaped arguments received by Bash:
inputs/-leading.txt
inputs/alpha\ beta.txt
$'inputs/line\nbreak.txt'
An empty match set runs no command:
Done

Read the result

find -print0 terminates each path with a NUL byte. GNU sort -z retains those record boundaries while making the display order repeatable. xargs -0 reads the same format. The fixed Bash program receives paths as separate arguments in "$@"; it does not splice their text into shell source. show-paths occupies Bash’s $0, so the first path remains in $1. Bash printf %q displays shell-escaped representations, including the embedded newline.

Apply it carefully

GNU xargs -r skips the command when there are no records. NUL delimiters solve argument boundaries, not races: another process can rename or replace files between discovery and use. This example only previews arguments in a controlled directory. Paths begin with inputs/, so the leading hyphen in one basename is not a command option. For a real consumer, also follow its end-of-options convention where supported. Do not replace the fixed script with generated shell code or eval.

The GNU reference documents these options and their behavior.

Clean up

Remove the saved script, return to the starting directory, and remove the empty practice directory:

rm -- demonstrate-find-xargs-null-paths.sh
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dir

If the directory is not empty, inspect what remains rather than deleting unknown files.

Acknowledgements

This post was created with assistance from AI.

Last updated on