/errors/find/xargs-unmatched-single-quote
xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option
- tool
- find
- exit code
- 1
- versions
- GNU findutils 4.x
- os
- linux, macos, windows
GNU xargs prints xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option when its input contains an apostrophe with no closing one. By default xargs splits input on blanks and interprets ', " and \ as quoting, so a file named it's.txt breaks it. Feed it NUL-separated names instead: find . -type f -print0 | xargs -0 COMMAND.
Reproduce it
touch "it's.txt" notes.txt
find . -name '*.txt' | sort | xargs ls
echo "exit status: ${PIPESTATUS[2]}"Output
xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option exit status: 1
xargs stops at the bad line and exits with status 1. Names before it may already have been passed to the command, so the command can run on part of the input.
Fix: NUL separators
touch "it's.txt" notes.txt "with space.txt"
find . -name '*.txt' -print0 | sort -z | xargs -0 ls -1Output
./it's.txt ./notes.txt ./with space.txt
-print0 ends each name with a NUL byte, the one character that cannot appear in a file name, and -0 tells xargs to split on NUL and treat quotes, backslashes and spaces as ordinary characters.
Other options
| Approach | Command | Notes |
|---|---|---|
| NUL-separated | find . -print0 | xargs -0 CMD | Safe for every file name |
| Newline-separated (GNU) | xargs -d '\n' CMD | Safe unless names contain newlines |
| No xargs | find . -exec CMD {} + | Batches arguments like xargs |
| grep output | grep -lZ PATTERN ... | xargs -0 CMD | -Z (--null) ends each name with NUL |
touch "it's.txt" notes.txt
find . -name '*.txt' -exec ls -1 {} + | sortOutput
./it's.txt ./notes.txt