Negli script batch, le modifiche alle variabili di ambiente hanno un impatto globale sulla sessione corrente per impostazione predefinita. Per PowerShell, l'esatto contrario è vero perché gli ambiti vengono utilizzati per isolare le modifiche di uno script. Qui, esamineremo come gli scope influenzano gli script di PowerShell e come lavorare dentro e intorno a loro.
In PowerShell, un "scope" si riferisce all'ambiente corrente in cui una shell di script o comando sta funzionando. Gli ambiti vengono utilizzati per proteggere determinati oggetti all'interno dell'ambiente da modifiche involontarie di script o funzioni. In particolare, le seguenti cose sono protette dalle modifiche da comandi eseguiti da un altro ambito, se non diversamente specificato dai parametri in questi comandi:
Nuovi ambiti vengono creati ogni volta che si esegue uno script o una funzione o quando si crea una nuova sessione o istanza di PowerShell. Gli ambiti creati eseguendo script e funzioni hanno una relazione "genitore / figlio" con l'ambito da cui sono stati creati. Esistono alcuni ambiti che hanno significati particolarmente speciali e sono accessibili per nome:
Gli ambiti possono anche essere indicati in base al numero in alcuni comandi, in cui l'ambito corrente viene indicato come zero e i relativi antenati vengono referenziati aumentando gli interi. Ad esempio, all'interno di uno script eseguito dall'ambito Globale, l'ambito Script sarebbe 0 e l'ambito Globale sarebbe 1. Un ambito ulteriormente nidificato nell'ambito Script, come una funzione, farebbe riferimento all'ambito Globale come 2 I numeri negativi non funzioneranno per fare riferimento agli ambiti figlio - il motivo per questo sarà evidente a breve.
Come accennato in precedenza, i comandi eseguiti all'interno di un ambito non influenzeranno le cose in un altro ambito a meno che non fare così. Ad esempio, se $ MyVar esiste nell'ambito globale e uno script esegue un comando per impostare $ MyVar su un valore diverso, la versione globale di $ MyVar rimarrà inalterata mentre una copia di $ MyVar viene inserita nello scope Script con il nuovo valore. Se un $ MyVar non esiste, uno script lo creerà all'interno dell'ambito Script per impostazione predefinita, non nell'ambito globale. Questo è importante da ricordare quando si apprende la reale relazione genitore / figlio tra gli ambiti.
La relazione genitore / figlio degli ambiti in PowerShell è a senso unico. I comandi possono vedere in, e facoltativamente modificare, l'ambito corrente, il suo genitore e qualsiasi ambito sopra quello. Tuttavia, non possono vedere o modificare le cose in nessun bambino nell'ambito corrente. Ciò è principalmente dovuto al fatto che, una volta spostato in un ambito genitore, l'ambito figlio è già stato distrutto perché ha raggiunto il suo scopo. Ad esempio, perché dovresti vedere o modificare una variabile nell'ambito Script, dall'ambito Globale, dopo che lo script è terminato? Esistono molti casi in cui è necessario che le modifiche di uno script o di una funzione persistano oltre il suo completamento, ma non così tante in cui è necessario apportare modifiche agli oggetti all'interno dello scope o dell'ambito della funzione prima o dopo l'esecuzione. (Di solito, tali cose saranno gestite comunque come parte della sceneggiatura o funzione stessa.)
Naturalmente, quali sono le regole senza eccezioni? Un'eccezione a quanto sopra sono gli ambiti privati. Gli oggetti negli ambiti privati sono accessibili solo ai comandi eseguiti nell'ambito nell'ambito del quale sono stati creati. Un'altra importante eccezione sono gli oggetti che hanno la proprietà AllScope. Queste sono variabili speciali e alias per i quali una modifica in qualsiasi ambito influenzerà tutti gli ambiti. I seguenti comandi mostreranno quali variabili e alias hanno la proprietà AllScope:
Ottieni-Variabile | Where-Object {$ _. Options -match 'AllScope'} Get-Alias | Where-Object {$ _. Options -match 'AllScope')
Per il nostro primo sguardo agli ambiti in azione, inizieremo in una sessione di PowerShell in cui è stata impostata la variabile $ MyVar a una stringa, 'I am a global variable!', dalla riga di comando. Quindi, lo script seguente verrà eseguito da un file denominato Scope-Demo.ps1:
Funzione FunctionScope {'Modifica $ MyVar con una funzione.' $ MyVar = 'Sono stato impostato da una funzione!' "MyVar dice $ MyVar"} "Verifica il valore corrente di $ MyVar." "MyVar dice $ MyVar" "Modifica $ MyVar per script." $ MyVar = 'Sono stato impostato da uno script!' "MyVar dice $ MyVar" "FunctionScope" Controllo del valore finale di MyVar prima dell'uscita dallo script. ' "MyVar dice $ MyVar" "
Se gli script di PowerShell funzionavano allo stesso modo degli script batch, ci aspettiamo che il valore di $ MyVar (o% MyVar% in sintassi batch) cambi da" I am a global variable! ", a "Sono stato impostato da uno script!", e infine a "Sono stato impostato da una funzione!" dove rimarrà fino a quando non viene esplicitamente modificato di nuovo o la sessione viene interrotta. Tuttavia, guarda cosa succede realmente qui mentre ci spostiamo attraverso ciascuno degli ambiti - in particolare, dopo che la funzione FunctionScope ha completato il suo lavoro e controlliamo nuovamente la variabile dallo Script , e successivamente Global, scope.
Come puoi vedere, la variabile è sembrata cambiare mentre ci muovevamo attraverso lo script perché, fino a quando la funzione FunctionScope non veniva completata, stavamo controllando la variabile dallo stesso scope che era l'ultima cambiato dopo la fine di FunctionScope, siamo tornati nello scope Script dove $ MyVar non è stato toccato dalla funzione, quindi, quando lo script è stato terminato, siamo tornati nello scope Globale dove non era stato affatto modificato.
Quindi, tutto questo è utile per evitare di applicare accidentalmente modifiche all'ambiente oltre agli script e alle funzioni, ma cosa succede se in realtà si desidera apportare tali modifiche ni? Esiste una sintassi speciale e abbastanza semplice per la creazione e la modifica di oggetti oltre l'ambito locale. Basta inserire il nome dell'ambito all'inizio del nome della variabile e inserire due punti tra l'ambito e i nomi delle variabili. In questo modo:
$ global: MyVar $ script: MyVar $ locale: MyVar
È possibile utilizzare questi modificatori sia durante la visualizzazione e l'impostazione delle variabili. Vediamo cosa succede con questo script dimostrativo:
Funzione FunctionScope {"Modifica $ MyVar nell'ambito della funzione locale ... '$ locale: MyVar =" Questo è MyVar nell'ambito locale della funzione. "' Modifica di $ MyVar nell'ambito dello script ... '$ script: MyVar =' MyVar era impostato da uno script, ora impostato da una funzione. "Modifica $ MyVar nell'ambito globale ... '$ global: MyVar =' MyVar è stato impostato nell'ambito globale. Ora impostato da una funzione. "Verifica $ MyVar in ogni ambito ... '" Locale: $ locale: MyVar " Script: $ script: MyVar " Globale: $ globale: MyVar "} "Ottieni il valore corrente di $ MyVar.' "MyVar dice $ MyVar" "Modifica $ MyVar per script." $ MyVar = 'Sono stato impostato da uno script!' "MyVar dice $ MyVar" FunctionScope "Controllo di $ MyVar dall'ambito dello script prima di uscire. ' "MyVar dice $ MyVar" "
Come prima, inizieremo impostando la variabile nel Global scope e terminando con il controllo del risultato dell'ambito Global finale.
Qui puoi vedere che FunctionScope è stato in grado di cambiare la variabile nello scope Script e le modifiche persistono dopo che è stata completata. Inoltre, la modifica alla variabile nello scope Globale persisteva anche dopo che lo script era terminato. Ciò può essere particolarmente utile se si devono cambiare ripetutamente variabili all'interno di uno script , o nell'ambito Global, usando lo stesso codice - devi solo definire una funzione o uno script che è scritto per modificare la variabile dove e come ne hai bisogno, e chiamaci quando sono necessarie tali modifiche.
Come accennato in precedenza, i numeri degli scope possono anche essere usati in certi comandi per modificare la variabile a diversi livelli in relazione all'ambito locale. Ecco lo stesso script usato nel secondo esempio sopra, ma con la funzione modificata per usare i comandi Get-Variable e Set-Variable con scope num bers invece di fare riferimento direttamente alla variabile con scope nominati:
Funzione FunctionScope {"Modifica $ MyVar nell'ambito 0, relativo a FunctionScope ... 'Set-Variabile MyVar" Questo è MyVar nell'ambito della funzione 0. "-Scope 0' Modifica $ MyVar nell'ambito 1, relativo a FunctionScope ... 'Set-Variable MyVar MyVar è stato modificato nell'ambito 1, da una funzione. ' -Scope 1 'Modifica $ MyVar nell'ambito 2, relativo a Functionscope ...' Set-Variabile MyVar 'MyVar è stato modificato nell'ambito 2, da una funzione.' -Scope 2 "Controllo $ MyVar in ogni ambito ..." Ambito 0: 'Ottieni-Variabile MyVar -Scope 0 -ValueOnly' Ambito 1: 'Ottieni-Variabile MyVar -Scope 1 -ValueOnly' Ambito 2: 'Ottieni-Variabile MyVar -Scope 2 -ValueOnly "}" Ottieni il valore corrente di $ MyVar. ' "MyVar dice $ MyVar" "Modifica $ MyVar per script." $ MyVar = 'Sono stato impostato da uno script!' "MyVar dice $ MyVar" FunctionScope "Controllo di $ MyVar dall'ambito dello script prima di uscire. ' "MyVar dice $ MyVar" "
Simile a prima, possiamo vedere qui come i comandi in un ambito possono modificare gli oggetti nel suo ambito genitore.
C'è ancora molto altro che può essere fatto con gli ambiti In questo articolo gli ambiti hanno un impatto maggiore delle semplici variabili e c'è ancora molto da imparare sugli ambiti privati e le variabili di AllScope. Per ulteriori informazioni utili, è possibile eseguire il seguente comando da PowerShell:
Get-Help about_scopes
Lo stesso file di aiuto è disponibile anche su TechNet.
Scope image credit: spadassin on openclipart
Come accedere al desktop Linux con Google Authenticator
Per maggiore sicurezza, è possibile richiedere un token di autenticazione basato sul tempo e una password per accedere al proprio PC Linux. Questa soluzione utilizza Google Authenticator e altre app TOTP. Questo processo è stato eseguito su Ubuntu 14.04 con il desktop Unity standard e il gestore di accesso LightDM, ma i principi sono gli stessi nella maggior parte delle distribuzioni e desktop Linux.
Come Samsung ha vinto su un incubo con il Galaxy S7
Samsung mi ha finalmente conquistato. Ho odiato i telefoni Samsung Samsung per molto tempo, praticamente finché Samsung ha state facendo telefoni Android. Ho dato loro vari tentativi nel corso degli anni, e ognuno di loro mi ha lasciato con il forte desiderio di gettare il telefono attraverso la stanza (e l'ho fatto, una volta).