Hva er “ erklærer ” i Bash?

Etter å ha lest ilkkachus svar på dette spørsmålet fikk jeg vite om eksistensen av declare (med argument -n) innebygd skall.

help declare bringer:

Angi variabelverdier og attributter.

Erklær variabler og gi dem attributter. Hvis ingen NAVN er gitt, viser du attributter og verdier for alle variabler.

-n … gjør NAME til en referanse til variabelen oppkalt etter verdien

I be om en generell forklaring med et eksempel angående declare fordi jeg ikke forstår man. Jeg vet hva som er en variabel og utvider den, men jeg savner fortsatt mandeclare (variabelattributt?).

Kanskje du vil forklare dette basert på koden av ilkkachu i svaret:

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

Kommentarer

Svar

I de fleste tilfeller er det nok med en implisitt erklæring i bash

asdf="some text" 

Men noen ganger vil du at verdien til en variabel bare skal være heltall (så hvis den senere endres, selv automatisk, kan den bare endres til et heltall, er som standard null i noen tilfeller), og kan bruke:

declare -i num 

eller

declare -i num=15 

Noen ganger vil du ha matriser, og da trenger du declare

declare -a asdf # indexed type 

eller

Du kan finne gode veiledninger om matriser i bash når du surfer på internett med søkestrengen» bash array tutorial «(uten anførselstegn), for eksempel

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


Jeg tror dette er de vanligste tilfellene når du erklærer variabler.


Vær også oppmerksom på at

  • i en funksjon, declare gjør variabelen lokal (i funksjonen)
  • uten noe navn, den viser alle variablene (i det aktive skallet)

    declare 

Til slutt får du et kort sammendrag av funksjonene til den innebygde skallkommandoen declare i bash med kommandoen

help declare 

Kommentarer

  • Hei fra OP! Jeg synes svaret ditt er flott, og jeg har oppstemt det og takker for dette, etter min mening, veldig didaktisk svar. Jeg har nettopp foreslått en mindre redigering som etter min ydmyke mening gjør det enda lettere og tilgjengelig for nykommere å lese; vennligst gå gjennom det forslaget.
  • Jeg så nettopp at user:muru stemte for å avvise redigeringen; vær så snill å vite at jeg og muru har » sammenstøt » flere ganger i de forskjellige delene av dette nettstedet, og jeg antar at hans avvisning ikke er = «e44298e665»>

