Variables en PowerShell
Si vas a utilizar PowerShell como una shell puede ser que no necesites variables, aunque me extrañaría. Sin embargo, si vas a realizar scripts, va a ser muy difícil que consigas escapar de ellas. Tarde o temprano necesitarás hacer uso de variables para poder sacar el máximo partido a tus scripts. No siempre es posible encadenar comandos, por distintas razones, como por ejemplo, porque sea necesario realizar un tratamiento previo de la información que sacas en un paso anterior.
Sea como fuere, en este capítulo sobre PowerShell, el objetivo es tratar con las variables, ver como se definen y conocer como se trabaja con ellas.
Variables en PowerShell
¿Que es una variable y como se utilizan en PowerShell?
Una variable, no es ni mas ni menos, que un espacio en memoria donde guardar información. Un espacio con un nombre. Dado que es necesario tener identificado a ese espacio para poder guardar o sacar esa información.
En el caso de PowerShell la forma de identificar esos espacios en memoria es mediante una cadena de texto precedida por $
. Por ejemplo, $variable
.
Respecto a los nombres que les puedes asignar a las variables algunas observaciones,
- no distinguen entre mayúsculas y minúsculas. Es decir que
$VARiable
es exactamente la misma que$variable
. - La cadena de texto que define el nombre de la variable puede contener algunos categorías de caracteres unicode, el carácter
_
y el carácter?
. - Lo mas recomendable a la hora de crear tus propios nombres de variables es que utilices exclusivamente carácteres alfanuméricos y el carácter
_
. La razón para esto es que el uso de otros carácteres te puede complicar el uso de estas variables. - Para utilizar variables que incluyan espacios o caracteres especiales tienes que encerrar el nombre de la variable entre
{}
. Por ejemplo,
PS /home/lorenzo> ${esta variable con espacios}=contenido
PS /home/lorenzo> Write-Output ${esta variable con espacios}
contenido
Variables especiales
Existen algunas variables especiales o automáticas o definidas por defecto. Variables que guardan información de estado. En general, estas variables se consideran de solo lectura, aunque es posible escribir en ellas, pero, no es recomendable hacerlo, por cuestiones de compatibilidad con versiones anteriores.
Algunas de estas variables son las siguientes,
$$
contiene el último token en la última línea recibida por la sesión. En el siguiente ejemplo la última línea recibida por la sesión esWrite-Output 1 2.
Por ejemplo,
PS > Write-Output 1 2
1
2
PS > Write-Output $$
2
$^
contiene el primer token en la última línea recibida por la sesión. Es decir, básicamente, justo lo contrario a la anterior solución. Por ejemplo.
PS > Write-Output 1 2
1
2
PS > Write-Output $^
Write-Output
$?
esta variable contiene el estado de la ejecución del último comando. Si el resultado de la ejecución del último comando ha sido satisfactorio contendráTrue
y en otro caso contendráFalse
. Por ejemplo, si a las bravas escribes un error, verás que el resultado de la ejecución esFalse
,
PS > Write-Error "Mal"
Write-Error: Mal
PS > Write-Output $?
False
$args
esta variable contiene un vector de valores de los parámetros que se pasan a una función o a un script.$Error
contiene un vector, array, de los últimos errores ordenados de mas reciente a menos, de forma que el error mas reciente es$Error[0]
.$HOME
contiene la ruta absoluta al directorio de inicio del usuario.$IsLinux
,$IsWindows
y$IsMacOS
devuelvenTrue
si se corresponden con el sistema operativo, en otro caso devolveránFalse
.$true
,$false
,$null
conienen respectivamenteTrue
,False
yNull
.
Estas son solo algunas de las variables definidas por defecto por PowerShell, puedes encontrar mas en variables automáticas de PowerShell
Trabajando con variables en PowerShell
Para definir una variable es tan sencillo como hacer lo siguiente,
$variable = 1
De la misma manera puedes crear una variable que contenga una cadena de texto,
$variable = "Hola mundo"
O incluso que contenga un vector de enteros.
$variable = 1, 2, 3
De la misma manera puedes guardar el resultado de la ejecución de un cmdlet en una variable para utilizarlo posteriormente. Esto es especialmente cómodo cuando el resultado es un objeto y quieres utilizar alguno de los métodos del objeto. Por ejemplo, puedes guardar todos los procesos que están corriendo en tu sistema utilizando la siguiente instrucción,
$procesos = Get-Process
Si quieres obtener el primero de los procesos, dado que se trata de un vector de procesos, tan solo tienes que ejecutar Write-Output $procesos[0]
. Recuerda que siempre puedes utilizar el alias echo
, como en echo $procesos[0]
.
Así, por ejemplo si quisieras saber cuando comenzó ese proceso, tan solo tienes que ejecutar,
echo $procesos[0].StartTime
Recuerda que para ver todos los métodos y propiedades que aplican a un determinado objeto siempre puedes utilizar echo $procesos[0] | Get-Member
.
Pongamos que ahora quieres seleccionar uno de los procesos. Por ejemplo, cupsd
. Esto lo puedes hacer, tal y como viste en el capítulo anterior, utilizando,
echo $procesos | Where-Object -Property ProcessName -eq cupsd
Es mas, ahora puedes asignar este proceso a una variable, por ejemplo, y por ser algo original a $cupsd
. ¿Como?
$cupsd = (echo $procesos | Where-Object -Property ProcessName -eq cupsd)
Y ahora, de nuevo, como has hecho anteriormente, puedes obtener el momento en el que se inició este proceso con $cupsd.StartTime
. Recuerda, que aunque yo esté respetando mayúsculas y minúsculas, es totalmente equivalente $cupsd.StartTime
a $cupsd.starttime
.
Operaciones con variables en PowerShell
Una vez asignado un valor a una variable. Es posible eliminar su contenido. Para ello tienes dos opciones. O bien utilizando el cmdlet Clear-Variable
como en el ejemplo siguiente,
Clear-Variable -Name cupsd
O bien directamente asignado $null
a la variable como en este otro ejemplo,
$cupsd = $null
Para eliminar la variable tienes que utilizar el comando Remove-Variable
como en el ejemplo,
Remove-Variable -Name cupsd
Ahora es posible que te estés preguntando que diferencia hay entre eliminar el contenido y eliminar la variable. La cuestión es que aunque elimines el contenido de una variable esta sigue existiendo. ¿Como puedes saber si una variable existe?. Para ello, tienes que utilizar el cmdlet Get-Variable
. Por ejemplo,
Get-Variable -Name cupsd
En el caso de que la variable exista, te devolverá su valor o, si has eliminado el contenido, te devolverá vacío, pero algo te devuelve. Por el contrario. Si, has eliminado la variable, tendrás algo como lo que te muestro en el siguiente ejemplo,
PS > Get-Variable -Name cupsd
Get-Variable: Cannot find a variable with the name 'cupsd'.
Tipos de variables
PowerShell no es tipado, por defecto. Esto quiere decir que puedes guardar cualquier tipo de dato en cualquier variable. Si quieres saber que tipo de dato contiene una variable, puedes utilizar el método GetType
. Recuerda, de nuevo, que para conocer propiedades y métodos tienes que utilizar GetMember
… Para que veas algunos ejemplos,
PS > $variable = 3.1415; $variable.GetType().Name
Double
PS > $variable = 3.1415, "atareao.es"; $variable.GetType().Name
Object[]
PS > $variable = "atareao.es"; $variable.GetType().Name
String
Sin embargo, a pesar de que, por defecto, PowerShell no sea tipado, puedes definir el tipo de las variables. Para ello, tienes que preceder al nombre de la variable del tipo que le quieres asignar entre corchetes. Por ejemplo,
[double]$variable = 3.1415;
Eso si, la variable $variable
no debe estar definida definida, o debe estar a $null
, o de lo contrario dará un error similar al que te muestro en el siguiente ejemplo,
PS > [double]$variable
InvalidArgument: Cannot convert value "atareao.es" to type "System.Double". Error: "Input string was not in a correct format."
Por otro lado, si a una variable que hayas definido de un tipo, le asignas un valor de otro tipo lo intentará convertir, y en caso de que no lo consiga arrojará un error. Por ejemplo, si defines una variable del tipo string
y le asignas un int
, convertirá el int
a string
, conforme te muestro en el siguiente ejemplo,
PS> [string]$variable = 12
PS> echo $variable.GetType().Name
String
El infierno de las comillas
El comportamiento de las comillas en PowerShell es similar al que te encontrar en otras intérpretes de comandos como puede ser por ejemplo Bash, del cual te recuerdo tienes un excelente tutorial sobre Scripts en Bash. Así, si utilizas dobles comillas, la variable se reemplazará por su contenido, mientras que si utilizas simples, se utilizará el nombre de la variable. Por ejemplo.
PS> $variable = 3.141592
PS> Write-Output "La variable contiene $variable"
La variable contiene 3.141592
PS> Write-Output 'La variable contiene $variable'
La variable contiene $variable
Pero todavía tienes una opción también interesante que te muestro en el siguiente ejemplo,
PS> $variable = 3.141592
PS> Write-Output "La variable `$variable contiene $variable"
La variable $variable contiene 3.141592
Al preceder la variable con «« se muestra el nombre de la variable en lugar de su contenido.
Sobre el ámbito de actuación
Las variables en PowerShell tienen un vida que se circunscribe al ámbito en el que fueron creadas. Como veremos en un capítulo posterior, cuando definas una variable dentro de una función, esta variable, solo estará disponible dentro de esa función. Y lo mismo sucede para el caso de variables que definas en scripts. Sin embargo es posible definir variables con un ámbito global. Para ello, tienes que preceder el nombre la variable de la palabra Global. Por ejemplo,
PS > $Global:variable=1
PS > echo $variable
1
Conclusiones
Ha sido este un capítulo intenso, pero es que las variables en PowerShell, lo cierto es que dan mucho de si, y en capítulos posteriores las vas a poder exprimir al máximo, tanto en funciones como en otros apartados.
Más información,
Imagen de portada de Pankaj Patel en Unsplash
La entrada Variables en PowerShell aparece primero en Atareao.