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 ответ

Решение

Я не знаком с 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"

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

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

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