Use find -exec or -print0 instead of piping to xargs

SC2038: `find ... | xargs` breaks on filenames with spaces, newlines, or quotes. Use `-print0 | xargs -0` or `-exec`.

Problem

The default pipeline splits on whitespace, so any filename containing a space, tab, newline, or quote character is misinterpreted. This is a data-corruption bug waiting for an unusual filename.

Bad

find . -name '*.tmp' | xargs rm

Good

find . -name '*.tmp' -print0 | xargs -0 rm --
# or (no xargs needed):
find . -name '*.tmp' -exec rm -- {} +

Explanation

`-print0` / `-0` uses NUL as the separator — the only byte that cannot appear in a filename. `-exec ... +` batches efficiently and needs no xargs at all.

When It Matters

find ... | xargs splits on whitespace, so every filename containing a space is passed as two or more arguments. Combined with a destructive command, "my file.txt" becomes an attempt to operate on "my" and on "file.txt" — and if a file named "my" happens to exist, it is the one that gets deleted. Filenames with newlines are worse still, and they are entirely legal on Linux, which is why archive extraction and user-uploaded content are the usual triggers.

Second Example

Note

-exec ... + batches many files into one invocation, so it is as efficient as xargs while being safe by construction.

Exceptions

When the input is generated by you and cannot contain whitespace — a list of numeric IDs or git hashes, for example — plain xargs is fine. Prefer -0 anyway when the producer can emit it; it costs nothing and removes an entire class of bug.

Faq

Q

What is the difference between -exec {} \; and -exec {} +?

A

The semicolon form runs the command once per file; the plus form appends as many files as fit onto one command line, which is much faster for large sets.

Q

Is xargs -0 portable?

A

It is a GNU and BSD extension rather than POSIX, but it is available on Linux, macOS, and the BSDs. In strictly POSIX environments use -exec.

Q

Why not just quote the filenames in the pipe?

A

There is nothing to quote — the pipe carries plain text, and xargs cannot know which spaces are separators and which are part of a name. Only a NUL delimiter removes the ambiguity.