Próbuję użyć tablic w powłoce Bourne'a ( /bin/sh
). Odkryłem, że sposobem na zainicjowanie elementów tablicy jest:
arr=(1 2 3)
Ale napotyka błąd:
syntax error at line 8: `arr=' unexpected
Teraz post, w którym znalazłem tę składnię, mówi, że jest bash
, ale nie mogłem znaleźć żadnej osobnej składni dla powłoki Bourne'a. Czy składnia też jest taka sama /bin/sh
?
shell
array
bourne-shell
SubhasisM
źródło
źródło
Odpowiedzi:
/bin/sh
w dzisiejszych czasach prawie nigdy nie jest powłoką Bourne'a (nawet Solaris, który był jednym z ostatnich głównych systemów w tym zakresie, teraz przeszedł na POSIX sh dla swojego / bin / sh w Solaris 11)./bin/sh
był pocisk Thompson na początku lat 70. Powłoka Bourne zastąpiła ją w Unix V7 w 1979 r./bin/sh
od wielu lat jest powłoką Bourne'a (lub powłoką Almquist, bezpłatna reimplementacja BSD).Obecnie
/bin/sh
częściej jest tłumaczem lub innymsh
językiem POSIX , który sam jest oparty na podzbiorze języka ksh88 (i nadzbiór języka powłoki Bourne'a z pewnymi niezgodnościami).Powłoka Bourne'a lub specyfikacja języka sh POSIX nie obsługują tablic. Albo raczej, że mają tylko jedną tablicę: parametry pozycyjne (
$1
,$2
,$@
, więc na jednej tablicy funkcji, jak również).ksh88 miał tablice, które ustawiłeś
set -A
, ale nie zostały one określone w POSIX sh, ponieważ składnia jest niewygodna i niezbyt użyteczna.Inne pociski z tablicy / list zmiennych są:
csh
/tcsh
,rc
,es
,bash
(które najczęściej kopiowane składnię KSH sposób ksh93)yash
,zsh
,fish
każdy z innym składni (rc
powłoce raz do następcą Unix,fish
izsh
jest najbardziej zgodne te) ...Standardowo
sh
(działa również w nowoczesnych wersjach powłoki Bourne'a):(zwróć uwagę, że w powłoce Bourne'a i ksh88
$IFS
musi zawierać znak spacji,"$@"
aby działał poprawnie (błąd), aw powłoce Bourne'a nie możesz uzyskać dostępu do elementów powyżej$9
(${10}
nie będzie działać, nadal możesz to zrobićshift 1; echo "$9"
lub zapętlić im)).źródło
"${@:2:4}"
. Oczywiście, widzę podobieństwa , ale nie uważam parametrów pozycyjnych za tablicę per se."$@"
działa jak tablicy (jak tablicecsh
,rc
,zsh
,fish
,yash
...), to bardziej Korn / bash „tablice”, które nie są naprawdę, ale niektóre tablice forma tablic asocjacyjnych z kluczami ograniczonymi do dodatnich liczb całkowitych (mają również indeksy zaczynające się od 0 zamiast 1, jak we wszystkich innych powłokach z tablicami i „$ @”). Powłoki obsługujące krojenie mogą wycinać $ @ tak samo (z ksh93 / bash niezręcznie dodając 0 $ do parametrów pozycyjnych podczas wycinania „$ @”).W zwykłej powłoce Bourne'a nie ma tablic. Możesz użyć następującego sposobu, aby utworzyć tablicę i przejść przez nią:
Bez względu na to, w jaki sposób użyjesz tablic
sh
, zawsze będzie to uciążliwe. Rozważyć użycie innego języka, takich jakPython
lubPerl
, jeśli można, chyba że są skazani na bardzo ograniczonej platformie lub chcesz się czegoś nauczyć.źródło
$(...)
składni. Musisz więc mieć skorupę Bourne'a. Czy korzystasz z Solaris 10 lub wcześniej? Możliwe, że nie będziesz mieć żadnego zseq
nich. W Solarisie 10 i wcześniejszych chcesz, aby / usr / xpg4 / bin / sh miał standardsh
zamiast powłoki Bourne'a. Korzystanie zseq
tego sposobu również nie jest zbyt dobre.seq
ten sposób nie jest dobre?$(...)
nad`
, ale OP/bin/sh
jest prawdopodobnie Bourne shell, a nie powłoki POSIX. Pozaseq
tym, że nie jest standardową komendą, robienie$(seq 100)
oznacza przechowywanie całego wyniku w pamięci, a to oznacza, że zależy to od bieżącej wartości $ IFS zawierającej znak nowej linii i nie zawierającej cyfr. Najlepiej używaći=1; while [ "$i" -le 100 ]; ...; i=$(($i + 1)); done
(choć nie działałoby to również w powłoce Bourne'a)./bin/sh
składni, sprawia, że ludzie myślą, że można użyć niewłaściwego#!/bin/sh
shebang, a następnie łamie skrypty, gdy inni próbują ich użyć. Radzimy nie zamieszczać tego rodzaju przynęty na płomienie. :)Jak powiedzieli inni, Bourne Shell nie ma prawdziwych tablic.
Jednak w zależności od tego, co musisz zrobić, powinny wystarczyć ciągi rozdzielane:
Jeśli typowe ograniczniki (spacja, tabulator i znak nowej linii) nie wystarczą, możesz ustawić
IFS
dowolny ogranicznik przed pętlą.A jeśli musisz zbudować tablicę programowo, możesz po prostu utworzyć łańcuch rozdzielany ograniczeniami.
źródło
split+glob
operator).Sposób, aby symulować tablice w desce rozdzielczej (może być dostosowany do dowolnej liczby wymiarów tablicy): (Należy pamiętać, że korzystanie z
seq
polecenia wymagaIFS
. Jest ustawiona na „” (spacja = wartość domyślna) można używaćwhile ... do ...
lubdo ... while ...
zamiast tego pętle, aby tego uniknąć (ja byłemseq
w zakresie lepszej ilustracji tego, co robi kod).)źródło
local
jest obsługiwany przez obabash
idash
nie jest POSIX.seq
nie jest także poleceniem POSIX. Prawdopodobnie powinieneś wspomnieć, że twój kod przyjmuje pewne założenia dotyczące bieżącej wartości $ IFS (jeśli unikniesz używaniaseq
i cytowania zmiennych, można tego uniknąć)