Luettuani ilkkachun vastauksen tähän kysymykseen opin kuulemaan declare
(argumentilla -n
) kuori on rakennettu.
help declare
tuo:
Aseta muuttujien arvot ja määritteet.
Ilmoita muuttujat ja anna heille määritteet. Jos NAME-nimiä ei anneta, näytä kaikkien muuttujien attribuutit ja arvot.
-n … tee NAME viitteeksi muuttujalle, joka on nimetty sen arvolla
I pyydä yleistä selitystä esimerkillä declare
, koska en ymmärrä man
. Tiedän mikä on muuttuja ja sen laajentaminen, mutta kaipaan silti man
-tietoa declare
(muuttuja-määritteessä?).
Ehkä haluat selittää tämän vastauksen ilkkachun koodin perusteella:
#!/bin/bash function read_and_verify { read -p "Please enter value for "$1": " tmp1 read -p "Please repeat the value to verify: " tmp2 if [ "$tmp1" != "$tmp2" ]; then echo "Values unmatched. Please try again."; return 2 else declare -n ref="$1" ref=$tmp1 fi }
kommentit
- Liittyvät: unix.stackexchange.com/questions/522366/…
Vastaus
Useimmissa tapauksissa riittää, että implisiittinen ilmoitus on bash
asdf="some text"
Mutta joskus haluat muuttujan arvon olevan vain kokonaisluku (joten jos se muuttuisi myöhemmin, jopa automaattisesti, se voidaan muuttaa vain kokonaisluku, oletusarvoisesti nolla joissakin tapauksissa) ja voi käyttää:
declare -i num
tai
declare -i num=15
Joskus haluat taulukoita, ja sitten tarvitset declare
declare -a asdf # indexed type
tai
Löydät hyviä taulukoita koskevia oppaita bash
-sivulta, kun selaat Internetiä hakumerkkijonolla” bash array tutorial ”(ilman lainausmerkkejä). esimerkki
linuxconfig.org/how-to-use-arrays-in-bash-script
Luulen, että nämä ovat yleisimpiä tapauksia, kun ilmoitat muuttujia.
Huomaa myös, että
- funktiossa
declare
tekee muuttujasta paikallisen (funktiossa) -
ilman nimeä, siinä luetellaan kaikki muuttujat (aktiivisessa kuoressa)
declare
Lopuksi saat lyhyen yhteenvedon komentotulkin sisäisen komennon declare
ominaisuuksista bash
komennolla
help declare
Kommentit
- Hei OP: lta! Mielestäni vastauksesi on loistava, ja minä olen myöntänyt sen ja kiitän teitä tästä mielestäni hyvin didaktisesta vastauksesta. Olen juuri ehdottanut pientä muokkausta, joka nöyrän mielestäni tekee siitä entistä helpomman ja helpommin tulokkaiden luettavissa; käy läpi tämä ehdotus.
- Huomasin juuri, että
user:muru
äänesti hylkäämään muokkauksen. tiedä, että minä ja muru olemme ” törmänneet ” useita kertoja tämän verkkosivuston eri osioihin, ja oletan, että hänen hylkäämisensä ei ole ’ tavoite ja on todella haitallinen, toisin kuin muokkausehdotussivulla esitetyt suorat muutokset: unix.stackexchange.com/review/suggested -edits / 325749 - @JohnDoea, huomasin, että myös toinen käyttäjä on hylännyt muokkauksesi. Mielestäni jotkut muokkauksistasi ovat hyviä, mutta jotkut niistä muuttavat viestin aikeistani, joten en halua niitä. Voin muokata vastausta sisällyttämään mielestäni hyvät muokkaukset.
- kiitos; kuten luultavasti tiedät, muokkausten hylkääminen on tavallista yleisempää SE: ssä kuin niiden hyväksyminen (jopa osittain); kiitos, kun kerroit minulle, että toinen käyttäjä hylkäsi muokkauksen (en nähnyt sitä ennen rehellisesti) ja harkitsit lisätä ainakin joitain muokkauksiani vastaukseesi; Kunnioitan tätä kovasti,
vastaus
Tulos help declare
on melko suppea. Selkeämmän selityksen löydät kohdista man bash
tai info bash
– jälkimmäinen on lähde seuraavalle.
Ensinnäkin joitain määritelmiä. Tietoja -muuttujista ja määritteistä :
parametri on yhteisö, joka tallentaa arvot. … muuttuja on parametri, jota merkitään
name
. Muuttujalla on arvo ja nolla tai enemmän määritteitä . Attribuutit määritetäändeclare
sisäänrakennetulla komennolla …
Ja declare
sisäänrakennetusta :
declare
declare [-aAfFgilnrtux] [-p] [name[=value] …]
Ilmoita muuttujat ja anna heille määritteet. Jos nimiä ei anneta, näytä sen sijaan muuttujien arvot.
…
-n
Anna jokaiselle nimi nameref -attribuutti, mikä tekee siitä nimiviitteen toiseen muuttujaan. Tuo muuttuja määritetään nimi -arvolla. Kaikki nimi -viittaukset, -määritykset ja attribuuttimuutokset lukuun ottamatta niitä, jotka käyttävät tai muuttavat itse-n
-attribuuttia, suoritetaan muuttujalle, johon viittaa nimi : n arvo. …
Huomaa, että nimiviite -muuttujat ovat käytettävissä vain Bash 4.3: ssa tai uudemmassa 1 .
Lisäksi, jos haluat käyttää hyödyllistä johdantoa declare
-muuttujaan ja muuttujan määritteisiin Bashissa, haluaisin osoittaa sinulle tämän vastaus ” Mitä declare name
ja declare -g
tekevät? ” (joka kuitenkin keskittyy pääasiassa muuttujiin ”).
Pohjimmiltaan 2 , declare name=[value]
vastaa luultavasti tuntemaasi tehtävää name=[value]
. Molemmissa tapauksissa name
on annettu nolla arvo, jos value
puuttuu.
Huomaa, että hieman erilainen declare name
ei sen sijaan aseta muuttuja name
3 :
$ declare name ## With the -p option, declare is used to display ## attributes and values of variables $ declare -p name declare -- name ## "name" exists ## Parameter expansion can be used to reveal if a variable is set: ## "isunset" is substituted to "name" only if unset $ echo "${name-isunset}" isunset
Muuttuja name
voi siis olla:
- ilmoitettu ja poista
declare name
jälkeen; - ilmoitettu ja aseta kanssa null arvona
name=
taideclare name=
jälkeen; - ilmoitettu , set ja ei nolla -arvolla
name=value
tai .
Yleisemmin declare [options] name=value
- luo muuttujan
name
– joka on parametri, jolla on nimi, joka puolestaan on vain osa muistista, jota voit käyttää tietojen tallentamiseen 4 ; - määrittää arvo
value
siihen; - asettaa valinnaisesti
name
”-attribuutit, jotka määrittelevät molemmat arvotyypit voi tallentaa (ei tarkalleen ottaen tyypin suhteen, koska Bashin kieltä ei ole kirjoitettu) ja tapoja, joilla sitä voidaan käsitellä.
Attribuutit ovat luultavasti helpompi selittää esimerkillä: declare -i name
-toiminnon avulla määritetään ” kokonaisluku ” name
, jolloin sitä voidaan pitää kokonaislukuna; lainaamalla käsikirjaa , ” suoritetaan aritmeettinen arviointi, kun muuttujalle annetaan arvo ”:
## Let"s compare an ordinary variable with an integer $ declare var $ declare -i int $ var="1+1" $ int="1+1" $ echo "$var" 1+1 ## The literal "1+1" $ echo "$int" 2 ## The result of the evaluation of 1+1
yllä oleva asia, mitä ilkkachun koodissa tapahtuu, on:
-
Muuttuja nimeltä
ref
ilmoitetaan ” nameref ” -määritesarja ja$1
(ensimmäinen sijainti-argumentti) sisältö on osoitettu se:declare -n ref="$1"
Nimeviitemuuttujan, kuten
ref
on pidettävä toisen muuttujan nimeä, jota ei yleensä tiedetä etukäteen, mahdollisesti siksi, että haluamme sen olevan dynaamisesti määritelty (esim. Koska haluamme käyttää koodia uudelleen ja saada se sovellettu useisiin muuttujiin) ja tarjota kätevä tapa viitata siihen (ja manipuloida). (Ei kuitenkaan ainoa: indirection on vaihtoehto; katso Shell-parametrien laajennus ). -
Milloin muuttujan
tmp1
arvo määritetään ryhmälleref
:ref=$tmp1
Lisämuuttuja, jonka nimi on arvon
ref
, ilmoitetaan implisiittisesti.tmp1
-arvo määritetään myös epäsuorasti implisiittisesti ilmoitetulle muuttujalle tällä nimenomaisella osoituksellaref
.
linkitetyn kysymyksesi yhteydessä , kutsumalla read_and_verify
kuten
read_and_verify domain "Prompt text here..."
julistaa muuttujan domain
ja määritä sille arvon tmp1
arvo (ts. käyttäjän syöte). Se on suunniteltu tarkalleen käyttämään käyttäjän kanssa vuorovaikutuksessa olevaa koodia uudelleen ja käyttämään nameref-muuttujaa. julistaa domain
ja muutama muu muuttuja.
Tarkastelemalla implisiittistä osaa voimme toistaa prosessin vaiheittain:
## Assign a value to the first positional argument $ set -- "domain" ## Declare the same "tmp1" variable as in your code $ tmp1="value for domain" ## Declare a "ref" variable with the nameref attribute set and ## assign the value "domain" to it $ declare -n ref="$1" ## Note that there is no "domain" variable yet $ declare -p domain bash: declare: domain: not found ## Assign a value to "ref" and, indirectly, to the "domain" variable ## that is implicitly declared $ ref=$tmp1 ## Verify that a variable named "domain" now exists, and that ## its value is that of "tmp1" $ declare -p domain declare -- domain="value for domain" ## Verify that "ref" is actually a reference to "domain" $ domain="new value" $ echo "$domain" new value $ declare -p ref declare -n ref="domain" $ echo "$ref" new value
1 Viite: MUUTOS -tiedosto, osio ” 3. Bashin uudet ominaisuudet ”, kohta ” w ”.
Tämä voi olla merkitystä: esimerkiksi CentOS Linux 7.6 (tällä hetkellä uusin versio) toimitetaan Bash 4.2: n mukana.
2 Kuten tavallista sisäänrakennettuja kuorellisia, tyhjentävä ja tiivis selitys on vaikeasti ymmärrettävissä, koska ne suorittavat erilaisia, mahdollisesti heterogeenisiä toimintoja. Keskityn vain määritteiden ilmoittamiseen, määrittämiseen ja asettamiseen, ja harkitsen attribuuttien luetteloimista, laajentamista ja poistamista tämän vastauksen ulkopuolelta.
3 Tämä declare -p
-käyttäytyminen on otettu käyttöön Bash 4.4: ssä. Viite: MUUTOS tiedosto, osio ” 3. Bashin uudet ominaisuudet ”, kohta ” f ”.
Kuten G-Man huomautti kommenteissa, Bash 4.3: ssa declare name; declare -p name
tuottaa virheen. Mutta voit silti tarkistaa, että name
on olemassa declare -p | grep "declare -- name"
.
4 FullBashGuide, Parametrit osoitteessa mywiki.wooledge.org
Kommentit
m vain versiolla 4.3.
declare x
ei ’ t set x
, kun declare x=
tekee. En voinut ’ löytää mitään viittausta väitteelle, jonka mukaan declare -- x
(declare -p x
) tarkoittaa ” ei asetettu ”, kun taas declare -- x=""
tarkoittaa ” set ”; Siksi toin ${parameter-word}
-laajennuksen, vaikka se ei pysty erottamaan ” unset ” ja ” ei ’ ole ”, kuten huomautat. En ’ ole varma, kuinka voin selvittää tämän vastauksessani (häiritsemättä lukijaa asiasta). Vastaa
Yritän yrittää selittää tämän, mutta anna anteeksi, jos en noudata antamaasi esimerkkiä. Yritän mieluummin ohjata sinua omalla, erilaisella lähestymistavallani.
Sanot jo ymmärtävän käsitteitä, kuten ”muuttujat” ja ”niiden laajentaminen”, jne. taustatietoa, joka muuten vaatisi syvempää keskittymistä.
Aloitan siis sanomalla, että korkeintaan basic level, declare
-komento on vain tapa kertoa Bashille, että tarvitset muuttujan arvon (eli arvon, joka saattaa muuttua komentosarjan suorituksen aikana) ja että viittaa kyseiseen arvoon käyttämällä tiettyä nimeä, tarkalleen nimen, jonka ilmoitat itse declare
-komennon vieressä.
Eli:
declare foo="bar"
kertoo Bashille, että olet haluat, että muuttujalle nimeltä foo
on arvo bar
.
Mutta .. pidä hetki .. voimme tee se käyttämättä declare
, emmekö voi. Kuten:
foo="bar"
Erittäin totta.
No , sattuu niin, että yllä oleva yksinkertainen määritys on itse asiassa implisiittinen tapa .. itse asiassa .. ilmoitetaan muuttuja.
( Tapahtuu myös, että yllä oleva on yksi muutamista tavoista muuttaa muuttujan foo
arvoa; se on todellakin suorin, ytimekäs, selvä, suoraviivainen tapa .. mutta se ei ole ainoa tapa .. .. palaan tähän myöhemmin .. ).
Mutta sitten, jos on niin on hyvin mahdollista julistaa ”nimi, joka merkitsee muuttujien arvot” (vain ”muuttuja” tästä lähtien, lyhyyden vuoksi) käyttämättä declare
ollenkaan, miksi haluaisit koskaan käytä tätä loistavaa ”julista” -komentoa?
Vastaus on siinä, että yllä oleva implici t tapa julistaa muuttuja (foo="bar"
), se .. implisiittisesti .. saa Bashin miettimään sitä tyypin muuttujaa, jota käytetään yleisimmin kuoren tyypillisessä käyttöskenaariossa. .
Tällainen tyyppi on merkkijonotyyppi, eli merkkijono, jolla ei ole mitään erityistä merkitystä. Siksi merkkijono on se, mitä saat käyttäessäsi implisiittistä ilmoitusta.
Mutta sinun, ohjelmoijana, on joskus pidettävä mieluummin muuttujaa esimerkiksi numerona .. jolle sinun on tehtävä aritmeettinen operaatioita .. ja käyttämällä implisiittistä ilmoitusta, kuten foo=5+6
ei saa Bashin määrittelemään arvon 11 arvoon foo
saatat odottaa. Se määrittää pikemminkin foo
kolmen merkin sarjan 5
+
6
.
Joten .. tarvitset tavan kertoa Bashille, että foo
pidetään numerona, ei numerona. merkkijono .. ja juuri tästä on hyödyllinen nimenomainen declare
.
Sano vain:
declare -i foo=5+6 # <<- note the "-i" option: it means "integer"
ja Bash tekee mielellään matematiikan puolestasi ja määrittää numeerisen arvon 11 muuttujalle foo
.
Eli: sanomalla declare -i foo
annat muuttujalle foo
attribute olevan kokonaisluku.
Lukujen ilmoittaminen (tarkalleen kokonaisluvut, koska Bash ei edelleenkään ymmärrä desimaaleja, liukulukuja ja kaikkea muuta) voi olla ensimmäinen syy declare
, mutta se ei ole ainoa syy. Kuten olet jo ymmärtänyt, muuttujille voidaan antaa muutama muu attribuutti. Voit esimerkiksi asettaa Bashin tekemään muuttujan arvosta aina ison kirjaimen riippumatta: jos sanot declare -u foo
, sitten siitä, kun sanot foo=bar
Bash määrittää oikeastaan merkkijonon BAR
muuttujalle foo
.
Minkä tahansa näiden attribuuttien antamiseksi muuttujaan täytyy käyttää declare
-komentoa, muuta vaihtoehtoa ei ole.
Nyt yksi muu määritteet, jotka voit antaa kautta declare
on surullisen ”name-ref”, -n
-määritteen. ( Ja nyt aion jatkaa aikaisemmin pidossa olleeni konseptia ).
Name-ref-attribuutti antaa Bash-ohjelmoijille pohjimmiltaan toisen tavan muuttaa arvoa Se antaa tarkemmin epäsuoran tavan tehdä se.
Tässä on miten se toimii:
Sinä declare
muuttuja, jolla on -n
-attribuutti, ja se on erittäin suositeltavaa (vaikkakaan sitä ei vaadita, mutta se tekee asioista yksinkertaisempia), että annat myös arvon tälle muuttujalle samalla declare
-komento. Näin:
declare -n baz="foo"
Tämä kertoo Bashille siitä lähtien päällä, aina kun käytät tai muutat baz
-nimisen muuttujan arvoa, se käyttää tai muuttaa muuttujan nimeltä foo
.
Mikä tarkoittaa sitä, että siitä lähtien yo u voi sanoa jotain baz=10+3
, jotta foo
saa arvon 13.Olettaen tietysti, että foo
ilmoitettiin aiemmin kokonaislukuna (declare -i
), kuten teimme vain minuutti sitten, muuten se saa järjestyksen neljästä merkistä 1
0
+
3
.
Lisäksi: jos muutat foo
-arvoa suoraan, kuten kohdassa foo=15
, näet 15 myös sanomalla echo “${baz}”
. Tämä johtuu siitä, että muuttuja baz
, joka on ilmoitettu foo
-nimeksi, heijastaa aina foo
arvo.
Yllä oleva declare -n
-komento sanotaan ”nimiviitteeksi”, koska se tekee muuttujasta baz
viittaa toisen muuttujan nimeen . Itse asiassa olemme julistaneet, että baz
-arvolla on arvo ”foo”, jota -n
-vaihtoehdon takia Bash käsittelee nimenä toinen muuttuja.
Nyt miksi Maan päällä haluaisit koskaan tehdä sen?
No .. kannattaa sanoa, että tämä ominaisuus on melko vaativiin tarpeisiin.
Itse asiassa niin edistynyt, että kun ohjelmoija kohtaa ongelman, joka todella vaatisi nimen viitteen, se on myös todennäköisesti tällaiseen ongelmaan tulisi pikemminkin puuttua käyttämällä oikeaa ohjelmointikieliä Bashin sijaan.
Yksi näistä edistyneistä tarpeista on esimerkiksi silloin, kun et voi ohjelmoijana tietää kehityksen aikana mitä muuttujaa sinun on käytettävä komentosarjan tietyssä kohdassa, mutta se tunnetaan täysin dynaamisesti ajon aikana. Ja koska ohjelmoija ei voi millään tavalla puuttua ajon aikana, ainoa vaihtoehto on järjestää etukäteen tällainen tilanne komentosarjassa, ja ”nimi-viite” voi olla ainoa toteuttamiskelpoinen tapa. Ajattele esimerkiksi laajennuksia yleisesti tunnetuksi tämän edistyneen tarpeen tarpeeksi. ”Laajennuskelpoisen” ohjelman ohjelmoijan on etukäteen huolehdittava tulevista (ja mahdollisesti kolmannen osapuolen) laajennuksista. Siksi ohjelmoijan on käytettävä tiloja, kuten nimi-viite Bashissa.
Yksi muu edistynyt tarve on, kun joudut käsittelemään valtavaa datamäärää RAM-muistissa ja myös sinun on välitettävä nämä tiedot komentosarjan toimintojen ympärille, jotka myös on muokattava kyseisiä tietoja matkan varrella. Tällöin voit varmasti kopioida nämä tiedot toiminnosta toiseen (kuten Bash tekee, kun teet dest_var="${src_var}"
tai kun kutsut toimintoja kuten myfunc "${src_var}"
), mutta koska tämä data on valtava määrä, se tekisi valtavan RAM-muistin tuhlauksen ja erittäin tehottomasta toiminnasta. Joten Ratkaisu tällaisissa tilanteissa ei ole käyttää kopiota tiedoista, vaan viite kyseisiin tietoihin. Bashissa nimi-viite. Tämä käyttötapaus on todellakin normi kaikilla nykyaikaisilla ohjelmointikielillä, mutta se on melko poikkeuksellinen Bashin suhteen, koska Bash on suunniteltu lähinnä lyhyille yksinkertaisille komentosarjoille, jotka käsittelevät enimmäkseen tiedostoja ja ulkoisia komentoja, joten Bash-komentosarjojen on harvoin läpäistävä valtavia datan määrä toimintojen välillä. Ja kun komentosarjan toimintojen täytyy jakaa jotakin tietoa (käyttää sitä ja muokata sitä), tämä saavutetaan yleensä käyttämällä vain globaalia muuttujaa, mikä on melko normaali Bash-skripteissä yhtä paljon kuin se on hyvin vanhentunut oikeilla ohjelmointikielillä.
Sitten Bashissa voi olla merkittävä nimitiedostojen käyttötapa, ja (ehkä ironista) se liittyy siihen, kun käytät vielä muun tyyppisiä muuttujia:
- muuttujat, jotka on ilmoitettu ”indeksoiduiksi matriiseiksi” (
declare -a
) - muuttujat, jotka on ilmoitettu ”assosiatiivisiksi matriiseiksi” (
declare -A
).
Nämä ovat muuttujatyyppejä, jotka voidaan helpommin (ja myös tehokkaammin) siirtää funktioiden mukana käyttämällä nimeviitteitä normaalin kopioinnin sijaan, vaikka ne eivät kantaisikaan valtavia määriä tietoa.
Jos kaikki nämä esimerkit kuulostavat oudolta ja edelleen käsittämättömiltä, se johtuu vain siitä, että nimiviitteet ovat todellakin edistynyt aihe ja harvinainen tarve tyypilliselle käyttötilanteelle B tuhka.
Voisin kertoa teille tilanteista, joissa olen esimerkiksi löytänyt käyttötarkoituksen Bashin nimiviitteille, mutta toistaiseksi ne ovat olleet enimmäkseen melko ”esoteerisia” ja monimutkaisia tarpeita varten, ja olen pelkää, että jos kuvaan niitä, mutkistan asioita vain sinulle tässä oppimisen vaiheessa. Mainitsen vain vähiten monimutkaisen (ja mahdollisesti ei esoteerisen): arvojen palauttamisen funktioista. Bash ei todellakaan tue tätä toimintoa, joten sain saman käyttämällä nimiviitteitä. Tämä on muuten juuri sitä, mitä esimerkkikoodisi tekee.
Tämän lisäksi pieni henkilökohtainen neuvo, joka todella soveltuu paremmin kommentille, mutta en ole pystynyt tiivistämään sitä tarpeeksi sopia StackExchangen kommenttien rajoihin.
Luulen, että eniten sinun pitäisi tällä hetkellä tehdä vain kokeilla nimiviitteitä käyttämällä yksinkertaisia esimerkkejäni ja ehkä antamaasi esimerkkikoodia huomioimatta tällä hetkellä ”miksi maan päällä” osa ja keskittyminen vain ”miten se toimii” -osaan. Hieman kokeilemalla ”miten” -osa voi uppoutua paremmin mieleesi, jotta ”miksi” -osa tulee sinulle selväksi ajoissa, kun (tai jos) sinulla on todellinen käytännön ongelma, jolle nimi- viite olisi todella hyödyllinen.
Kommentit
- LL3 Pidän vastauksestasi erittäin hyvin ja peukaloin: ymmärrän vihdoin mitä julistaa – – ei ilmoiteta muuttujia vaan ilmoitetaan niiden määritteet kuitenkin valitettavasti menetin jäljen, kun aloin selittää, mikä on nimi-viite. Minulla ei ollut aavistustakaan, mitä se tekee ja miksi käyttää sitä.
- Eli – miksi annettaisiin tämä attribuutti
- @JohnDoea näen. Ehkä voit vain jättää tämän aiheen hetkeksi. On luultavasti liian aikaista ymmärtää tätä käsitettä oppimisen nykyisessä vaiheessa. Joka tapauksessa olen laajentanut vastaustani uusilla esimerkeillä ja myös pienellä henkilökohtaisella lisäyksellä siitä, miten minun pitäisi edetä. Olen myös asettanut vaakasuoria viivoja rajataksesi
declare
-esityksen yleisen selityksen henkilökohtaisesta lisäyksestä annettuun-n
-selitykseen. Olen myös muotoillut hieman uudelleen täällä ja siellä, mutta ei mitään olennaista, joten luulen, että voit lukea-n
osan ja pienen lisäyksen uudelleen. - Kiitos, luulen, että ’ on hyvä, että opin tästä heti, tarvitsen vain ymmärrettävän selityksen ja minun pitäisi lukea koko vastauksesi tänään, minä ’ m täällä.
- Mainitset
foo="bar"
jadeclare foo="bar"
. Haluat ehkä mainita (jos vain alaviitteessä), että kuoritoiminnossadeclare foo="bar"
luo paikallisen muuttujan jafoo="bar"
luo globaali muuttuja.
Vastaa
Yleensä declare
bash
-kuori asettaa (tai poistaa tai näyttää) attribuutit muuttujille. Attribuutti on eräänlainen huomautus, jossa sanotaan ”tämä on nimiviite”, ”tämä on assosiatiivinen taulukko” tai ”tämä muuttuja tulisi aina arvioida kokonaislukuna” tai ”tämä muuttuja on vain luku -merkki eikä voi be re-set ”, tai” tämä muuttuja viedään (ympäristömuuttuja) ”jne.
Sisäänrakennettu typeset
on synonyymi declare
bash
, koska typeset
käytetään muissa kuoreissa (ksh
, mistä se on syntynyt, ja zsh
, esimerkiksi) muuttujien määritteiden asettamiseksi.
Tarkastellaan tarkemmin nimiviittausta esimerkissä kysymys:
Näytettävä kuoritoiminto ja lisätty bitti koodia, joka käyttää sitä:
#!/bin/bash function read_and_verify { read -p "Please enter value for "$1": " tmp1 read -p "Please repeat the value to verify: " tmp2 if [ "$tmp1" != "$tmp2" ]; then echo "Values unmatched. Please try again."; return 2 else declare -n ref="$1" ref=$tmp1 fi } read_and_verify foo printf "The variable "foo" has the value "%s"\n" "$foo"
Tämän suorittaminen:
$ bash script.sh Please enter value for "foo": hello Please repeat the value to verify: hello? Values unmatched. Please try again. The variable "foo" has the value ""
Tämä osoittaa, että muuttujaa foo
ei ole asetettu mihinkään, kun käyttäjä syöttää kaksi erilaista merkkijonot.
Tämä osoittaa, että muuttuja foo
asetetaan merkkijonoksi, jonka käyttäjä kirjoitti kirjoittaessaan saman merkkijonon kahdesti .
Tapa, jolla $foo
saa arvon hello
komentosarjan pääosassa, seuraa seuraavia rivejä shell-toiminnossa:
declare -n ref="$1" ref=$tmp1
missä $tmp1
on merkkijono hello
ja $1
on merkkijono foo
välitetty funktion komentoriville komentosarja.
Huomaa, että muuttuja ref
ilmoitetaan nimellä declare -n
nimeviitemuuttujana ja että arvo foo
annetaan arvona tässä ilmoituksessa. Tämä tarkoittaa sitä, että siitä hetkestä lähtien, kunnes muuttuja siirtyy alueen ulkopuolelle, muuttujan ref
käyttö on sama kuin foo
. Muuttuja ref
on nimen viitemuuttuja , joka viittaa foo
tässä vaiheessa.
Tämän seurauksena arvon antaminen arvolle ref
, kuten tehdään ilmoitusta seuraavalla rivillä, antaa arvon ryhmälle foo
.
Arvo hello
on tällöin käytettävissä komentosarjan pääosassa $foo
.
declare name
ja sen jälkeendeclare -p name
tuottaa ”bash: declare: name: not found”. (Vaikkadeclare -p | grep na
tuottaadeclare -- name
.) (2) Uskon, että on hieman harhaanjohtavaa esittääecho "${name-isunset}"
declare name
-yhteydessä, sikäli kuin se käsittelee ilmoittamatonta (eli määrittelemätöntä) muuttujaa samalla tavalla kuin ilmoitettua mutta poista muuttuja. (3) Haluat ehkä mainita, että namerefit ovat saatavilla vain bash-versiossa 4.3 ja uudemmissa.GNU bash, version 5.0.7(1)-release (x86_64-pc-linux-gnu)
Arch Linuxilla tuottaa edelleen tulokset, jotka näytin. Ehkä tämä käytös on otettu käyttöön vasta äskettäin, tutkin sitä.