65

A fair number of linux commands have a dry-run option that will show you what they're going to do without doing it. I see nothing in the xargs man page that does that and no obvious way to emulate it.

(my specific use case is troubleshooting long pipelines, though I'm sure there are others)

Am I missing something?

Andrew
  • 1,115

3 Answers3

113

You may benefit from the -p or -t flags.

xargs -p or xargs --interactive will print out the command to be executed and then prompt for input (y/n) to confirm before executing the command.

% cat list
one
two
three

% ls
list

% cat list | xargs -p -I {} touch {}
touch one ?...y
touch two ?...n
touch three ?...y

% ls
list
one
three

xargs -t or xargs --verbose will print each command, then immediately execute it:

% cat list | xargs -t -I {} touch {}
touch one 
touch two 
touch three 

% ls
list
one
three
two
Kevin Hencke
  • 1,246
  • 10
    superb answer with both -p and -t options. excellent examples. thank you! – JCotton Dec 22 '18 at 04:41
  • 1
    On mac BSD xargs the --verbose option isn't recognized, but -t works! – Carl Walsh Apr 01 '21 at 14:54
  • Agreed - Great answer. One tweak I might suggest, though. While it's good to know the -I {} option for more complicated cases, it probably over-complicates that example slightly. More concise would be to use -L 1 as in cat list | xargs -L 1 -p touch, right? – NotTheDr01ds Apr 06 '21 at 16:03
24

Put an echo in front of the command to run?

$ echo a b c d e | xargs -n2 echo rm
rm a b
rm c d
rm e
ilkkachu
  • 138,973
  • 7
    (This, is of course only a simple solution that works in trivial cases. The output will be ambiguous if the parameters contain spaces or control characters. We'd need some dedicated tool to unambiguously print the parameters it receives.) – ilkkachu Aug 04 '16 at 12:14
  • What about if you're trying to dry-run echo? :) – mbigras Apr 10 '17 at 00:19
  • This isn't the answer to the question, and it shouldn't be the accepted one. This answer show an example of using 'xargs' on the 'echo' command. The OP wants to run 'xargs' on an arbitrary command, but also show the computed command which is about to be fired. The correct answer is below, by Kevin Hencke, about the -t and -p flags. – Gabriel Apr 27 '20 at 09:24
  • @Gabriel, of course it's an answer to the question. It's not a complete answer, of course, more like an idea (which is somewhat hinted at by the question mark, and the comment noting that there are limitations). But an answer it is, and it's up to every one else to decide how to vote on it. Not that there seem to have been many alternatives in, oh, one and a half years. – ilkkachu Apr 27 '20 at 17:27
  • @Gabriel, note that the question mentioned "[an] option that will show you what they're going to do without doing it." -- I can't really see how --verbose and --interactive could be bent to do that, unless someone can figure out a way to pipe the output of yes n to xargs --interactive (I tried and failed). Also, --verbose also has the issue that its output is ambiguous, e.g. echo '"a b" c' | xargs --verbose rm prints rm a b c, the same as echo 'a b c' | xargs --verbose rm prints, even though the commands are very much not the same. – ilkkachu Apr 27 '20 at 17:31
  • @Gabriel, but honestly, I wish there was a better answer. I'll be happy to edit this to point to one when e.g. xargs implements a working --dry-run itself. – ilkkachu Apr 27 '20 at 17:33
2

Inspect Arguments with Your Favorite Programming Langauges

Insert any of the following commands betweenxargs and commands you want to execute.

  1. ruby -e 'p ARGV'
  2. node -e 'console.log(process.argv)'
  3. python -c 'import sys; print sys.argv'

In this answer, I would use ruby -e 'p ARGV' for every example.

Usage

Let's say you want to debug the script:

echo 1 2 3 4 | xargs echo

To debug, put ruby -e 'p ARGV' before echo:

echo 1 2 3 4 | xargs ruby -e 'p ARGV' echo
["echo", "1", "2", "3", "4"]

As we can see, it's very clear that echo received 2 arguments.

Here is another example using -I:

echo 1 2 3 4 | xargs -I@ ruby -e 'p ARGV' echo @
["echo", "1 2 3 4"]

Now we know echo received only one argument.

Why not xargs -t -p?

Because -t and -p are really ambiguous when there are white spaces in command arguments, for example:

printf 'hello world\0goodbye world' | xargs -0 -t echo
echo hello world goodbye world
hello world goodbye world

When looking at echo hello world goodbye world, it's hard to tell whether echo received 2 or 4 arguments.

By using the solution, it's easy to understand how xargs treats each arguments:

printf 'hello world\0goodbye world' | xargs -0 ruby -e 'p ARGV' echo
["echo", "hello world", "goodbye world"]
Weihang Jian
  • 1,227