Fornece strings armazenadas em um arquivo como uma lista de argumentos para um comando?

3

Eu instalo uma lista de URLs em um arquivo de texto chamado myurls :

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

Como devo passar esses URLs para wkhtmltopdf como entradas?

O caminho direto sem usar um arquivo para armazenar os URLs é

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

Talvez wkhtmltopdf tenha requisitos especiais em seus argumentos, mas acho que minha pergunta pode ser mais geral do que wkhtmltopdf : como fornecer uma lista de (novas linhas separadas) strings armazenadas em um arquivo como uma lista de argumentos para um comando?

    
por Tim 18.06.2015 / 06:52

4 respostas

4

Tente:

# disable shell filename generation (globbing) 
# and temporarily save applicable shell state
set -f -- "-${-:--}" "${IFS+IFS=\;}" "$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"

Isso é muito cauteloso ao restaurar todo o estado do shell depois de possivelmente alterar os atributos aplicados universalmente. Mas o preceito básico é apenas para definir o divisor do shell em $IFS , para cuidar de não para glob no caso de qualquer expansão de substituição de comando incluir [?* e, em seguida, expandi-lo sem ser incluído em um lista de argumentos.

Isso pode ser feito de maneira muito mais simples em um subshell, porque você não precisa viver com nenhum efeito secundário:

(   set -f; IFS='
';  wkhtmltopdf $(cat) allurl.pdf
)   <myurls
    
por 18.06.2015 / 07:05
2

Infelizmente não é o caso de wkhtmltopdf , mas muitos comandos fornecem uma opção para ler argumentos de um arquivo ( wget -i , por exemplo); essa é a abordagem preferida, sempre que possível.

Se o espaço em branco em seu arquivo não for importante, a substituição de comando funcionará:

wkhtmltopdf $(cat myurls) all.pdf

Usar xargs também funcionaria com o seu exemplo, mas, em geral, considerando o que você está tentando fazer, é necessário garantir que ele execute wkhtmltopdf uma vez; all.pdf conterá apenas as páginas da última execução de wkhtmltopdf :

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

wkhtmltopdf suporta uma opção para ler argumentos da entrada padrão , --read-args-from-stdin , mas que repete execuções, mesclar cada linha da entrada padrão com o restante dos argumentos da linha de comando; então

wkhtmltopdf --read-args-from-stdin all.pdf < myurls

seria equivalente a

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

que não é o que você deseja ( all.pdf conterá apenas o último site).

    
por 18.06.2015 / 07:01
1

com xargs :

xargs -a myurls sh -c 'wkhtmltopdf $@ all.pdf'
    
por 18.06.2015 / 08:21
0

Outra abordagem:

wkhtmltopdf $(printf '%s ' $(<myurls)) all.pdf
    
por 18.06.2015 / 07:05