1

Judging from the GNU findutils change log it had to be in GNU's find for at least a decade (also longer than that it was part of POSIX) so can it be safely assumed to be supported everywhere now?

Also, are there any good reasons to advocate for xargs instead in cases where -exec … + could be used? (Obviously you would use xargs if you need some of those special parameters like e.g. those for controlling the maximal number of arguments, parallelism, …)

An interesting quote from a part of GNU findutil's documentation:

[find with -exec … +] can be less efficient than some uses of xargs; for example xargs allows new command lines to be built up while the previous command is still executing, and allows you to specify a number of commands to run in parallel. However, the find ... -exec ... + construct has the advantage of wide portability. GNU findutils did not support ‘-exec ... +’ until version 4.2.12 [January 2005]; one of the reasons for this is that it already had the ‘-print0’ action in any case.

phk
  • 5,953
  • 7
  • 42
  • 71
  • 2
    -exec utility_name [argument ...] {} + is POSIX. What's the question here ? – don_crissti Oct 31 '16 at 21:46
  • @don_crissti: GNU is a major player, I saw people using long-time missing support for -exec … + as a justification to argue for xargs instead. (Compare it to like you can't or couldn't ignore IE even when sticking to the various standards in web development.) – phk Oct 31 '16 at 21:48
  • 2
    Yes, it can be safely assumed to be supported everywhere now, unless you are writing for very old platforms in which case you can't safely assume anything, can you? As @don_crissti pointed out, -exec ... {} + is specified by POSIX. – Wildcard Oct 31 '16 at 22:45
  • @Wildcard I knew about it being part of POSIX, maybe I should've make it clear in my question at first. In any case a standard itself wouldn't be worth much if not widely implemented. – phk Oct 31 '16 at 23:06
  • "...are there any good reasons to advocate for xargs instead in cases where -exec ... + could be used?" No, there aren't. If you have GNU xargs and GNU find you can use the null byte separator, but if you have GNU find you can also just use -exec ... {} +. Since using find | xargs without a null byte separator will work in most cases, it's all the more dangerous because beginners will think their code is robust when it isn't. – Wildcard Oct 31 '16 at 23:35

2 Answers2

4

The + variant of -exec was introduced in POSIX following PASC Interpretation 1003.2 #210 in 2001, and merged with the POSIX standard in issue 6 (as documented in the current standard find(1) documentation). According to the Interpretation, all derivatives of System V Release 4 support it, as does HP-UX (in 2001 — I know HP-UX 10 didn't support it); obviously any POSIX issue 6 or 7-compliant systems support it too.

The GNU-ism is actually the find -print0 | xargs -0 set of commands. If -exec ... + is available, and the -0 support in xargs isn't, you're definitely better off using the former; even with -0 though there's no reason not to use -exec ... + if it supports what you need.

Stephen Kitt
  • 434,908
  • Do you recall if XPG3 find supported the + variant? The last proper Unix system I've used was a Tru64 (support ended in 2012), I believe, with an XPG3 (non-POSIX) find and other utilities, and I don't remember it supporting the + variant. I could easily remember wrong, though; that's why I wrote I was unsure in my own answer. – Nominal Animal Oct 31 '16 at 22:57
  • XPG3 find(1) doesn't support the + variant, but XPG3 is very old (1988). Even XPG4 doesn't have it! – Stephen Kitt Oct 31 '16 at 23:05
  • The last non-macOS "proper Unix" I used was AIX, and that does support the + variant (since at least 5.3). – Stephen Kitt Oct 31 '16 at 23:08
  • Maybe I recall wrong which standard Tru64's find followed, but I do recall issues... In any case, finds with support for the + variant are more common than xargs with -0 support or finds with -print0/-printf support, which makes find ... -exec ... + the more portable safe approach. I think I like your answer better than mine. :) – Nominal Animal Oct 31 '16 at 23:16
  • AIX 5.3 is more recent than Tru64. It's possible to find manual pages for Tru64, e.g., this. – Thomas Dickey Oct 31 '16 at 23:20
  • The Tru64 documentation sets are still available on HPE's web site too. – Stephen Kitt Oct 31 '16 at 23:25
  • Neither the Tru64 documentation or manual pages I can find online say if find supports -exec ... '{}' + or not. Not worth the effort, though; it's not like anyone sane still uses Tru64. At least not a network-connected one. – Nominal Animal Oct 31 '16 at 23:38
1

Can [-exec ...] be safely assumed to be supported everywhere now?

The -exec ... '{}' ';' variant, which supplies exactly one match per command executed, is definitely expected to be supported everywhere now, even on non-POSIX unix systems.

The -exec ... '{}' + variant, I am not certain. True, it is defined in POSIX-1, so it definitely is supported in all current POSIXy systems. However, I am unsure of whether all older unix systems (still in use) support it.

Are there any good reasons to advocate for xargs instead in cases where [-exec ... '{}' +] could be used?

No, not really. Why use two commands when one would suffice?

The issue is more that if the only tool you know is a hammer, all problems look like nails. The power of xargs comes from the fact that you can manipulate the list of matches using bash, sed, awk, and so on, before executing the command(s) acting upon the list.

(In practice, this requires that the file and directory names do not have embedded newlines in them, though. Bash and GNU find, sed, awk, and xargs all support nul character \0 as a separator, so they can manipulate all possible file names without issues.)

  • 2
    Why are you quoting '{}'? That's not special to Bash, nor any POSIX-y shell. – Wildcard Oct 31 '16 at 23:18
  • 1
    @Wildcard: I could claim paranoia or typo mitigation, but the truth is, I just want all newbies to get used to quoting everything. I've seen (and had to fix) way too many issues from scripts and one-liners that forget to quote parameters correctly. Quoting Is Your Friend. Extra quotes like this do no harm, even when they are not necessary. I even like to point out that one can use single-quotes for everything literal in a shell command list, and double-quotes when variable expansion (${var}) is desired. (Note how I used ${var} and not $var?) Seems to help avoid bugs. – Nominal Animal Oct 31 '16 at 23:26
  • Good response. I worry more about people including {} within code passed to sh, and thinking it's safe because it's inside quotes. (Never, ever do this.) :) – Wildcard Oct 31 '16 at 23:28