Skip to content

fix: replace {} placeholder in -exec utility name#647

Open
mvanhorn wants to merge 2 commits intouutils:mainfrom
mvanhorn:osc/614-fix-exec-placeholder
Open

fix: replace {} placeholder in -exec utility name#647
mvanhorn wants to merge 2 commits intouutils:mainfrom
mvanhorn:osc/614-fix-exec-placeholder

Conversation

@mvanhorn
Copy link
Copy Markdown

Summary

Fixed -exec to replace {} in the utility_name position, not just in arguments. Previously find -exec {} \; passed the literal string "{}" to Command::new.

Why this matters

Per POSIX (find -exec utility_name [argument ...] ;), a utility_name containing only "{}" should be replaced with the current pathname. GNU find and BSD find both handle this correctly. uutils find failed with "No such file or directory" because {} was never substituted in the executable field.

Repro from #614:

find /usr/bin -name pwd -exec {} -P ';'
# Expected: runs /usr/bin/pwd -P
# Got: Failed to run {}: No such file or directory (os error 2)

Changes

  • src/find/matchers/exec.rs: Extracted parse_arg helper from the duplicated split logic. Changed SingleExecMatcher.executable from String to Arg so it undergoes the same {} replacement as arguments. Updated error formatting to use the resolved executable path.

Testing

All 25 existing tests pass. Verified compilation with cargo check and cargo clippy (no warnings). Tested manually with cargo run --bin find -- /usr/bin -name pwd -exec {} -P \;.

Fixes #614

This contribution was developed with AI assistance (Claude Code).

The {} placeholder was only replaced in arguments to -exec, not in the
utility_name position itself. Running `find -exec {} \;` passed the
literal string "{}" to Command::new, causing "No such file or directory".

Extracted arg parsing into a shared `parse_arg` helper and changed the
`executable` field from String to the existing Arg enum so it undergoes
the same {} replacement as other arguments.

Fixes uutils#614
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 27, 2026

Codecov Report

❌ Patch coverage is 68.75000% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.70%. Comparing base (015727f) to head (da847c6).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/find/matchers/exec.rs 68.75% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #647      +/-   ##
==========================================
- Coverage   91.76%   91.70%   -0.06%     
==========================================
  Files          31       31              
  Lines        6203     6207       +4     
  Branches      328      328              
==========================================
  Hits         5692     5692              
- Misses        390      394       +4     
  Partials      121      121              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jmr
Copy link
Copy Markdown

jmr commented Mar 27, 2026

What do you do with foo{}bar in the first position? According to POSIX, this is unspecified, but GNU will substitute there.

Also, probably a good idea to add some tests. Claude didn't do that automatically?

@sylvestre
Copy link
Copy Markdown
Contributor

Indeed, it needs tests

Verify that SingleExecMatcher resolves {} in arguments
when the executable is a known path. Covers the case
where -exec receives {} in argument positions.
@mvanhorn
Copy link
Copy Markdown
Author

Added a test in da847c6. On the foo{}bar question - the current implementation already handles embedded placeholders via the FileArg(parts) pattern (splits on {} and joins with the pathname), so foo{}bar in any position resolves to foo/path/to/filebar. This matches GNU find behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

find -exec {} [args...] \; fails

3 participants