Mikä on “ declare ” Bashissa?

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

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ään declare 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= tai declare name= jälkeen;
  • ilmoitettu , set ja ei nolla -arvolla name=value tai .

Yleisemmin declare [options] name=value

  1. luo muuttujan name – joka on parametri, jolla on nimi, joka puolestaan on vain osa muistista, jota voit käyttää tietojen tallentamiseen 4 ;
  2. määrittää arvo value siihen;
  3. 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:

  1. 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 ).

  2. Milloin muuttujan tmp1 arvo määritetään ryhmälle ref:

     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 osoituksella ref .

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

  • (1) En voi toistaa tuloksia, jotka näytät ensimmäisessä koodilohkossasi: declare name ja sen jälkeen declare -p name tuottaa ”bash: declare: name: not found”. (Vaikka declare -p | grep na tuottaa declare -- 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.
  • @ G-Man Kiitos huomautuksistasi! ’ Ll osoitan heille niin pian kuin voin, ja päivitän vastaukseni tarvittaessa ’. Mitä tulee kohtaan (1), 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ä.
  • Joo;

m vain versiolla 4.3.

  • @ G-Man Answer päivitetty muistiinpanoilla (1) ja (3). Tietoja (2): Tarkoitin havainnollistaa, että 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:

    1. muuttujat, jotka on ilmoitettu ”indeksoiduiksi matriiseiksi” (declare -a)
    2. 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" ja declare foo="bar" . Haluat ehkä mainita (jos vain alaviitteessä), että kuoritoiminnossa declare foo="bar" luo paikallisen muuttujan ja foo="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.

    Vastaa

    Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *