Как пометить массив в POSIX sh? - PullRequest
13 голосов
/ 28 июня 2011

При замене внешних команд в сценарии оболочки я использовал массив, чтобы избавиться от NF.

в awk. Теперь, поскольку я перешел с bash на POSIX sh, я не могу получить массив, помеченный правильно:

#!/bin/bash
export RANGE="0 1 4 6 8 16 24 46 53"
RANGE=($RANGE)
echo arrayelements: $((${#RANGE[@]}))
LAST=$((${#RANGE[@]}-1))
echo "Last element(replace NF): ${RANGE[$LAST]}"

# ./foo
arrayelements: 9
Last element(replace NF): 53

Я использую OpenBSD, sh, и он имеет точно такой же размер, как и ksh.При изменении выше на /bin/sh кажется, что следующее не работает:

set -A "$RANGE"
set -- "$RANGE"

Как я мог реализовать вышеописанный скрипт в /bin/sh?(Обратите внимание, что он работает нормально, если вы запускаете bash с --posix, это не то, что я ищу.)

Ответы [ 3 ]

21 голосов
/ 28 июня 2011

Массивы не являются частью спецификации POSIX sh .

Существуют различные другие способы найти последний элемент.Пара возможностей:

#!/bin/sh
export RANGE="0 1 4 6 8 16 24 46 53"
for LAST_ITEM in $RANGE; do true; done
echo "Last element(replace NF): $LAST_ITEM"

или:

#!/bin/sh
export RANGE="0 1 4 6 8 16 24 46 53"
LAST_ITEM="${RANGE##* }"
echo "Last element(replace NF): $LAST_ITEM"
2 голосов
/ 05 апреля 2013

Вы можете использовать следующий проект от Github, который реализует POSIX-совместимый массив, который работает во всех оболочках, которые я пробовал: https://github.com/makefu/array

Это не очень удобно для использования, но я нашел, что оно хорошо работает для моих целей.

1 голос
/ 28 июня 2011

Следующий код работает для меня, используя Семейная реликвия Bourne Shell :

#!/usr/local/bin/bournesh
# cf. Heirloom Bourne Shell, 
#     http://freshmeat.net/projects/bournesh/
#     http://www.in-ulm.de/~mascheck/bourne/

# use a caret as a pipe symbol to make sure it's a Bourne shell
# cf. http://mywiki.wooledge.org/BourneShell
ls ^ cat 1>/dev/null 2>&1 || 
   { echo 'No true Bourne shell! ... exiting ...'; exit 1; }

IFS=' '
unset RANGE
RANGE="0 1 4 6 8 16 24 46 53"
export IFS RANGE
set -- $RANGE
echo arrayelements: $#
LAST=$#
eval echo "Last element\(replace NF\): \$$#"

Обратите внимание, что IFS установлен в пробел, и вокруг $RANGE нет двойных кавычек.

...