Wget в сценарии оболочки с использованием шаблона

Итак, я сейчас пытаюсь настроить скрипт оболочки, использующий wget для загрузки огромного количества файлов с сервера. Я использую опцию -A 'pattern * .extension', чтобы загружать только файлы с определенным шаблоном и расширением, которые меня интересуют. (Кроме того, есть множество файлов, которые я не хочу тратить на моем ПК .) Если я запускаю wget через командную строку, все работает нормально и загружает все файлы, соответствующие шаблону. Теперь, если я попытаюсь запустить скрипт с той же самой командой wget, что и раньше, он внезапно скажет: "wget: No match". (Следует отметить, что скрипт оболочки выполняется скриптом python, который снабжен списком идентификаторов для загрузки файлов из определенных подпапок.) Но: если я напечатаю точную строку wget, скрипт оболочки выполнится и скопирует и вставит его в командная строка, это снова работает. Это просто не имеет смысла для меня.

Вот как выглядит мой wget:

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/

А вот как в принципе выглядит мой скрипт оболочки:

#!/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 

Выходные данные выглядят следующим образом:

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.

Но теперь, если я скопирую ту самую строку, которая повторяет мой сценарий, это работает! Пожалуйста, просветите меня. Я так старался это исправить, но, очевидно, мне просто не удалось это сделать.

Также: если я заменю -A 'pattern * .extension' на -A.extenstion, он загрузит все файлы с этим расширением. По некоторым причинам это просто не работает при использовании шаблона.

Как я упоминал выше, скрипт оболочки вызывается скриптом python:

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

Может быть, это тоже помогает, и, возможно, я должен также упомянуть, что я не очень продвинутый программист.

Заранее спасибо.

1
задан 23 May 2018 в 14:54

1 ответ

Я не знаком с tcsh, поэтому в tcsh может быть хорошее решение для этого.

Тем не менее, я знаком с bash и вижу, что может быть причиной этой проблемы. Обратите внимание на цитату здесь:

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

Существует внешний слой цитат и, кроме того, внутренний слой цитат для pattern*.expansion. Предположительно вы используете внутренний слой, потому что так выглядело бы вы, если бы вы действительно набрали команду в оболочке.

Как это работает, оболочка выполняет различные расширения в командной строке, такие как расширение переменных, расширение по шаблону и т. Д. Поэтому в такой команде, как:

wget $OPT ...

оболочка будет расширяться $OPT до его содержимое, разделение полей, разделение содержимого $OPT на отдельные слова и расширение по шаблону (или подстановка), в котором команда не выполняется:

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

Обратите внимание, как заключаются в кавычки $foo ] предотвратил ошибку? Но вы не можете использовать кавычки в вашем скрипте, так как кавычки также предотвратят разделение полей, и вы полагаетесь на разделение полей, так что различные опции в $OPT (-r, -c и т. Д.) Передаются как отдельные Аргументы к wget.

Вот демонстрация различий с кавычками и без них:

> 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|

Я полагаю, это может сработать, если вы использовали:

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

Но это может привести к расширению подстановочного знака, если вы не t использовать "$OPT", и в рабочем каталоге есть файлы, соответствующие 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|

Опять же, я не достаточно опытен в tcsh, чтобы предложить хорошее решение, но я знаю достойное решение в bash :

Используйте массивы для построения командных строк.

В bash ваш скрипт будет выглядеть так:

#!/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/"

Я внес несколько изменений здесь. Вы присвоили $3 OPT2, но затем перебрали все аргументы (по сути, именно это и сделает while ($1 != '') ... shift), но без использования этих аргументов в цикле, что не имеет смысла - второй аргумент для скрипт фактически игнорируется, но третий аргумент используется как опция. Учитывая фрагмент Python, я собираюсь предположить, что только первый аргумент является идентификатором, а остальные являются опциями для wget.

Теперь, используя массив, подобный так:

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

Позволяет нам расширяться до каждого отдельного слова в массиве, не рискуя разбить поле или генерировать имя файла, используя "${OPT[@]}" в bash:

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

Каждый аргумент прекрасно сохраняется.

1
ответ дан 23 May 2018 в 14:54

Другие вопросы по тегам:

Похожие вопросы: