Я понимаю, что это не то, о чем спрашивал OP, а lynx, текстовый браузер является более простым вариантом, например:
pages=($(lynx -dump -hiddenlinks=listonly $1 | grep EpisodeDownload | awk "{print $2}"))
приведенный выше пример извлечения URL-адресов подкастов с определенного сайта.
Ошибка возникает, когда $3
заменяется пустой строкой в
for (( trial=1 ; trial<=$3 ; ++trial ))
Bash поддерживает for ((.. ))
даже в режиме POSIX, так что это само по себе не является проблемой. В данном конкретном случае проблема заключается в расширении ${!#}
, используемом при вызове функции. Его можно разобрать двумя способами.
В стандартной оболочке это операция удаления префикса -${var#word}
, применяемая к специальному параметру !
с пустой строкой для удаления. Удаление пустой строки ничего не дает, но для примера мы могли бы удалить один символ:
$ dash -c 'sleep 123 & echo $! ${!#?};'
27920 7920
Но в Bash ${!#}
воспринимается как косвенное расширение ${!var}
, использующее $#
как "указатель", дающий последний позиционный параметр.
Bash поддерживает непрямое расширение даже в режиме POSIX, но здесь он обрабатывает этот крайний случай более стандартным -соответствующим образом.Документация на самом деле говорит об этом:
- While variable indirection is available, it may not be applied to the ‘#’ and ‘?’ special parameters.
Теперь, поскольку $!
содержит PID последнего фонового процесса, но скрипт не запускает его, стандартное значение дает просто пустую строку. Приводя к возможной ошибке.
Вы также можете использовать "${@: -1}"
для получения последнего позиционного параметра в Bash. Это тоже не стандарт, но работает в режиме POSIX.
В любом случае, если вы хотите использовать не -функции POSIX, поддерживаемые Bash, такие как ((.. ))
, ${!var}
, ${var:n:m}
, запустите bash
, а не sh
. Вы избавите себя от проблем с несовместимостью.
Вы запускаете сценарий с sh
в качестве интерпретатора, но используете функции bash
. Даже если предположить, что sh
указывает на bash
, вы все равно не сможете этого сделать, поскольку bash
отключает многие из своих пользовательских функций, когда его просят запустить как sh
.
Одним из решений является правильное объявление скрипта. Вы используете функции bash
, поэтому объявите их скриптом bash
.
#!/bin/bash
Или, если вам нужно продолжить с зависимостью от env
,
#!/usr/bin/env bash
Другим вариантом является удаление специальногоbash
-синтаксиса.
В любом случае не забудьте убедиться, что переменные при их использовании заключены в двойные -кавычки. Например, если одна из ваших переменных без кавычек (, включая параметры скрипта ), содержит пробел, она будет разделена оболочкой на два или более слов.