4

I install a list of URLs in a text file named myurls:

http://www.examples.com/1
http://www.examples.com/2
http://www.examples.com/3

How shall I pass these URLs to wkhtmltopdf as inputs?

The direct way without using a file to store the URLs is

wkhtmltopdf http://www.examples.com/1 http://www.examples.com/2 http://www.examples.com/3 all.pdf

Maybe wkhtmltopdf has special requirements on its arguments, but I think my question may be more general than wkhtmltopdf: how to provide a list of (new line separated) strings stored in a file as a list of arguments to a command?

Tim
  • 101,790

4 Answers4

5

Try:

# disable shell filename generation (globbing) 
# and temporarily save applicable shell state
set -f -- "-${-:--}" "${IFS+IFS=\$2;}" "$IFS" "$@"

# explicitly set the shell's Internal
# Field Separator to only a newline 
eval "IFS='$(printf \\n\')"

# split command substitution into an
# arg array at $IFS boundaries while
# eliding all blank lines in myurls
wkhtmltopdf $(cat <myurls) allurl.pdf

# restore current shell to precmd state
unset IFS; set +f "$@"; eval "$1 shift 2"

That's extra cautious about restoring all shell state after possibly altering universally applied attributes. But the basic precept is just to set the shell's splitter in $IFS, to take care not to glob in case any of the command substitution's expansion includes [?*, and then to expand it unquoted into a list of arguments.

It can be done robustly much more simply in a subshell because you don't have to live with any after-effects:

(   set -f; IFS='
';  wkhtmltopdf $(cat) allurl.pdf
)   <myurls
Stephen Kitt
  • 434,908
cuonglm
  • 153,898
  • Ah, yeah, my mistake, need literal newline here. What do you mean about using tab? – cuonglm Jun 18 '15 at 15:26
  • Ah, of course. But the OP want a general solution- how to provide a list of (new line separated) strings stored in a file as a list of arguments to a command? - so I stick with limiting it to newline. – cuonglm Jun 18 '15 at 15:34
  • @mikeserv: Feel free to edit it for better approach, I'm not in my PC now. – cuonglm Jun 18 '15 at 15:44
3

Unfortunately it's not the case with wkhtmltopdf, but many commands provide an option to read arguments from a file (wget -i for example); that's the preferred approach where possible.

If whitespace in your file isn't important, command substitution works:

wkhtmltopdf $(cat myurls) all.pdf

Using xargs would also work with your example, but in general given what you're trying to do you'd need to ensure that it only runs wkhtmltopdf once; all.pdf will only contain the pages from the last run of wkhtmltopdf:

xargs -a myurls sh -c 'wkhtmltopdf "$@" all.pdf'

wkhtmltopdf does support an option to read arguments from standard input, --read-args-from-stdin. If you use that to feed it URLs separated by newlines, it repeats executions; to avoid that, you need to ensure that standard input is a single line with all URLs separated by spaces:

tr "\n" " " < myurls | wkhtmltopdf --read-args-from-stdin all.pdf
Stephen Kitt
  • 434,908
1

With xargs:

xargs -a myurls sh -c 'wkhtmltopdf $@ all.pdf'
FloHimself
  • 11,492
0

Another approach:

wkhtmltopdf $(printf '%s ' $(<myurls)) all.pdf
jimmij
  • 47,140