Wat is “ declareren ” in Bash?

Na het lezen van ilkkachu “s antwoord op deze vraag leerde ik over het bestaan van de declare (met argument -n) shell ingebouwd.

help declare brengt:

Stel variabelen en attributen in.

Declareer variabelen en geef ze attributen. Als er geen NAMEN zijn opgegeven, geeft u de attributen en waarden van alle variabelen.

-n … maak NAME een verwijzing naar de variabele genoemd door zijn waarde

I vraag om een algemene uitleg met een voorbeeld met betrekking tot declare omdat ik “de man niet begrijp. Ik weet wat een variabele is en ik breid het uit, maar ik mis nog steeds de man op declare (variabel attribuut?).

Misschien “wil je dit graag uitleggen op basis van de code van ilkkachu in het antwoord:

#!/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 } 

Reacties

Answer

In de meeste gevallen is het voldoende met een impliciete declaratie in bash

asdf="some text" 

Maar soms wil je dat de waarde van een variabele alleen een geheel getal is (dus in het geval dat het later zou veranderen, zelfs automatisch, zou het alleen veranderd kunnen worden in een geheel getal, standaard nul in sommige gevallen), en kan gebruiken:

declare -i num 

of

declare -i num=15 

Soms wil je arrays, en dan heb je declare

declare -a asdf # indexed type 

of

Je kunt goede tutorials over arrays vinden in bash wanneer je op internet surft met de zoekterm” bash array tutorial “(zonder aanhalingstekens), voor voorbeeld

linuxconfig.org/how-to-use-arrays-in-bash-script


Ik denk dat dit de meest voorkomende gevallen zijn waarin je variabelen declareert.


Merk ook op dat

  • in een functie declare maakt de variabele lokaal (in de functie)
  • zonder enige naam, het toont alle variabelen (in de actieve shell)

    declare 

Ten slotte krijgt u een korte samenvatting van de kenmerken van het in de shell ingebouwde commando declare in bash met het commando

help declare 

Reacties

  • Hallo van het OP! Ik denk dat je antwoord geweldig is en ik heb het positief gestemd en ik dank je voor dit, naar mijn mening, zeer didactische antwoord. Ik heb zojuist een kleine bewerking voorgesteld die het naar mijn bescheiden mening nog gemakkelijker en toegankelijker maakt voor nieuwkomers om te lezen; doorloop die suggestie.
  • Ik zag net dat user:muru stemde om de bewerking te weigeren; weet alsjeblieft dat Muru en ik ” meerdere keren ” hebben gecrasht in de verschillende secties van deze website en ik neem aan dat zijn afwijzing niet ‘ t objectief en is eigenlijk schadelijk in tegenstelling tot de directe wijzigingen die worden weergegeven op de pagina met bewerkingssuggesties hier: unix.stackexchange.com/review/suggested -edits / 325749
  • @JohnDoea, ik zag dat ook een andere gebruiker je bewerkingen heeft afgewezen. Ik denk dat sommige van je bewerkingen goed zijn, maar sommige zullen de boodschap veranderen van wat ik bedoelde, dus ik zou ze niet leuk vinden. Ik kan het antwoord bewerken om wat ik denk dat goede bewerkingen op te nemen.
  • bedankt; zoals u waarschijnlijk weet, komt het afwijzen van bewerkingen in SE veel vaker voor dan het accepteren ervan (zelfs gedeeltelijk); bedankt dat je me hebt laten weten dat een andere gebruiker de bewerking heeft afgewezen (ik heb het niet eerder ‘ niet eerder gezien) en voor het overwegen om ten minste enkele van mijn bewerkingen in je antwoord in te voegen; Ik respecteer dit zeer,

Answer

De output van help declare is nogal beknopt. Een duidelijkere uitleg is te vinden in man bash of info bash – de laatste is de bron voor wat volgt.

Allereerst enkele definities. Over variabelen en attributen :

Een parameter is een entiteit die waarden opslaat. … Een variabele is een parameter die wordt aangeduid met een name. Een variabele heeft een waarde en nul of meer attributen . Attributen worden toegewezen met de declare ingebouwde opdracht …

En over de declare ingebouwde :

declare

 declare [-aAfFgilnrtux] [-p] [name[=value] …]  

Declareer variabelen en geef ze attributen. Als er geen namen zijn opgegeven, geef dan in plaats daarvan de waarden van variabelen weer.

