PowerShell: Est-il une variable automatique pour le dernier résultat de l'exécution?
Je suis à la recherche d'une fonctionnalité comparable à Python shell interactif de "_" à la variable. Dans PowerShell je veux quelque chose comme ceci:
> Get-Something # this returns an object and display it to the output.
# Now I want to assign that object to some variable
> $anObj = ???
Vous devez vous connecter pour publier un commentaire.
Non, il n'est pas variable automatique comme ça.
Que vous avez à faire:
pour obtenir le comportement
$$
et$^
(dont les cas d'utilisation m'échappe) mais rien de comparable à%
ouANS
ou_
dans beaucoup d'autres coquillages/repls?Comme indiqué, il n'y a pas intégré de soutien pour cela, mais voici
un simple, mais sous-optimale PSv3+ personnalisé solution:
Remarque:
Pour une bonne, mais une solution non triviale, voir BartekB de réponse utile.
Il y a un feature request sur Github pour construire cette fonctionnalité dans un avenir PowerShell de Base version (la version actuelle de cette écriture est PowerShell Core 6.1.0).
Ajouter les éléments suivants à votre
$PROFILE
fichier:Quel est le nom de la variable - par exemple,
$__
(2 underscores) - est jusqu'à vous, mais méfiez-vous des collisions de nom, notamment avec$_
, le automatique variable qui représente l'entrée de l'objet à portée de main dans un certain nombre de contextes.Cela permettra de capturer le terminal lié sortie de la dernière commande exécutée [qui produit la sortie du terminal] dans la variable
$__
dans vos sessions interactives, sauf pour les commandes qui appel unFormat-*
mise en forme de la cmdlet explicitement,par voie de PowerShell de la capacité à l'échelle mondiale des paramètres prédéfinis par défaut - voir
Get-Help about_Parameters_Default_Values
.-OutVariable
est un paramètre commun conçue pour recueillir un applet de commande et /ou de l'avancée de la fonction de sortie des objets dans une variable, et la définition ci-dessus s'applique ce paramètre implicitement à tousOut-Default
appels, qui, à son tour, est appelée derrière les scènes à chaque fois que PowerShell sorties quelque chose à la borne - toutefois, note l'exceptionFormat-*
applets de commande.Mises en garde:
Comme indiqué, de sortie des commandes que l'utilisation d'une applet de mise en forme -
Format-Custom
,Format-Hex
,Format-List
,Format-Table
, ouFormat-Wide
- ne pas être capturé.$PSDefaultParameterValues['Format-*:OutVariable'] = '__'
, mais, malheureusement, cela permettrait de recueillir objets de mise en forme (instructions) plutôt que de la de données d'origine dans$__
, ce qui est indésirable.Une belle petite solution de contournement est de capturer
Format-*
de sortie dans un différents variable, qui non seulement exige que vous pensez variables dont vous avez besoin pour cible, mais vous aurez encore seulement voir le formatage des objets plutôt que des données, et, depuisFormat-*
applets de commande sont impliqués derrière les scènes, même si vous ne les utilisez pas explicitement, la sortie de commandes sansFormat-*
appels est alors capturé deux fois - une fois que les données, en$__
, et encore que les objets de mise en forme, dans l'autre variable.En raison d'un conception caprice,
$__
sera toujours contenir un tableau liste (de type[System.Collections.ArrayList]
), même si la commande précédente sortie seulement un unique objet. En cas de doute, utilisez$__[0]
pour faire référence à un seul objet de sortie.Méfiez-vous des commandes de production de très grande sortie de jeux, parce que
$__
la collecte dans la mémoire.$__
ne capturer des objets en sortie de la terminal - tout comme_
n'en Python, une commande qui ne produit aucune sortie ou$null
/un tableau de$null
s feuilles précédentes$__
valeur intacte.Dernière option qui nécessite le plus de travail, mais de l'OMI vous donne ce que vous demandez: créer un proxy qui va remplacer Out par Défaut (qui est toujours appelé implicitement à la fin de pipeline, si vous n'avez pas hors-* à autre chose).
Jeffrey snover fait a fait une présentation sur elle au cours de l'une de PowerShell Plongées Profondes (je crois que c'était le premier) - vous pouvez trouver des scripts qu'il a utilisé (y compris au-dessus mentionnés hors défaut) sur Dmitry Sotnikov blog. Vous pouvez aussi regarder vidéo pour comprendre tout le concept.
Vous pouvez également imprimer le résultat de la commande et de la capture de l'objet de sortie(s) en utilisant le paramètre OutVariable, plus tard, puis utiliser $anObj pour afficher le contenu des variables.
Pas exactement. Il y a le $_ valeur automatique qui contient l'objet en cours dans le pipe-line.
Le pipeline est la façon habituelle de passer d'un résultat à partir d'une applet de commande à l'autre, et les applets de commande sont configurés pour accepter les paramètres à partir de la canalisation ou de l'propriétés des objets dans le pipeline, ce qui rend l'utilisation d'un "dernier résultat" variable non pertinente.
Encore certaines situations nécessitent une référence spécifique à la "courante" de l'objet et, pour ceux d'il y a le $_ valeur automatique.
Voici un exemple de son utilisation: À l'aide de la Cmdlet where-Object et voici une liste de powershell automatique de variables: Chapitre 4. PowerShell Variables Automatiques
Script en powershell nécessite un style différent de celui de la programmation en Python (comme Python exige un style différent de celui de C++.)
Powershell est construit de telle sorte que les tuyaux sont largement utilisés, si vous voulez briser en place d'un pipeline de plus de procédure, étape par étape, de la structure, vous aurez besoin pour enregistrer vos résultats dans les variables nommées pas automatiques.
Comment au sujet de l'invocation de la dernière commande avec "r" (alias pour Invoquer-Histoire), et en l'enveloppant dans des parenthèses() pour exécuter d'abord?
Oui ce rediffusions de la dernière commande, mais dans mon cas d'utilisation c'est de loin la plus simple solution, en particulier pour les moments où je ne réalise pas vraiment que je vais devoir les dernières commandes de sortie au premier abord.
Il conserve également la structure de l'objet intact.
Utiliser le module PowerShellCookbook et ajouter un appel à Add-ObjectCollector à votre script de démarrage
Pour mon cas d'utilisation spécifiques, j'ai été l'exécution d'un fichier de commandes à partir de PowerShell, et je voulais imprimer la sortie de ce fichier de commandes en temps réel ET d'enregistrer le résultat dans une variable. J'ai été en mesure d'accomplir par la tuyauterie de la sortie de mon opérateur d'appel de
Tee-Object
:La première commande configure mes arguments pour le fichier de commandes. La deuxième commande exécute le fichier de commandes à l'aide de l'opérateur d'appel avec mes arguments, et il les tuyaux de la sortie de la
Tee-Object
de commande, qui imprime la sortie en temps réel à partir de l'appel de l'opérateur, mais enregistre également toutes les informations dans une nouvelle variable appelée sortie. La dernière fonction, il suffit de copier le contenu de$output
dans le presse-papiers.Tee-Object
aussi permet d'enregistrer la sortie dans un fichier (codage Unicode), et si j'ai besoin d'enregistrer dans un fichier et une variable (en plus de l'impression à la console), je peux chaîner les appels àTee-Object
ensemble dans un pipeline. Voir ce lien pour plus d'informations:https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/tee-object
Une approche qui a fonctionné pour moi est de traiter la sortie de la commande avec
Select-Object
comme un pass-through. Par exemple, j'ai eu une console EXE que la sortie des résultats détaillés destderr
et significative de sortie destdout
, de qui je voulais capturer uniquement la dernière ligne.La façon dont ce script a été invoquée, ayant de sortie sur PowerShell est
Error
flux de sortie a été considéré comme une erreur de disque dur, qui n'a pas de maillage très bien avec la façon PowerShell prend les applications externes'stderr
de sortie et la transforme enError
de sortie. Cette approche d'emballage de la sortie m'a permis de contrôler la façon dont il est passé à travers, ainsi que la capture de lastdout
la ligne que je voulais. Il me semble que ce serait une assez approche flexible qui vous permettra d'intercepter de sortie et de faire ce que vous voulez avec elle car elle passe à travers. Par exemple: