给大家安利一下 PowerShell
代码更简洁、脚本更清晰、跨平台一致性等好处是让 Linux 和 OS X 用户喜爱 PowerShell 的原因。
今年(2018)早些时候,Powershell Core 以 MIT 开源协议发布了正式可用版(GA)。PowerShell 算不上是新技术。自 2006 年为 Windows 发布了第一版 PowerShell 以来,PowerShell 的创建者在结合了 Unⅸ shell 的强大和灵活的同时也在弥补他们所意识到的缺点,特别是从组合命令中获取值时所要进行的文本操作。
在发布了 5 个主要版本之后,PowerShell 已经可以在所有主流操作系统上(包括 OS X 和 Linux)本地运行同样创新的 shell 和命令行环境。一些人(应该说是大多数人)可能依旧在嘲弄这位诞生于 Windows 的闯入者的大胆和冒失:为那些远古以来(从千禧年开始算不算?)便存在着强大的 shell 环境的平台引荐自己。在本帖中,我希望可以将 PowerShell 的优势介绍给大家,甚至是那些经验老道的用户。
跨平台一致性
如果你计划将脚本从一个执行环境迁移到另一个平台时,你需要确保只使用了那些在两个平台下都起作用的命令和语法。比如在 GNU 系统中,你可以通过以下方式获取昨天的日期:
1 |
|
在 BSD 系统中(比如 OS X),上述语法将没办法工作,因为 BSD 的 date 工具需要以下语法:
1 |
|
因为 PowerShell 具有宽松的许可证,并且在所有的平台都有构建,所以你可以把 PowerShell 和你的应用一起打包。因此,当你的脚本运行在目标系统中时,它们会运行在一样的 shell 环境中,使用与你的测试环境中同样的命令实现。
对象和结构化数据
*nix 命令和工具依赖于你使用和操控非结构化数据的能力。对于那些长期活在 sed
、 grep
和 awk
环境下的人们来说,这可能是小菜一碟,但现在有更好的选择。
让我们使用 PowerShell 重写那个获取昨天日期的实例。为了获取当前日期,使用 Get-Date
cmdlet(读作 “commandlet”):
1 |
|
你所看到的输出实际上并不是一个文本字符串。不如说,这是 .Net Core 对象的一个字符串表现形式。就像任何 OOP 环境中的对象一样,它具有类型以及你可以调用的方法。
让我们来证明这一点:
1 |
|
$(...)
语法就像你所期望的 POSIX shell 中那样,计算括弧中的命令然后替换整个表达式。但是在 PowerShell 中,这种表达式中的 $
是可选的。并且,最重要的是,结果是一个 .Net 对象,而不是文本。因此我们可以调用该对象中的 GetType()
方法来获取该对象类型(类似于 Java 中的 Class
对象),FullName
属性 则用来获取该类型的全称。
那么,这种对象导向的 shell 是如何让你的工作变得更加简单呢?
首先,你可将任何对象排进 Get-Member
cmdlet 来查看它提供的所有方法和属性。
1 |
|
你可以很快的看到 DateTime 对象具有一个 AddDays
方法,从而可以使用它来快速的获取昨天的日期:
1 |
|
为了做一些更刺激的事,让我们调用 Yahoo 的天气服务(因为它不需要 API 令牌)然后获取你的本地天气。
1 |
|
现在,我们可以使用老派的方法然后直接运行 curl $url
来获取 JSON 二进制对象,或者……
1 |
|
如果你查看了 $weather
类型(运行 echo $weather.GetType().FullName
),你将会发现它是一个 PSCustomObject
。这是一个用来反射 JSON 结构的动态对象。
然后 PowerShell 可以通过 tab 补齐来帮助你完成命令输入。只需要输入 $weather.
(确报包含了 .
)然后按下 Tab
键。你将看到所有根级别的 JSON 键。输入其中的一个,然后跟上 .
,再一次按下 Tab
键,你将看到它所有的子键(如果有的话)。
因此,你可以轻易的导航到你所想要的数据:
1 |
|
并且如果你有非结构化的 JSON 或 CSV 数据(通过外部命令返回的),只需要将它相应的排进 ConverFrom-Json
或 ConvertFrom-CSV
cmdlet,然后你可以得到一个漂亮干净的对象。
计算 vs. 自动化
我们使用 shell 用于两种目的。一个是用于计算,运行独立的命令然后手动响应它们的输出。另一个是自动化,通过写脚本执行多个命令,然后以编程的方式相应它们的输出。
我们大多数人都能发现这两种目的在 shell 上的不同且互相冲突的要求。计算任务要求 shell 简洁明了。用户输入的越少越好。但如果用户输入对其他用户来说几乎难以理解,那这一点就不重要了。脚本,从另一个角度来讲是代码。可读性和可维护性是关键。这一方面,POSIX 工具通常是失败的。虽然一些命令通常会为它们的参数提供简洁明了的语法(如:-f
和 --force
),但是命令名字本身就不简洁明了。
PowerShell 提供了几个机制来消除这种浮士德式的平衡。
首先,tab 补齐可以消除键入参数名的需要。比如:键入 Get-Random -Mi
,按下 Tab
然后 PowerShell 将会为你完成参数:Get-Random -Minimum
。但是如果你想更简洁一些,你甚至不需要按下 Tab
。如下所示,PowerShell 可以理解:
1 |
|
因为 Mi
和 Ma
每一个都具有独立不同的补齐。
你可能已经留意到所有的 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