-n
Geef elk name het nameref attribuut, waardoor het een naamverwijzing is naar een andere variabele. Die andere variabele wordt gedefinieerd door de waarde van naam . Alle verwijzingen, toewijzingen en kenmerkaanpassingen aan name , behalve degenen die het -n -kenmerk zelf gebruiken of wijzigen, worden uitgevoerd op de variabele waarnaar wordt verwezen door naam s waarde. …

Merk op dat naamverwijzing variabelen alleen beschikbaar zijn in Bash 4.3 of hoger 1 .

Voor een nuttige inleiding tot declare en variabele attributen in Bash wil ik je ook wijzen op dit antwoord op ” Wat doen declare name en declare -g? ” (die zich echter voornamelijk richt op variabelen “scope).


In wezen 2 , declare name=[value] is gelijk aan de toewijzing name=[value] waarmee u waarschijnlijk bekend bent. In beide gevallen krijgt name de nul toegewezen waarde als value ontbreekt.

Merk op dat de iets andere declare name in plaats daarvan niet ingesteld de variabele 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  

De variabele name kan dus zijn:

  • gedeclareerd en uitgeschakeld , na declare name;
  • gedeclareerd en ingesteld met null als waarde, na name= of declare name=;
  • verklaard , set en met een niet nul waarde na name=value of .

Meer in het algemeen maakt declare [options] name=value

  1. de variabele name – dit is een parameter met een naam, die op zijn beurt slechts een deel van het geheugen is dat u kunt gebruiken om informatie op te slaan 4 ;
  2. wijst de waarde value eraan;
  3. stelt optioneel name “s attributen in, die zowel het soort waarde bepalen kan opslaan (niet in termen van een type , strikt genomen, aangezien de taal van Bash niet wordt getypt) en de manieren waarop deze kan worden gemanipuleerd.

Attributen zijn waarschijnlijk gemakkelijker uit te leggen met een voorbeeld: door declare -i name te gebruiken, wordt het ” gehele getal ” -attribuut ingesteld van name, waardoor het wordt behandeld als een geheel getal; onder vermelding van de handleiding , ” zal rekenkundige evaluatie worden uitgevoerd wanneer aan de variabele een waarde wordt toegewezen “:

 ## 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  

In het licht van het bovenstaande, wat er gebeurt in de code van ilkkachu is dat:

  1. Een variabele met de naam ref wordt gedeclareerd, met de ” nameref ” attribuutset, en de inhoud van $1 (het eerste positionele argument) is toegewezen aan it:

     declare -n ref="$1"  

    Het doel van een naamreferentievariabele zoals ref is om de naam van een andere variabele vast te houden, die doorgaans niet van tevoren bekend zou zijn, mogelijk omdat we willen dat deze dynamisch wordt gedefinieerd (bijvoorbeeld omdat we een stuk code willen hergebruiken en toegepast op verschillende variabelen), en op een gemakkelijke manier bieden om ernaar te verwijzen (en te manipuleren). (Niet de enige echter: indirecte is een alternatief; zie Shell Parameter Expansion ).

  2. Wanneer de waarde van de variabele tmp1 is toegewezen aan ref:

     ref=$tmp1  

    een extra variabele, waarvan de naam de waarde is van ref, wordt impliciet gedeclareerd. De waarde van tmp1 wordt ook indirect toegewezen aan de impliciet gedeclareerde variabele door middel van deze expliciete toewijzing aan ref .

In de context van uw gelinkte vraag , door read_and_verify als

 read_and_verify domain "Prompt text here..."  

zal de variabele en wijs het de waarde toe van tmp1 (dwz de invoer van de gebruiker). Het is precies ontworpen om de code die interactie heeft met de gebruiker te hergebruiken en een naamloze variabele te gebruiken om domain en een paar andere variabelen te declareren.

Om het impliciete deel van naderbij te bekijken, kunnen we het proces stap voor stap reproduceren:

 ## 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 Referentie: CHANGES -bestand, sectie ” 3. Nieuwe functies in Bash “, wijs ” w “.
Dit kan relevant zijn: bijvoorbeeld CentOS Linux 7.6 (momenteel de laatste versie) wordt geleverd met Bash 4.2 .

