Использование aria2 вместо curl прерывает конкатенацию строк

Это не работает на многих уровнях. В основном, bash не очень хорош для многопоточного программирования. Но если вы собираетесь сделать это таким образом, вы должны осознать две вещи: (1) для того, чтобы ваш «поток» чтения ключей работал, он должен иметь монопольный доступ к tty. (2) Когда вы помещаете процесс в фоновый режим, он естественным образом копирует stdin из tty текущего процесса. (3) Обычно оболочка обнаруживает это и останавливает фоновый процесс.

Только процессы переднего плана могут читать из или, если пользователь так указывает с помощью stty tostop, записывать в терминал. Фоновые процессы, которые пытаются читать (записывать, когда действует stty tostop) терминала, посылают сигнал SIGTTIN (SIGTTOU) драйвером терминала ядра, который, если он не пойман, приостанавливает процесс.

Вы можете увидеть это здесь:

otheus@otheus-VirtualBox ~ $ ( while true; read x; do echo $x; done; ) &
[1] 2841
otheus@otheus-VirtualBox ~ $ 

[1]+  Stopped                 ( while true; read x; do
    echo $x;
done )

Итак, процесс чтения tty должен быть на переднем плане. Фон может выполнять «работу», но сначала убедитесь, что вы закрыли stdin: <& -

Чтобы остановить «рабочий» процесс, вам нужно знать его pid. Для этого вам нужно включить управление заданиями в скрипте (по умолчанию оно отключено). set -m делает это. Запустите его и убейте % - после нажатия клавиши. Вы можете убедиться, что цикл нажатия клавиш завершается, когда это делает рабочий. Вы выполняете свой поток ключевого монитора:

start_worker &

while jobs %- &>/dev/null; do 
   read -n 1 -s -t 1 key
   # test key
   if [[ $key == q ]]; then
      kill -1 %-
      break
   fi
fi
wait

Условие while проверяет, выполняется ли / распознано ли задание. После его завершения задания вернут false, и цикл завершится. Команда чтения теперь дополнительно истекает через 1 секунду. Наконец, после выхода из цикла подождите, чтобы убедиться, что задание «очищено».(Если у вас есть другие выполняемые задания, это будет зависеть здесь.)

Другое дело: то, что вы пытаетесь выполнить, по своей сути опасно. Смешивание корневого доступа и сценариев bash опасно . Здесь есть несколько тем, которые следует затронуть, например, что происходит, когда пользователь нажимает Control-C или Ctl-Z.

Наконец, я даже не уверен, что вы можете смешивать рабочий поток с su , как в вашем примере. Когда su запускается, он изменяет текущий tty на root, не позволяя вашему рабочему потоку выводить на него данные.

1
25.07.2018, 11:41
2 ответа

Последнее не работает, потому что -execне зависит от -printf.

Но вы можете использовать xargsвместо-exec:

find. -type f -printf '%P\n' \
    | xargs -I{} aria2c -x 16 -s 1 "https://web.archive.org/save/https://{}"

Вы также можете позволить нескольким экземплярам aria2cработать параллельно с xargs -P <num>.


Еще лучше было бы создать файловый дескриптор из findв качестве входных данных для aria2вместо использования конвейеров и xargs.

aria2c -x 16 -s 1 -i <(find. -type f -printf 'https://web.archive.org/save/https://%P\n')
1
27.01.2020, 23:43

Добавление -printfприведет только к выводу, но не изменит то, чем заменяется {}.

Кажется, curlнемного умнее (или, наоборот, применяет больше магии ), чем aria2, и удаляет ./. Начальное значение ./в найденном пути исходит из того факта, что findбудет создавать пути относительно каталога верхнего уровня, с которого вы начинаете поиск.

Для вызова aria2или curlс URL-адресом, который не содержит начального ./, используйте

find. -type f -exec sh -c '
    for pathname do
        pathname=${pathname#./}
        aria2c -x 16 -s 1 "https://web.archive.org/save/https://$pathname"
    done' sh {} +

Это вызовет дочернюю оболочку с кучей найденных путей. Дочерняя оболочка будет перебирать их и удалять начальный ./с помощью стандартного раскрытия параметра перед вызовом, в данном случае aria2c.

В целом:

topdir=/some/directory/path  # no '/' at the end

find "$topdir" -type f -exec sh -c '
    topdir="$1"; shift
    for pathname do
        pathname=${pathname#$topdir/}
        aria2c -x 16 -s 1 "https://web.archive.org/save/https://$pathname"
    done' sh "$topdir" {} +

Связанные:

0
27.01.2020, 23:43

Теги

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