给大家安利一下 PowerShell
创始人
2024-03-02 02:05:43
0

代码更简洁、脚本更清晰、跨平台一致性等好处是让 Linux 和 OS X 用户喜爱 PowerShell 的原因。

今年(2018)早些时候,Powershell CoreMIT 开源协议发布了正式可用版(GA)。PowerShell 算不上是新技术。自 2006 年为 Windows 发布了第一版 PowerShell 以来,PowerShell 的创建者在结合了 Unⅸ shell 的强大和灵活的同时也在弥补他们所意识到的缺点,特别是从组合命令中获取值时所要进行的文本操作。

在发布了 5 个主要版本之后,PowerShell 已经可以在所有主流操作系统上(包括 OS X 和 Linux)本地运行同样创新的 shell 和命令行环境。一些人(应该说是大多数人)可能依旧在嘲弄这位诞生于 Windows 的闯入者的大胆和冒失:为那些远古以来(从千禧年开始算不算?)便存在着强大的 shell 环境的平台引荐自己。在本帖中,我希望可以将 PowerShell 的优势介绍给大家,甚至是那些经验老道的用户。

跨平台一致性

如果你计划将脚本从一个执行环境迁移到另一个平台时,你需要确保只使用了那些在两个平台下都起作用的命令和语法。比如在 GNU 系统中,你可以通过以下方式获取昨天的日期:

date --date="1 day ago"

在 BSD 系统中(比如 OS X),上述语法将没办法工作,因为 BSD 的 date 工具需要以下语法:

date -v -1d

因为 PowerShell 具有宽松的许可证,并且在所有的平台都有构建,所以你可以把 PowerShell 和你的应用一起打包。因此,当你的脚本运行在目标系统中时,它们会运行在一样的 shell 环境中,使用与你的测试环境中同样的命令实现。

对象和结构化数据

*nix 命令和工具依赖于你使用和操控非结构化数据的能力。对于那些长期活在 sedgrepawk 环境下的人们来说,这可能是小菜一碟,但现在有更好的选择。

让我们使用 PowerShell 重写那个获取昨天日期的实例。为了获取当前日期,使用 Get-Date cmdlet(读作 “commandlet”):

> Get-Date                        

Sunday, January 21, 2018 8:12:41 PM

你所看到的输出实际上并不是一个文本字符串。不如说,这是 .Net Core 对象的一个字符串表现形式。就像任何 OOP 环境中的对象一样,它具有类型以及你可以调用的方法。

让我们来证明这一点:

> $(Get-Date).GetType().FullName
System.DateTime

$(...) 语法就像你所期望的 POSIX shell 中那样,计算括弧中的命令然后替换整个表达式。但是在 PowerShell 中,这种表达式中的 $ 是可选的。并且,最重要的是,结果是一个 .Net 对象,而不是文本。因此我们可以调用该对象中的 GetType() 方法来获取该对象类型(类似于 Java 中的 Class 对象),FullName 属性 则用来获取该类型的全称。

那么,这种对象导向的 shell 是如何让你的工作变得更加简单呢?

首先,你可将任何对象排进 Get-Member cmdlet 来查看它提供的所有方法和属性。

> (Get-Date) | Get-Member
PS /home/yevster/Documents/ArticlesInProgress> $(Get-Date) | Get-Member         


   TypeName: System.DateTime

Name                 MemberType     Definition                                 
----                 ----------     ----------                                 
Add                  Method         datetime Add(timespan value)               
AddDays              Method         datetime AddDays(double value)             
AddHours             Method         datetime AddHours(double value)            
AddMilliseconds      Method         datetime AddMilliseconds(double value)     
AddMinutes           Method         datetime AddMinutes(double value)          
AddMonths            Method         datetime AddMonths(int months)             
AddSeconds           Method         datetime AddSeconds(double value)          
AddTicks             Method         datetime AddTicks(long value)              
AddYears             Method         datetime AddYears(int value)               
CompareTo            Method         int CompareTo(System.Object value), int ...

你可以很快的看到 DateTime 对象具有一个 AddDays 方法,从而可以使用它来快速的获取昨天的日期:

> (Get-Date).AddDays(-1)

Saturday, January 20, 2018 8:24:42 PM

为了做一些更刺激的事,让我们调用 Yahoo 的天气服务(因为它不需要 API 令牌)然后获取你的本地天气。

$city="Boston"
$state="MA"
$url="https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22${city}%2C%20${state}%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys"

现在,我们可以使用老派的方法然后直接运行 curl $url 来获取 JSON 二进制对象,或者……

$weather=(Invoke-RestMethod $url)

如果你查看了 $weather 类型(运行 echo $weather.GetType().FullName),你将会发现它是一个 PSCustomObject。这是一个用来反射 JSON 结构的动态对象。

然后 PowerShell 可以通过 tab 补齐来帮助你完成命令输入。只需要输入 $weather.(确报包含了 .)然后按下 Tab 键。你将看到所有根级别的 JSON 键。输入其中的一个,然后跟上 . ,再一次按下 Tab 键,你将看到它所有的子键(如果有的话)。

因此,你可以轻易的导航到你所想要的数据:

> echo $weather.query.results.channel.atmosphere.pressure                         
1019.0

> echo $weather.query.results.channel.wind.chill                                 41

并且如果你有非结构化的 JSON 或 CSV 数据(通过外部命令返回的),只需要将它相应的排进 ConverFrom-JsonConvertFrom-CSV cmdlet,然后你可以得到一个漂亮干净的对象。

计算 vs. 自动化

我们使用 shell 用于两种目的。一个是用于计算,运行独立的命令然后手动响应它们的输出。另一个是自动化,通过写脚本执行多个命令,然后以编程的方式相应它们的输出。

我们大多数人都能发现这两种目的在 shell 上的不同且互相冲突的要求。计算任务要求 shell 简洁明了。用户输入的越少越好。但如果用户输入对其他用户来说几乎难以理解,那这一点就不重要了。脚本,从另一个角度来讲是代码。可读性和可维护性是关键。这一方面,POSIX 工具通常是失败的。虽然一些命令通常会为它们的参数提供简洁明了的语法(如:-f--force),但是命令名字本身就不简洁明了。

PowerShell 提供了几个机制来消除这种浮士德式的平衡。

首先,tab 补齐可以消除键入参数名的需要。比如:键入 Get-Random -Mi,按下 Tab 然后 PowerShell 将会为你完成参数:Get-Random -Minimum。但是如果你想更简洁一些,你甚至不需要按下 Tab。如下所示,PowerShell 可以理解:

Get-Random -Mi 1 -Ma 10

因为 MiMa 每一个都具有独立不同的补齐。

你可能已经留意到所有的 PowerShell cmdlet 名称具有动名词结构。这有助于脚本的可读性,但是你可能不想一而再、再而三的键入 Get-。所以并不需要!如果你之间键入了一个名词而没有动词的话,PowerShell 将查找带有该名词的 Get- 命令。

小心:尽管 PowerShell 不区分大小写,但在使用 PowerShell 命令是时,名词首字母大写是一个好习惯。比如,键入 date 将会调用系统中的 date 工具。键入 Date 将会调用 PowerShell 的 Get-Date cmdlet。

如果这还不够,PowerShell 还提供了别名,用来创建简单的名字。比如,如果键入 alias -name cd,你将会发现 cd 在 PowerShell 实际上时 Set-Location 命令的别名。

所以回顾以下 —— 你可以使用强大的 tab 补全、别名,和名词补全来保持命令名词简洁、自动化和一致性参数名截断,与此同时还可以享受丰富、可读的语法格式。

那么……你看呢?

这些只是 PowerShell 的一部分优势。还有更多特性和 cmdlet,我还没讨论(如果你想弄哭 grep 的话,可以查看 Where-Object 或其别称 ?)。如果你有点怀旧的话,PowerShell 可以为你加载原来的本地工具。但是给自己足够的时间来适应 PowerShell 面向对象 cmdlet 的世界,然后你将发现自己会选择忘记回去的路。


via: https://opensource.com/article/18/2/powershell-people

作者:Yev Bronshteyn 译者:sanfusu 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

相关内容

捕捉添加组成员到本地组的P...
要捕捉添加组成员到本地组的PowerShell脚本的异常,可以使用...
2025-01-12 17:02:04
不知道如何在PowerSh...
在PowerShell中,可以使用-join操作符将数组转换为字符...
2025-01-12 08:00:13
不需要PowerShell...
在Windows操作系统中,可以使用命令行中的xcopy命令来复制...
2025-01-10 14:30:49
不寻常的PowerShel...
在PowerShell中,函数和脚本块的返回值是通过return语...
2025-01-10 11:30:51
不小心设置了只允许运行Po...
打开组策略编辑器:按下Win + R,输入 gpedit.msc,...
2025-01-10 10:00:27
不同于Postman,当用...
当使用PowerShell脚本与Microsoft Graph A...
2025-01-10 00:01:49

热门资讯

Helix:高级 Linux ... 说到 基于终端的文本编辑器,通常 Vim、Emacs 和 Nano 受到了关注。这并不意味着没有其他...
使用 KRAWL 扫描 Kub... 用 KRAWL 脚本来识别 Kubernetes Pod 和容器中的错误。当你使用 Kubernet...
JStock:Linux 上不... 如果你在股票市场做投资,那么你可能非常清楚投资组合管理计划有多重要。管理投资组合的目标是依据你能承受...
通过 SaltStack 管理... 我在搜索Puppet的替代品时,偶然间碰到了Salt。我喜欢puppet,但是我又爱上Salt了:)...
Epic 游戏商店现在可在 S... 现在可以在 Steam Deck 上运行 Epic 游戏商店了,几乎无懈可击! 但是,它是非官方的。...
《Apex 英雄》正式可在 S... 《Apex 英雄》现已通过 Steam Deck 验证,这使其成为支持 Linux 的顶级多人游戏之...
如何在 Github 上创建一... 学习如何复刻一个仓库,进行更改,并要求维护人员审查并合并它。你知道如何使用 git 了,你有一个 G...
2024 开年,LLUG 和你... Hi,Linuxer,2024 新年伊始,不知道你是否已经准备好迎接新的一年~ 2024 年,Lin...
什么是 KDE Connect... 什么是 KDE Connect?它的主要特性是什么?它应该如何安装?本文提供了基本的使用指南。科技日...
Opera 浏览器内置的 VP... 昨天我们报道过 Opera 浏览器内置了 VPN 服务,用户打开它可以防止他们的在线活动被窥视。不过...