2 Zoals gewoonlijk met shell-builtins, een volledige en beknopte uitleg is ongrijpbaar omdat ze verschillende, mogelijk heterogene acties uitvoeren. Ik zal me alleen concentreren op het declareren, toewijzen en instellen van attributen, en ik zal overwegen om attributen op te sommen, te scopen en te verwijderen buiten het bereik van dit antwoord.

3 Dit gedrag van declare -p is geïntroduceerd in Bash 4.4. Referentie: CHANGES -bestand, sectie ” 3. Nieuwe functies in Bash “, wijs ” f “.
Als G-Man vermeld in opmerkingen, in Bash 4.3 geeft declare name; declare -p name een foutmelding. Maar je kunt nog steeds controleren of name bestaat met declare -p | grep "declare -- name".

4 FullBashGuide, Parameters op mywiki.wooledge.org

Reacties

  • (1) Ik kan de resultaten die je toont in je eerste codeblok niet reproduceren: declare name gevolgd door declare -p name levert “bash: declare: name: not found” op. (Hoewel declare -p | grep na declare -- name oplevert.) (2) Ik denk dat het een beetje misleidend is om echo "${name-isunset}" in de context van declare name, aangezien het een niet-gedeclareerde (dwz ongedefinieerde) variabele hetzelfde behandelt als een gedeclareerde maar unset variabele. (3) Misschien wil je vermelden dat namerefs alleen beschikbaar zijn in bash-versie 4.3 en hoger.
  • @ G-Man Bedankt voor je opmerkingen! Ik ‘ zal ze zo snel mogelijk behandelen en ‘ zal mijn antwoord waar nodig bijwerken. Wat betreft (1), mijn GNU bash, version 5.0.7(1)-release (x86_64-pc-linux-gnu) op Arch Linux levert nog steeds de resultaten op die ik liet zien. Misschien is dat gedrag pas onlangs geïntroduceerd, ik ‘ zal dat onderzoeken.
  • Ja; Ik ‘ gebruik alleen versie 4.3.
  • @ G-Man Antwoord bijgewerkt met opmerkingen over (1) en (3). Over (2): ik wilde illustreren dat declare x niet ‘ t x instelt, terwijl declare x= doet. Ik kon ‘ geen verwijzing vinden naar de bewering dat declare -- x (als uitvoer van declare -p x) betekent ” niet ingesteld “, terwijl declare -- x="" betekent ” set “; dus heb ik de ${parameter-word} uitbreiding toegevoegd, zelfs als deze geen onderscheid kan maken tussen ” unset ” en ” bestaat niet ‘ t bestaat “, zoals u aangeeft. Ik ‘ weet echter niet zeker hoe ik dit in mijn antwoord kan verduidelijken (zonder de lezer van het punt af te leiden).

Antwoord

Ik zal mijn best doen om dit uit te leggen, maar vergeef me als ik het door jou opgegeven voorbeeld niet volg. Ik zal liever proberen je te begeleiden in mijn eigen, andere benadering.

Je zegt dat je begrippen als variabelen en ze uitbreiden, enz. Al begrijpt, dus ik zal wat achtergrondkennis die anders een diepere focus zou vereisen.

Dus ik zal beginnen met te zeggen dat op zijn hoogst basic level, is het declare commando slechts een manier om Bash te vertellen dat je een variabele waarde nodig hebt (dat wil zeggen een waarde die kan veranderen tijdens het uitvoeren van het script), en dat je dat zult doen verwijs naar die waarde met een specifieke naam, precies de naam die u aangeeft naast het declare commando zelf.

Dat wil zeggen:

 declare foo="bar"  

vertelt Bash dat je wil dat de variabele met de naam foo de waarde bar heeft.

Maar .. wacht even .. we kunnen doen dat zonder declare te gebruiken, nietwaar. Zoals in:

 foo="bar"  

Zeer waar.

Nou , is het zo dat de bovenstaande eenvoudige toewijzing eigenlijk een impliciete manier is voor .. in feite .. het declareren van een variabele.

( Het komt ook voor dat het bovenstaande één is van een aantal manieren om verander de waarde van de variabele met de naam foo; het is inderdaad precies de meest directe, beknopte, duidelijke, ongecompliceerde manier .. maar het is niet de enige .. .. ik kom hier later op terug .. ).

Maar dan, als het zo is het is goed mogelijk om een “naam die variabele waarden tagt” te declareren (alleen “variabele” van hierna, kortheidshalve) zonder declare te gebruiken, waarom zou je ooit willen gebruik je dit pompeuze “verklaar” -commando?

