Busybox sh не будет выполнять скрипт bash - PullRequest
0 голосов
/ 13 июня 2018

У меня есть небольшой скрипт с именем test.sh, который печатает значение на основе указанного индекса.

#!/bin/sh
days_in_month=(0 31 28 31 30 31 30 31 31 30 31 30 31)
echo "${days_in_month[$1]}"

Приведенный выше код работает нормально, если я выполняю с использованием bash.

$ bash test.sh 1
31

Но мне нужно выполнить тот же сценарий на встроенной плате, в которой sh является частью пакета Busybox.Когда я запускаю команду на этой плате, она выдает ошибку.

$ sh test.sh
test.sh: line 2: syntax error: unexpected "("

Я наблюдаю ту же ошибку, когда я использую dash вместо bash в системе Ubuntu.

$ dash test.sh
test.sh: line 2: syntax error: unexpected "("

Можно ли как-нибудь изменить код, чтобы Busybox sh работал без ошибок?

Ответы [ 2 ]

0 голосов
/ 13 июня 2018

/bin/sh в общем случае не поддерживает массивы, кроме списка позиционных параметров.

Давайте использовать это:

#/bin/sh

pos=$1

if [ "$pos" -lt 1 ] || [ "$pos" -gt 12 ]; then
    printf 'No such month: %s\n' "$pos" >&2
    exit 1
fi

set -- 31 28 31 30 31 30 31 31 30 31 30 31
shift "$(( pos - 1 ))"
printf '%s\n' "$1"

Сначала выбирается число из командной строкии помещает это в pos.Затем он устанавливает позиционные параметры, которые вы имели в вашем массиве.Сдвигая pos - 1 элементов из этого массива, мы получаем искомый номер в $1.

Это будет работать, даже если список содержит строки с пробелами в них, например, в

#/bin/sh

pos=$1

if [ "$pos" -lt 1 ] || [ "$pos" -gt 12 ]; then
    printf 'No such month: %s\n' "$pos" >&2
    exit 1
fi

set -- "thirty one" "twenty eight" "thirty one" etc.
shift "$(( pos - 1 ))"
printf '%s\n' "$1"

Другой способ решить эту проблему с помощью /bin/sh - с помощью оператора case:

case $1 in
    2)
        echo 28 ;;
    4|6|9|11)
        echo 30 ;;
    1|3|5|7|8|10|12)
        echo 31 ;;
    *)
        print 'No such month: %s\n' "$1" >&2
        exit 1
esac
0 голосов
/ 13 июня 2018

Оба busybox 'sh (то есть ash) и dash do not поддерживают массивы.

Вы можете написать большой оператор if-else или switch case, илииспользуйте следующий трюк.Мы моделируем массив, используя одну строку с пробелами в качестве разделителей.

cut -d ' ' -f "$1" <<< "31 28 31 30 31 30 31 31 30 31 30 31"

или даже более переносимый:

echo "31 28 31 30 31 30 31 31 30 31 30 31" | cut -d ' ' -f "$1"

Другой обходной путь - использование позиционных параметров скрипта, как показано в этот ответ .

...