t objektiv og er faktisk skadelig i motsetning til de direkte endringene som presenteres på redigeringsforsiden her: unix.stackexchange.com/review/suggested -edits / 325749

  • @JohnDoea, jeg så at også en annen bruker har avvist endringene dine. Jeg synes noen av endringene dine er bra, men noen av dem vil endre meldingen fra det jeg hadde tenkt, så jeg vil ikke like dem. Jeg kan redigere svaret for å inkludere det jeg synes er gode endringer.
  • takk; som du sikkert vet, er det mye mer vanlig å avvise endringer i SE enn å godta dem (til og med delvis); takk for at du la meg vite at en annen bruker avviste redigeringen (jeg så ‘ ikke ærlig før) og for at du vurderte å legge inn minst noen av endringene mine i svaret ditt; Jeg respekterer dette mye,
  • Svar

    Resultatet av help declare er ganske kort. En klarere forklaring finner du i man bash eller info bash – sistnevnte er kilden for det som følger.

    For det første noen definisjoner. Om variabler og attributter :

    En parameter er en enhet som lagrer verdier. … En variabel er en parameter betegnet med en name. En variabel har en verdi og null eller flere attributter . Attributter tildeles ved hjelp av declare innebygd kommando …

    Og om declare innebygd :

    declare

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

    Erklær variabler og gi dem attributter. Hvis ingen navn er gitt, så vis verdiene til variabler i stedet.

    -n
    Gi hver navn attributtet nameref , noe som gjør det til en referanse til en annen variabel. Den andre variabelen er definert av verdien av navn . Alle referanser, oppgaver og attributtendringer til navn , bortsett fra de som bruker eller endrer -n selve attributtet, utføres på variabelen det refereres til navn s verdi. …

    Vær oppmerksom på at navnereferanse variabler bare er tilgjengelige i Bash 4.3 eller nyere 1 .

    Også, for en nyttig introduksjon til declare og variable attributter i Bash, vil jeg peke deg på dette svar på » Hva gjør declare name og declare -g? » (som hovedsakelig fokuserer på variabler «omfang, skjønt).


    I utgangspunktet 2 , declare name=[value] tilsvarer oppgaven name=[value] du sannsynligvis er kjent med. I begge tilfeller tildeles name null verdi hvis value mangler.

    Legg merke til at den litt forskjellige declare name i stedet ikke angir variabelen 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  

    Dermed kan variabelen name være:

    • erklært og unset , etter declare name;
    • erklært og sett med null som verdi, etter name= eller declare name=;
    • erklært , sett og med en ikke null verdi etter name=value eller .

    Mer generelt, declare [options] name=value

    1. oppretter variabelen name – som er en parameter med et navn, som igjen bare er en del av minnet du kan bruke til å lagre informasjon 4 ;
    2. tildeler verdien value til den;
    3. angir valgfritt name «s attributter, som definerer både typen verdi den kan lagre (ikke i form av en type , strengt tatt siden Bash s språk ikke er skrevet) og måtene det kan manipuleres på.

    Attributter er sannsynligvis lettere å forklare med et eksempel: å bruke declare -i name vil angi » heltall » attributtet av name, slik at den kan behandles som et helt tall; siterer manualen , » aritmetisk evaluering vil bli utført når variabelen er tildelt en verdi «:

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

    I lys av det ovennevnte, det som skjer i ilkkachus kode er at:

    1. En variabel kalt ref blir erklært, med » nameref » attributt sett, og innholdet i $1 (det første posisjonsargumentet) er tildelt det:

       declare -n ref="$1"  

      Målet med en navnereferansevariabel som ref er å holde navnet på en annen variabel, som vanligvis ikke ville være kjent på forhånd, muligens fordi vi vil at den skal være dynamisk definert (f.eks. Fordi vi vil bruke et stykke kode på nytt og ha det brukt på flere variabler), og på gir en praktisk måte å henvise til (og manipulere) den. (Ikke den eneste, skjønt: indireksjon er et alternativ; se Skalparameterutvidelse ).

    2. Når verdien av variabelen tmp1 tildeles ref:

       ref=$tmp1  

      en ekstra variabel, hvis navn er verdien til ref, blir implisitt erklært. Verdien av tmp1 er også indirekte tilordnet den implisitt deklarerte variabelen ved hjelp av denne eksplisitte tildelingen til ref .

    I sammenheng med det linkede spørsmålet ditt , ringer du read_and_verify som

     read_and_verify domain "Prompt text here..."  

    vil erklære variabelen domain og tildel det verdien til tmp1 (dvs. brukerens inngang). Den er nøyaktig designet for å gjenbruke koden som samhandler med brukeren og utnytte en navneverifariabel å erklære domain og noen få andre variabler.

    For å se nærmere på den implisitte delen kan vi gjengi prosessen trinn for trinn:

     ## 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 Referanse: ENDRE fil, seksjon » 3. Nye funksjoner i Bash «, punkt » w «.
    Dette kan være aktuelt: for eksempel CentOS Linux 7.6 (for øyeblikket siste versjon) leveres med Bash 4.2 .

    2 Som vanlig med skallinnbygginger, en uttømmende og kortfattet forklaring er unnvikende siden de utfører forskjellige, muligens heterogene handlinger. Jeg vil fokusere på å kunngjøre, tilordne og sette attributter, og jeg vil vurdere å liste opp, ramme og fjerne attributter som ikke er omfattet av dette svaret.

    3 Denne oppførselen til declare -p er introdusert i Bash 4.4. Referanse: ENDRE fil, seksjon » 3. Nye funksjoner i Bash «, punkt » f «.
    Som G-Man påpekt i kommentarer, i Bash 4.3 declare name; declare -p name gir en feil. Men du kan fortsatt sjekke at name eksisterer med declare -p | grep "declare -- name".

    4 FullBashGuide, Parametere på mywiki.wooledge.org

    Kommentarer

    • (1) Jeg kan ikke gjengi resultatene du viser i din første kodeblokk: declare name etterfulgt av declare -p name gir «bash: declare: name: not found». (Selv om declare -p | grep na gir declare -- name.) (2) Jeg tror det er litt misvisende å presentere echo "${name-isunset}" i sammenheng med declare name, for så vidt den behandler en udeklarert (dvs. udefinert) variabel den samme som en erklært men usett variabel. (3) Det kan være lurt å nevne at navneord kun er tilgjengelig i bash versjon 4.3 og nyere.
    • @ G-Man Takk for dine kommentarer! Jeg ‘ Jeg adresserer dem så snart jeg kan, og jeg ‘ oppdaterer svaret mitt der det er passende. Når det gjelder (1), gir min GNU bash, version 5.0.7(1)-release (x86_64-pc-linux-gnu) på Arch Linux fremdeles resultatene jeg viste. Kanskje den atferden har blitt introdusert bare nylig, jeg ‘ vil undersøke det.
    • Yeah; Jeg ‘ bruker bare versjon 4.3.
    • @ G-Man Svar oppdatert med notater om (1) og (3). Om (2): Jeg hadde som mål å illustrere at declare x ikke ‘ t satt x, mens declare x= gjør det. Jeg kunne ikke ‘ ikke finne noen referanse til å hevde påstanden om at declare -- x (som utdata fra declare -p x) betyr » ikke angitt «, mens declare -- x="" betyr » sett «; dermed hentet jeg inn ${parameter-word} utvidelsen, selv om den ikke kan skille mellom » unset » og » eksisterer ikke ‘ t «, som du påpeker. Jeg ‘ er ikke sikker på hvordan jeg kan avklare dette i svaret mitt (uten å distrahere leseren fra poenget).

    Svar

    Jeg skal prøve å forklare dette, men tilgi meg hvis jeg ikke følger eksemplet du ga. Jeg vil heller prøve å veilede deg på min egen, annerledes, tilnærming.

    Du sier at du allerede forstår begreper som «variabler» og «utvidelse» osv. Så jeg skummer bare bakgrunnskunnskap som ellers ville krevd dypere fokus.

    Så jeg begynner med å si det, på det meste grunnleggende level, declare -kommandoen er bare en måte for deg å fortelle Bash at du trenger en variabel verdi (dvs. en verdi som kan endres under kjøring av skript), og at du vil referer til den verdien ved å bruke et bestemt navn, nøyaktig navnet du angir ved siden av declare selve kommandoen.

    Det vil si:

     declare foo="bar"  

    forteller Bash at du vil at variabelen kalt foo har verdien bar.

    Men .. vent litt … vi kan gjør det uten å bruke declare i det hele tatt, kan vi ikke. Som i:

     foo="bar"  

    Veldig sant.

    Vel , skjer det slik at ovennevnte enkle oppgave faktisk er en implisitt måte for .. faktisk .. å erklære en variabel.

    ( Det skjer også slik at ovenstående er en av noen få måter å endre verdien av variabelen som heter foo; faktisk er den akkurat den mest direkte, kortfattet, tydelig, rett frem måte .. men det er ikke den eneste .. .. Jeg kommer tilbake til dette senere .. ).

    Men så, hvis det er slik godt mulig å erklære et «navn som vil merke variabelverdier» (bare «variabelt» heretter, for korthets skyld) uten å bruke declare i det hele tatt, hvorfor skulle du noen gang ønske å bruk denne pompøse «erklær» -kommandoen?

    Svaret ligger i det faktum at ovennevnte implici t måte å erklære en variabel på (foo="bar"), det .. implisitt .. får Bash til å betrakte den variabelen for å være av den typen som er mest brukt i det typiske bruksscenariet for et skall .

    En slik type er strengtypen, dvs. en sekvens av tegn uten spesiell betydning. Derfor er en streng hva du får når du bruker den implisitte erklæringen.

    Men du, som programmerer, trenger noen ganger å betrakte en variabel som f.eks. Et tall .. som du trenger å regne på operasjoner .. og ved å bruke en implisitt erklæring som foo=5+6 vil ikke gjøre at Bash tilordner verdi 11 til foo som kan du forvente. Det vil heller tilordne foo sekvensen til de tre tegnene 5 + 6.

    Så .. du trenger en måte å fortelle Bash at du vil at foo skal betraktes som et tall, ikke et streng .. og det er en eksplisitt declare som er nyttig for.

    Si bare:

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

    og Bash gjør gjerne matematikken for deg, og tildeler numerisk verdien 11 til variabelen foo.

    Det vil si: ved å si declare -i foo gir du variabelen foo attributt for å være et heltall.

    Erklæring av tall (nøyaktig heltall, fordi Bash fremdeles ikke forstår desimaler, flytende punkter og alt det), kan være den første grunnen til at du bruker declare, men det er ikke den eneste grunnen. Som du allerede har forstått, er det noen få andre attributter du kan gi variabler. For eksempel kan du ha Bash for alltid å gjøre verdien til en variabel stor, uansett: hvis du sier declare -u foo, så fra da av når du sier foo=bar Bash tilordner faktisk strengen BAR til variabelen foo.

    For å gi noen av disse attributtene til en variabel, må du bruke declare -kommandoen. Det er ikke noe annet valg.


    Nå, en annen av attributter du kan gi gjennom declare er den beryktede “name-ref”, -n attributtet. ( Og nå skal jeg gjenoppta konseptet jeg la på vent tidligere ).

    Navnet-ref-attributtet tillater i utgangspunktet Bash-programmerere en annen måte å endre verdien på av en variabel. Det gir mer presist en indirekte måte å gjøre det på.

    Her er hvordan det fungerer:

    Du declare en variabel som har -n attributtet, og det er veldig anbefalt (men ikke strengt nødvendig, men det gjør ting enklere) at du også gir en verdi til dette veldig variabelt på samme declare kommando. Slik:

     declare -n baz="foo"  

    Dette forteller Bash at, fra da på, hver gang du bruker eller endrer verdien på variabelen med navnet baz, skal den faktisk bruke, eller endre, verdien på variabelen med navnet foo.

    Hvilket betyr at fra da av, yo du kan si noe sånt som baz=10+3 for å få foo til å få verdien 13.Forutsatt selvfølgelig at foo tidligere ble erklært som heltall (declare -i) som vi gjorde for bare ett minutt siden, ellers får den sekvensen av de fire tegnene 1 0 + 3.

    Også: hvis du endrer foo verdi direkte, som i foo=15, vil du se 15 også ved å si echo “${baz}”. Dette er fordi variabel baz deklarert som navn-ref til foo alltid gjenspeiler foo verdi.

    Ovennevnte declare -n kommando sies å være «navn-referanse» fordi den gjør variabel baz referer til navnet på en annen variabel. Vi har faktisk erklært at baz har verdien «foo» som på grunn av -n -alternativet håndteres av Bash som navnet på en annen variabel.

    Nå, hvorfor på jorden vil du noen gang ønske å gjøre det?

    Vel … det er verdt å si at dette er en funksjon for ganske avanserte behov.

    Faktisk så avansert at når en programmerer står overfor et problem som virkelig vil kreve navn-ref, er det også sannsynlig at et slikt problem heller skal adresseres ved å bruke et riktig programmeringsspråk i stedet for Bash.

    Et av disse avanserte behovene er for eksempel når du som programmerer ikke kan vite under utvikling hvilken variabel du må bruke i et bestemt punkt i et skript, men det vil være fullstendig kjent dynamisk ved kjøretid. Og med tanke på at det ikke er noen måte for noen programmerer å gripe inn på kjøretid, er det eneste alternativet å sørge for på forhånd for en slik situasjon i skriptet, og en «navn-ref» kan være den eneste levedyktige vei. Som et allment kjent brukstilfelle av dette avanserte behovet, tenk på plugin-moduler, for eksempel. Programmereren av et «plugin-kompatibelt» program må sørge for generiske avsetninger for fremtidige (og muligens tredjeparts) plugin-moduler på forhånd. Derfor vil programmereren måtte bruke fasiliteter som et navn-ref i Bash.

    Et annet avansert behov er når du må håndtere enorme mengder data i RAM og du også må sende disse dataene rundt funksjonene i skriptet ditt som også må endre dataene underveis. I slike tilfeller kan du absolutt kopiere dataene fra en funksjon til en annen (som Bash gjør når du gjør dest_var="${src_var}" eller når du påkaller funksjoner som i myfunc "${src_var}"), men fordi de dataene er enorme, vil det gi et enormt sløsing med RAM og for en veldig ineffektiv operasjon. Så løsningen hvis slike situasjoner oppstår, er å ikke bruke en kopi av dataene, men en referanse til disse dataene. I Bash, en navn-ref. Denne brukssaken er egentlig normen i ethvert moderne programmeringsspråk, men det er ganske eksepsjonelt når det gjelder Bash, fordi Bash er for det meste designet for korte, enkle skript som for det meste håndterer filer og eksterne kommandoer, og dermed trenger Bash-skript sjelden å passere enormt. mengde data mellom funksjonene. Og når funksjonene til et skript trenger å dele noen data (få tilgang til det og endre det), oppnås dette vanligvis bare ved å bruke en global variabel, noe som er ganske vanlig i Bash-skript så mye som det er veldig utfaset i riktige programmeringsspråk.

    Deretter kan det være en bemerkelsesverdig brukstilfelle for navn-ref i Bash, og (kanskje ironisk nok) er det knyttet til når du bruker enda andre typer variabler:

    1. variabler som er erklært som «indekserte matriser» (declare -a)
    2. variabler som er erklært som «assosiative matriser» (declare -A).

    Dette er en type variabler som kan lettere (så vel som mer effektivt) sendes langs funksjoner ved å bruke navn-ref i stedet for ved normal kopiering, selv når de ikke har store mengder data.

    Hvis alle disse eksemplene høres rare, og fremdeles uforståelige, er det bare fordi navn-referanser virkelig er avansert emne, og et sjeldent behov for det typiske bruksscenariet til B aske.

    Jeg kunne fortelle deg om anledninger der jeg for en gang har funnet bruk for navnehenvisninger i Bash, men så langt har de stort sett vært for ganske «esoteriske» og kompliserte behov, og jeg er redd for at hvis jeg beskrev dem, ville jeg bare komplisere ting for deg på dette tidspunktet du lærte deg. Bare for å nevne det minst komplekse (og muligens ikke esoteriske): å returnere verdier fra funksjoner. Bash støtter egentlig ikke denne funksjonaliteten, så jeg fikk det samme ved å bruke navn-ref. Dette er forøvrig nøyaktig hva eksempelkoden din gjør.


    I tillegg til dette, et lite personlig råd, som faktisk ville være bedre egnet for en kommentar, men jeg har ikke klart å fortette det nok for å passe inn i StackExchanges begrensninger.

    Jeg tror at det meste du bør gjøre for øyeblikket er å bare eksperimentere med navnereferanser ved å bruke de enkle eksemplene jeg viste og kanskje med eksempelkoden du oppga, uten å se bort fra for øyeblikket delen «hvorfor i all verden» og kun fokusere på «hvordan det fungerer» -delen. Ved å eksperimentere litt kan «hvordan» -delen synke bedre inn i tankene dine, slik at «hvorfor» -delen vil bli tydelig for deg i god tid når (eller hvis) du har et reelt praktisk problem som et navn- ref ville virkelig komme til nytte.

    Kommentarer

    • LL3 Jeg liker svaret ditt veldig godt, og jeg tommelfinger: Jeg forstår endelig hva erklæringen gjør – – ikke deklarere variabler, men deklarere attributtene; men dessverre mistet jeg oversikten når du begynte å forklare hva som er en navn-ref. Jeg ante ikke hva den gjør og hvorfor jeg skal bruke den.
    • Det er – hvorfor skulle man gi denne attributtet
    • @JohnDoea ser jeg. Kanskje du bare kan forlate dette emnet for øyeblikket. Det er sannsynligvis for tidlig å forstå dette konseptet på det nåværende tidspunktet du lærer deg. Uansett har jeg utvidet svaret mitt med flere eksempler og også et lite personlig tillegg til hvordan jeg synes du skal gå frem. Jeg har også lagt horisontale linjer for å avgrense den generelle forklaringen av declare fra den spesifikke forklaringen til -n fra det personlige tillegget. Jeg har også gjort litt omformulering her og der, men ikke noe vesentlig, så jeg tror du bare kan lese -n -delen pluss det lille tillegget.
    • Takk, jeg tror det ‘ er greit for meg å lære om dette akkurat nå, jeg trenger bare en forklaring jeg kan forstå, og jeg bør lese hele svaret ditt i dag, jeg ‘ m her rundt.
    • Du nevner foo="bar" og declare foo="bar" . Det kan være lurt å nevne (hvis bare i en fotnote) at declare foo="bar" i en skallfunksjon oppretter en lokal variabel og foo="bar" oppretter en global variabel.

    Svar

    Generelt sett declare i bash skallsett (eller fjerner eller viser) attributter på variabler. Et attributt er en slags kommentar som sier «dette er en navnereferanse», eller «dette er en assosiativ matrise», eller «denne variabelen skal alltid vurderes som et heltall», eller «denne variabelen er skrivebeskyttet og kan ikke settes på nytt «, eller» denne variabelen eksporteres (en miljøvariabel) «osv.

    Den typeset innebygde er et synonym for declare i bash, da typeset brukes i andre skall (ksh, hvor den stammer fra, og zsh, for eksempel) for å sette variabelattributter.


    Ser nærmere på eksemplet på navnereferansen i spørsmålet:

    Skallfunksjonen du viser, med en ekstra kode som bruker den:

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

    Kjører dette:

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

    Det viser at foo variabelen ikke blir satt til noe når brukeren legger inn to forskjellige strenger.

    Det viser at variabelen foo blir satt til strengen som brukeren skrev inn da de angav samme strengen to ganger .

    Måten som $foo får verdien hello i hoveddelen av skriptet, er av følgende linjer i skallfunksjonen:

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

    der $tmp1 er strengen hello som er lagt inn av brukeren, og $1 er strengen foo sendt inn på funksjonens kommandolinje fra hoveddelen av script.

    Legg merke til at ref -variabelen er erklært med declare -n som en navnereferansevariabel, og at verdien foo er gitt som verdien i erklæringen. Dette betyr at fra det tidspunktet til variabelen går utenfor omfanget, vil enhver bruk av variabelen ref være den samme som å bruke foo. Variabelen ref er en navnereferansevariabel som refererer til foo på dette punktet.

    Dette har den konsekvens at tildeling av en verdi til ref, slik det gjøres på linjen som følger deklarasjonen, vil tildele verdien til foo.

    Verdien hello er da tilgjengelig i $foo i hoveddelen av skriptet.

    Legg igjen en kommentar

    Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *