Estou tentando usar matrizes no shell Bourne ( /bin/sh
). Eu descobri que a maneira de inicializar os elementos da matriz é:
arr=(1 2 3)
Mas está encontrando um erro:
syntax error at line 8: `arr=' unexpected
Agora, o post onde encontrei essa sintaxe diz que é bash
, mas não consegui encontrar nenhuma sintaxe separada para o shell Bourne. A sintaxe também é a mesma /bin/sh
?
shell
array
bourne-shell
SubhasisM
fonte
fonte
Respostas:
/bin/sh
hoje em dia quase nunca é um shell Bourne em nenhum sistema (mesmo o Solaris, que foi um dos últimos grandes sistemas a incluí-lo, agora mudou para um POSIX sh para seu / bin / sh no Solaris 11)./bin/sh
foi a concha de Thompson no início dos anos 70. O shell Bourne o substituiu no Unix V7 em 1979./bin/sh
foi o shell Bourne por muitos anos depois (ou o shell Almquist, uma reimplementação gratuita nos BSDs).Atualmente,
/bin/sh
é mais comum um intérprete ou outro para ash
linguagem POSIX , que se baseia em um subconjunto da linguagem ksh88 (e um superconjunto da linguagem shell Bourne com algumas incompatibilidades).O shell Bourne ou a especificação de linguagem POSIX sh não suportam matrizes. Ou melhor, eles têm apenas uma matriz: os parâmetros de posição (
$1
,$2
,$@
, de modo que uma matriz por função, bem).O ksh88 tinha matrizes com as quais você configurou
set -A
, mas isso não foi especificado no sh POSIX, pois a sintaxe é estranha e pouco utilizável.Outros conchas com variáveis de matriz / listas incluem:
csh
/tcsh
,rc
,es
,bash
(que na maior parte copiado a sintaxe ksh o caminho ksh93),yash
,zsh
,fish
cada um com uma sintaxe diferente (rc
a casca de uma vez a-ser sucessor do Unix,fish
ezsh
ser o mais consistente uns)...No padrão
sh
(também funciona nas versões modernas do shell Bourne):(observe que no shell Bourne e no ksh88,
$IFS
deve conter o caractere de espaço para"$@"
funcionar corretamente (um bug) e, no shell Bourne, você não pode acessar os elementos acima$9
(${10}
não funcionará, você ainda pode fazershift 1; echo "$9"
ou fazer um loop) eles)).fonte
"${@:2:4}"
. Certamente, vejo as semelhanças , mas não considero os parâmetros posicionais como uma matriz em si."$@"
age como um array (como as matrizes decsh
,rc
,zsh
,fish
,yash
...), é mais da Korn / bash "matrizes" que não são realmente matrizes, mas alguns forma de matrizes associativas com chaves limitadas a números inteiros positivos (eles também têm índices começando em 0 em vez de 1 como em todos os outros shells com matrizes e "$ @"). Os shells que têm suporte para fatiar podem fatiar $ @ da mesma forma (com ksh93 / bash adicionando desajeitadamente $ 0 aos parâmetros posicionais ao fatiar "$ @").Não há matrizes no shell Bourne simples. Você pode usar a seguinte maneira de criar uma matriz e atravessá-la:
Independentemente da maneira de usar as matrizes
sh
, você a escolherá sempre será complicado. Considere usar um idioma diferente, comoPython
ouPerl
se você puder, a menos que esteja preso a uma plataforma muito limitada ou queira aprender alguma coisa.fonte
$(...)
sintaxe. Então você deve realmente ter o shell Bourne. Você está no Solaris 10 ou antes? Provavelmente, você também não teráseq
. No Solaris 10 e versões anteriores, você deseja que / usr / xpg4 / bin / sh tenha um padrão emsh
vez de um shell Bourne. Usarseq
esse caminho também não é muito bom.seq
dessa maneira não é bom?$(...)
mais`
, mas o OP de/bin/sh
é provavelmente um shell Bourne, não é um shell POSIX. Além deseq
não ser um comando padrão, fazer$(seq 100)
significa armazenar toda a saída na memória, e isso significa que depende do valor atual de $ IFS que contém nova linha e não contém dígitos. Melhor usari=1; while [ "$i" -le 100 ]; ...; i=$(($i + 1)); done
(embora isso também não funcione no shell Bourne)./bin/sh
sintaxe portátil mais tarde, tende a fazer as pessoas pensarem que não há problema em usar o#!/bin/sh
shebang errado e depois interrompe seus scripts quando outras pessoas tentam usá-los. Você seria aconselhado a não postar esse tipo de flama. :)Como os outros disseram, o Bourne Shell não possui matrizes verdadeiras .
No entanto, dependendo do que você precisa fazer, cadeias delimitadas devem ser suficientes:
Se os delimitadores típicos (espaço, tabulação e nova linha) não
IFS
forem suficientes, você poderá definir o delimitador que desejar antes do loop.E se você precisar criar a matriz programaticamente, poderá criar uma cadeia delimitada.
fonte
split+glob
operador).Uma forma de matrizes de simular em traço (ele pode ser adaptado para qualquer número de dimensões de uma matriz): (Por favor, note que o uso do
seq
comando requer queIFS
. É definido como '' (SPACE = o valor padrão) Você pode usarwhile ... do ...
oudo ... while ...
loops para evitar isso (eu mantiveseq
o escopo de uma ilustração melhor do que o código faz).)fonte
local
é suportado por ambosbash
edash
, não é POSIX.seq
também não é um comando POSIX. Você provavelmente deve mencionar que o código faz algumas suposições sobre o valor atual de US $ IFS (se você evitar usarseq
e citar suas variáveis, ele pode ser evitado)