Het antwoord ligt in het feit dat de bovenstaande implici De manier om een variabele te declareren (foo="bar"), het .. impliciet .. zorgt ervoor dat Bash die variabele beschouwt als zijnde van het type dat het meest wordt gebruikt in het typische gebruiksscenario voor een shell .

Een dergelijk type is het stringtype, dwz een reeks karakters zonder specifieke betekenis. Daarom is een string wat je krijgt als je de impliciete declaratie gebruikt.

Maar jij, als programmeur, moet soms een variabele beschouwen als bijvoorbeeld een getal … waarop je moet rekenen bewerkingen .. en het gebruik van een impliciete declaratie zoals foo=5+6 zal niet ervoor zorgen dat Bash waarde 11 toewijst aan foo als je zou verwachten. Het zal eerder aan foo de reeks van de drie tekens toewijzen 5 + 6.

Dus .. je hebt een manier nodig om Bash te vertellen dat je wilt dat foo als een getal wordt beschouwd, niet als een string .. en daarvoor is een expliciete declare nuttig.

Zeg gewoon:

 declare -i foo=5+6 # <<- note the "-i" option: it means "integer"  

en Bash doet de wiskunde graag voor je, en wijst de numerieke waarde 11 toe aan variabele foo.

Dat wil zeggen: door declare -i foo te zeggen geef je aan variabele foo de attribuut om een geheel getal te zijn.

Het declareren van getallen (precies gehele getallen, omdat Bash nog steeds geen decimalen, drijvende kommas en dergelijke begrijpt) kan de eerste reden zijn om declare, maar het is niet de enige reden. Zoals je al hebt begrepen, zijn er een paar andere attributen die je aan variabelen kunt geven. U kunt bijvoorbeeld Bash hebben om de waarde van een variabele altijd in hoofdletters te zetten, wat er ook gebeurt: als u declare -u foo zegt, dan zegt u vanaf dat moment foo=bar Bash wijst feitelijk de string BAR toe aan de variabele foo.

Om een van deze attributen te geven naar een variabele, moet het declare commando gebruiken, er is geen andere keuze.


Nu, nog een van de attributen die je kunt geven via declare is de beruchte “name-ref”, het -n attribuut. ( En nu ga ik verder met het concept dat ik eerder in de wacht heb gezet ).

Het name-ref attribuut geeft Bash-programmeurs in feite een andere manier om de waarde te veranderen van een variabele. Het geeft meer precies een indirecte manier om dat te doen.

Hier is hoe het werkt:

Je declare een variabele met het -n attribuut, en het is zeer aanbevolen (hoewel niet strikt vereist, maar het maakt dingen eenvoudiger) dat je ook een waarde geeft aan deze zeer variabele op dezelfde declare commando. Zoals dit:

 declare -n baz="foo"  

Dit vertelt Bash dat vanaf dat moment aan, elke keer dat u de waarde van de variabele met de naam baz gebruikt of wijzigt, zal deze de waarde van de variabele met de naam .

Wat betekent dat vanaf dat moment yo je kunt iets zeggen als baz=10+3 om ervoor te zorgen dat foo de waarde 13 krijgt.Ervan uitgaande natuurlijk dat foo eerder werd gedeclareerd als geheel getal (declare -i) zoals we slechts een minuut geleden deden, anders krijgt het de reeks van de vier tekens 1 0 + 3.

Ook: als je de waarde van foo rechtstreeks wijzigt, zoals in foo=15, zul je zien 15 ook door echo “${baz}” te zeggen. Dit komt doordat variabele baz gedeclareerd als naam-ref van foo altijd foo s weerspiegelt waarde.

Het bovenstaande declare -n commando wordt een “naamverwijzing” genoemd omdat het de variabele baz verwijs naar de naam van een andere variabele. In feite hebben we verklaard dat baz de waarde “foo” heeft die, vanwege de -n optie, wordt afgehandeld door Bash als de naam voor een andere variabele.

Nu, waarom op aarde zou je dat ooit willen doen?

Nou .. het is de moeite waard om te zeggen dat dit een functie is voor vrij geavanceerde behoeften.

In feite zo geavanceerd dat wanneer een programmeur met een probleem wordt geconfronteerd dat echt een naamverwijzing vereist, het ook waarschijnlijk dat een dergelijk probleem eerder zou moeten worden aangepakt door een goede programmeertaal te gebruiken in plaats van Bash.

