Скрипт не работает с shebang "/usr/bin/env sh", но работает с "/usr/bin/env bash", хотя sh указывает на bash?

Я понимаю, что это не то, о чем спрашивал OP, а lynx, текстовый браузер является более простым вариантом, например:

pages=($(lynx -dump -hiddenlinks=listonly $1 | grep EpisodeDownload | awk "{print $2}"))

приведенный выше пример извлечения URL-адресов подкастов с определенного сайта.

3
08.10.2021, 15:22
2 ответа

Ошибка возникает, когда $3заменяется пустой строкой в ​​

for (( trial=1 ; trial<=$3 ; ++trial ))

Bash поддерживает for ((.. ))даже в режиме POSIX, так что это само по себе не является проблемой. В данном конкретном случае проблема заключается в расширении ${!#}, используемом при вызове функции. Его можно разобрать двумя способами.

В стандартной оболочке это операция удаления префикса -${var#word}, применяемая к специальному параметру !с пустой строкой для удаления. Удаление пустой строки ничего не дает, но для примера мы могли бы удалить один символ:

$ dash -c 'sleep 123 & echo $! ${!#?};'
27920 7920

Но в Bash ${!#}воспринимается как косвенное расширение ${!var}, использующее $#как "указатель", дающий последний позиционный параметр.

Bash поддерживает непрямое расширение даже в режиме POSIX, но здесь он обрабатывает этот крайний случай более стандартным -соответствующим образом.Документация на самом деле говорит об этом:

  1. 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. Вы избавите себя от проблем с несовместимостью.

9
08.10.2021, 16:21

Вы запускаете сценарий с shв качестве интерпретатора, но используете функции bash. Даже если предположить, что shуказывает на bash, вы все равно не сможете этого сделать, поскольку bashотключает многие из своих пользовательских функций, когда его просят запустить как sh.

Одним из решений является правильное объявление скрипта. Вы используете функции bash, поэтому объявите их скриптом bash.

#!/bin/bash

Или, если вам нужно продолжить с зависимостью от env,

#!/usr/bin/env bash

Другим вариантом является удаление специальногоbash-синтаксиса.

В любом случае не забудьте убедиться, что переменные при их использовании заключены в двойные -кавычки. Например, если одна из ваших переменных без кавычек (, включая параметры скрипта ), содержит пробел, она будет разделена оболочкой на два или более слов.

20
08.10.2021, 15:49

Теги

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