pythonlinuxcommand-linedocopt

Pass output of 'find' command to Python with docopt (issue with spaces)


Consider this simple Python command-line script:

"""foobar
  Description

Usage:
  foobar [options] <files>...

Arguments:
  <files>         List of files.

Options:
  -h, --help      Show help.
      --version   Show version.
"""

import docopt

args = docopt.docopt(__doc__)
print(args['<files>'])

And consider that I have the following files in a folder:

Now I want to pass the output of the find command to my simple command-line script. But when I try

foobar `find . -iname '*.pdf'`

I don't get the list of files that I wanted, because the input is split on spaces. I.e. I get:

['./file', '2.pdf', './file1.pdf']

How can I correctly do this?


Solution

  • This isn't a Python question. This is all about how the shell tokenizes command lines. Whitespace is used to separate command arguments, which is why file 2.pdf is showing as as two separate arguments.

    You can combine find and xargs to do what you want like this:

    find . -iname '*.pdf' -print0 | xargs -0 foobar
    

    The -print0 argument to find tells it to output filenames seperated by ASCII NUL characters rather than spaces, and the -0 argument to xargs tells it to expect that form of input. xargs with then call your foobar script with the correct arguments.

    Compare:

    $ ./foobar $(find . -iname '*.pdf' )
    ['./file', '2.pdf', './file1.pdf']
    

    To:

    $ find .  -iname '*.pdf' -print0 | xargs -0 ./foobar
    ['./file 2.pdf', './file1.pdf']