Een van die geavanceerde behoeften is bijvoorbeeld wanneer u, als programmeur, niet weet tijdens de ontwikkeling welke variabele je moet gebruiken in een specifiek punt van een script, maar deze zal dynamisch volledig bekend zijn tijdens runtime. En aangezien er geen manier is voor een programmeur om in te grijpen tijdens runtime, is de enige optie om van tevoren voorzieningen te treffen voor een dergelijke situatie in het script, en een naamreferentie kan de enige haalbare zijn manier. Denk bijvoorbeeld aan plug-ins als een algemeen bekende use case van deze geavanceerde behoefte. De programmeur van een “plug-inbaar” programma moet vooraf generieke voorzieningen treffen voor toekomstige (en mogelijk van derden) plug-ins. Daarom zal de programmeur faciliteiten zoals een naamreferentie in Bash moeten gebruiken.

Een andere geavanceerde behoefte is wanneer je te maken hebt met een enorme hoeveelheid gegevens in RAM en je ook moet die gegevens doorgeven aan functies van uw script die ook die gegevens gaandeweg moeten wijzigen. In dat geval zou je die gegevens zeker kopiëren van de ene functie naar de andere (zoals Bash doet wanneer je dest_var="${src_var}" doet of wanneer je functies aanroept zoals in myfunc "${src_var}"), maar aangezien het om een enorme hoeveelheid data gaat, zou dit een enorme verspilling van RAM opleveren en voor een zeer inefficiënte operatie. Dus de oplossing als dergelijke situaties zich voordoen, is om geen kopie van de gegevens te gebruiken, maar een verwijzing naar die gegevens. In Bash, een naam-ref. Deze use-case is echt de norm in elke moderne programmeertaal, maar het is vrij uitzonderlijk als het om Bash gaat, omdat Bash meestal is ontworpen voor korte, eenvoudige scripts die meestal met bestanden en externe commandos te maken hebben en daarom hoeven Bash-scripts zelden enorme hoeveelheid gegevens tussen functies. En wanneer de functies van een script bepaalde gegevens moeten delen (er toegang toe krijgen en deze moeten wijzigen), wordt dit meestal bereikt door alleen een globale variabele te gebruiken, wat vrij de norm is in Bash-scripts, net zo goed als zeer verouderd in de juiste programmeertalen.

Dan kan er een opmerkelijke use case zijn voor name-refs in Bash, en (misschien ironisch genoeg) wordt het geassocieerd met wanneer je nog andere soorten variabelen gebruikt:

  1. variabelen die worden gedeclareerd als “geïndexeerde arrays” (declare -a)
  2. variabelen die worden gedeclareerd als “associatieve arrays” (declare -A).

Dit zijn een soort variabelen die gemakkelijker (en ook efficiënter) door functies kunnen worden doorgegeven door name-refs te gebruiken in plaats van door normaal te kopiëren, zelfs als ze geen enorme hoeveelheden data bevatten.

Als al deze voorbeelden raar klinken en nog steeds onbegrijpelijk, is dat alleen omdat name-refs inderdaad een geavanceerd onderwerp, en een zeldzame behoefte aan het typische gebruiksscenario van B ash.

Ik zou je kunnen vertellen over gelegenheden waarbij ik bijvoorbeeld gebruik heb gevonden voor naam-refs in Bash, maar tot nu toe waren ze meestal voor nogal “esoterische” en gecompliceerde behoeften, en ik ben bang dat als ik ze zou beschrijven, ik de dingen voor u alleen maar ingewikkelder zou maken op dit punt van uw leerproces. Om het minst complexe (en mogelijk niet esoterische) te noemen: het retourneren van waarden uit functies. Bash ondersteunt deze functionaliteit niet echt, dus ik heb hetzelfde verkregen door name-refs te gebruiken. Dit is overigens precies wat uw voorbeeldcode doet.


Daarnaast een klein persoonlijk advies, dat eigenlijk beter geschikt zou zijn voor een opmerking, maar ik heb het niet genoeg kunnen verdichten om in de commentaarlimieten van StackExchange te passen.

