How to mark an array in POSIX sh?
While replacing external commands in a shell script, I used an array to get rid of awk's NF
.
Now, since I moved from bash to POSIX sh, I cannot get the array marked right:
#!/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
I'm using OpenBSD's, sh and it has exactly the same size as the ksh.
Changing above to /bin/sh
, it seems that the following doesn't work:
set -A "$RANGE"
set -- "$RANGE"
How could I realise the above script in /bin/sh
? (Note that it works fine if you invoke bash with --posix
, that's not what I look for.)
Arrays are not part of the POSIX sh
specification.
There are various other ways to find the last item. A couple of possibilities:
#!/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"
or:
#!/bin/sh
export RANGE="0 1 4 6 8 16 24 46 53"
LAST_ITEM="${RANGE##* }"
echo "Last element(replace NF): $LAST_ITEM"
You can use the following project from Github, which implements a POSIX-compliant array, which works in all shells I tried: https://github.com/makefu/array
It is not very convenient to use, but I found it to work well for my purposes.
The following code works for me using the Heirloom 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\): \$$#"
Note that IFS
is set to a space and there are no double quotes around $RANGE
.
精彩评论