wget no shell script usando um padrão

1

Atualmente, estou tentando configurar um script de shell utilizando o wget para baixar uma grande quantidade de arquivos de um servidor. Estou usando a opção -A 'pattern * .extension' para baixar apenas arquivos com um padrão e uma extensão específicos que me interessem. (Além disso, há muitos arquivos que não quero perder espaço no meu PC Se eu executar wget via linha de comando, tudo funciona muito bem e ele baixa exatamente todos os arquivos que combinam com o padrão. Agora, se eu tentar executar o script com o mesmo comando wget de antes, ele diz: "wget: No match". (Devo mencionar que o script de shell está sendo executado por um script python que é fornecido com uma lista de IDs para baixar arquivos de subpastas específicas.) Mas: Se eu imprimir a linha exata do wget, o script de shell será executado e copiar e colá-lo a linha de comando, funciona novamente. Isso não faz sentido para mim.

Aqui está como meu wget se parece:

wget -r -c -nH -np -nd -e robots=off -P PATH -A 'pattern*.extension' -a logfile.log --progress=bar:force --no-check-certificate  https://.../ID/

E aqui está a aparência do meu script de shell:

#!/usr/bin/tcsh
set ID=$1  #just an ID for subfolders
set OPT2=$3  #additional options that can be passed to wget
set OPT="-r -c -nH -np -nd -e robots=off -P PATH/$ID -A 'pattern*.extension' -a $ID.log"
set OOP="--progress=bar:force --no-check-certificate" 
while ($1 != '')    
     echo "wget $OPT $OOP $OPT2 https://.../$ID/"
     wget $OPT $OOP $OPT2 https://.../$ID/
 shift
end 

A saída é a seguinte:

wget -r -c -nH -np -nd -e robots=off -P PATH/ID -A 'pattern*.extension'  -a ID.log --progress=bar:force --no-check-certificate https://.../ID/
wget: No match.

Mas agora, se eu copiar essa linha exata que meu script ecoa, funciona! Por favor me esclareça. Eu estava tentando tanto consertar isso, mas, obviamente, eu simplesmente não consegui fazer isso.

Além disso: se eu substituir -A 'pattern * .extension' por -A.extenstion, ele baixará todos os arquivos com essa extensão. Por algum motivo, simplesmente não funciona quando se usa um padrão.

Como mencionei acima, o script de shell é chamado por um script python:

for ID in IDs:
    cmd = 'csh PATH/script.csh %s' % (ID)
    sub.call( cmd, shell=True )

Talvez isso também ajude e talvez eu deva mencionar também que eu não sou realmente um programador avançado.

Obrigado antecipadamente.

    
por F. Emmerich 23.05.2018 / 11:15

1 resposta

1

Eu não estou familiarizado com o tcsh, então pode haver uma boa correção para isso no tcsh.

Dito isso, estou familiarizado com o bash e posso ver o que pode estar causando esse problema. Observe a citação aqui:

set OPT="-r -c -nH -np -nd -e robots=off -P PATH/$ID -A 'pattern*.extension' -a $ID.log"

Há uma camada externa de aspas e, além disso, uma camada interna de aspas para pattern*.expansion . Presumivelmente, você está usando a camada interna porque é assim que ficaria se você realmente digitasse o comando no shell.

A maneira como isso funciona, o shell executa várias expansões na linha de comando, como expansão de variáveis, expansão de curingas, etc. Em um comando como:

wget $OPT ...

o shell expandirá $OPT para seu conteúdo, realizará a divisão de campo, separando o conteúdo de $OPT para palavras separadas e a expansão de caractere curinga (ou globbing), que é onde o comando falha:

> set foo="'*'"
> echo $foo
echo: No match.
> echo "$foo"
'*'

Observe como as aspas em torno de $foo impediram o erro? Mas você não pode usar aspas no seu script, pois as cotações também impedirão a divisão de campo e você estará confiando na divisão de campo para que as várias opções em $OPT ( -r , -c , etc.) sejam passadas como separadas argumentos para wget .

Aqui está uma demonstração das diferenças com e sem citações:

> printf "|%s|\n" "$OPT"
|-r -c -nH -np -nd -e robots=off -P PATH/foo -A 'pattern*.extension' -a foo.log|
> printf "|%s|\n" $OPT
printf: No match.
> printf "|%s|\n" -r -c -nH -np -nd -e robots=off -P PATH/$ID -A 'pattern*.extension' -a $ID.log
|-r|
|-c|
|-nH|
|-np|
|-nd|
|-e|
|robots=off|
|-P|
|PATH/foo|
|-A|
|pattern*.extension|
|-a|
|foo.log|

Eu imagino que isso funcione se você usou:

set OPT="-r -c -nH -np -nd -e robots=off -P PATH/$ID -A pattern*.extension -a $ID.log"

Mas isso arrisca a expansão de curinga se você não usa "$OPT" , e o diretório de trabalho tem arquivos correspondentes a pattern*.extension :

> touch pattern-abc.extension
> printf "|%s|\n" $OPT
printf: No match.
> set set OPT="-r -c -nH -np -nd -e robots=off -P PATH/$ID -A pattern*.extension -a $ID.log"
> printf "|%s|\n" $OPT
|-r|
|-c|
|-nH|
|-np|
|-nd|
|-e|
|robots=off|
|-P|
|PATH/foo|
|-A|
|pattern-abc.extension|      <---- tcsh expanded pattern*.extension
|-a|
|foo.log|

Mais uma vez, não tenho habilidade suficiente em tcsh para sugerir uma boa solução, mas conheço uma solução decente no bash:

Use matrizes para criar linhas de comando.

No bash, seu script seria parecido com:

#!/bin/bash
ID=$1  #just an ID for subfolders
shift

OPT2=("$@")  #additional options that can be passed to wget
OPT=(-r -c -nH -np -nd -e robots=off -P PATH/"$ID" -A 'pattern*.extension' -a "$ID".log)
OOP=(--progress=bar:force --no-check-certificate)

echo wget "${OPT[@]}" "${OOP[@]}" "${OPT2[@]}" "https://.../$ID/"
wget "${OPT[@]}" "${OOP[@]}" "${OPT2[@]}" "https://.../$ID/"

Eu fiz algumas alterações aqui. Você atribuiu $3 a OPT2 , mas, em seguida, repetiu todos os argumentos (na verdade, é isso que while ($1 != '') ... shift fará), mas sem usar esses argumentos no loop, o que não faz sentido - o segundo argumento o script é efetivamente ignorado, mas o terceiro argumento é usado como uma opção. Dado o trecho de Python, vou assumir que apenas o primeiro argumento é o ID e o restante são opções para wget .

Agora, usando uma matriz assim:

OPT=(-r -c -nH -np -nd -e robots=off -P PATH/"$ID" -A 'pattern*.extension' -a "$ID".log)

Nos permite expandir para cada palavra separada na matriz, enquanto não estamos arriscando a divisão de campos ou geração de nome de arquivo, usando "${OPT[@]}" no bash:

$ printf "|%s|\n" "${OPT[@]}"
|-r|
|-c|
|-nH|
|-np|
|-nd|
|-e|
|robots=off|
|-P|
|PATH/foo|
|-A|
|pattern*.extension|
|-a|
|foo.log|

Todo argumento perfeitamente preservado.

    
por muru 23.05.2018 / 13:14