Ik denk dat het meeste dat je op dit moment zou moeten doen, is om gewoon te experimenteren met name-refs door de eenvoudige voorbeelden te gebruiken die ik liet zien en misschien met de voorbeeldcode die je hebt opgegeven, zonder rekening te houden met momenteel het “waarom op aarde” -gedeelte en alleen gericht op het “hoe het werkt” -gedeelte. Door een beetje te experimenteren, zinkt het hoe-gedeelte misschien beter in je geest, zodat het waarom-gedeelte je te zijner tijd duidelijk zal worden wanneer (of als) je een echt praktisch probleem hebt waarvoor een naam- ref zou echt van pas komen.

Opmerkingen

  • LL3 Ik vind je antwoord erg leuk en ik heb een duim omhoog: ik begrijp eindelijk wat declareren doet – – geen variabelen declareren, maar hun attributen; maar helaas ben ik het spoor kwijtgeraakt toen je begon uit te leggen wat een naam-ref is. Ik heb geen idee wat het doet en waarom ik het moet gebruiken.
  • Dat is – waarom zou je dit attribuut geven
  • @JohnDoea zie ik. Misschien verlaat u dit onderwerp even. Het is waarschijnlijk te vroeg om dit concept op het huidige punt van leren te begrijpen. Hoe dan ook, ik heb mijn antwoord uitgebreid met meer voorbeelden en ook een klein persoonlijk addendum over hoe ik denk dat je verder moet gaan. Ik heb ook horizontale lijnen geplaatst om de algemene uitleg van declare van de specifieke uitleg van -n van het persoonlijke addendum af te bakenen. Ik heb hier en daar ook een beetje herformulering gedaan, maar niets wezenlijks, dus ik denk dat je het -n -gedeelte plus het kleine addendum gewoon opnieuw kunt lezen.
  • Bedankt, ik denk dat het ‘ oké is dat ik hier nu over leer, ik heb alleen een uitleg nodig die ik kan begrijpen en ik zou je volledige antwoord vandaag nog eens moeten lezen, ik ‘ m hier in de buurt.
  • U vermeldt foo="bar" en declare foo="bar" . Misschien wil je vermelden (al was het maar in een voetnoot) dat in een shell-functie declare foo="bar" een lokale variabele maakt en foo="bar" een globale variabele.

Antwoord

In het algemeen declare in de bash shell stelt (of verwijdert, of toont) attributen op variabelen. Een attribuut is een soort annotatie die zegt dit is een naamverwijzing, of dit is een associatieve array, of deze variabele moet altijd worden geëvalueerd als een geheel getal, of deze variabele is alleen-lezen en kan niet opnieuw worden ingesteld “, of” deze variabele wordt geëxporteerd (een omgevingsvariabele) “enz.

De typeset ingebouwde is een synoniem voor declare in bash, aangezien typeset wordt gebruikt in andere shells (ksh, waar het vandaan kwam, en zsh, bijvoorbeeld) voor het instellen van variabele attributen.


Nauwkeuriger kijken naar het naamreferentievoorbeeld in de vraag:

De shell-functie die je laat zien, met een toegevoegd stukje code dat het gebruikt:

#!/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" 

Dit uitvoeren:

 $ 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 "" 

Dat toont aan dat de foo variabele nergens op wordt ingesteld wanneer de gebruiker twee verschillende strings.

Dat toont aan dat de variabele foo wordt ingesteld op de tekenreeks die de gebruiker heeft ingevoerd toen hij twee keer dezelfde tekenreeks invoerde .

De manier waarop $foo de waarde hello krijgt in het hoofdgedeelte van het script is door de volgende regels in de shell-functie:

declare -n ref="$1" ref=$tmp1 

waarbij $tmp1 de tekenreeks is hello ingevoerd door de gebruiker, en $1 is de string foo die is doorgegeven op de opdrachtregel van de functie vanaf het hoofdgedeelte van de script.

Merk op dat de ref variabele wordt gedeclareerd met declare -n als een naamreferentievariabele en dat de waarde foo wordt gegeven als de waarde in die declaratie. Dit betekent dat vanaf dat punt, totdat de variabele buiten het bereik valt, elk gebruik van de variabele ref hetzelfde zal zijn als het gebruik van foo. De variabele ref is een naamreferentievariabele die op dit punt verwijst naar foo.

Dit heeft tot gevolg dat het toekennen van een waarde aan ref, zoals wordt gedaan op de regel die volgt op de declaratie, de waarde toewijst aan foo.

De waarde hello is dan beschikbaar in $foo in het hoofdgedeelte van het script.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *