diff --git a/published/20180206 Power(Shell) to the people.md b/published/20180206 Power(Shell) to the people.md new file mode 100644 index 0000000000..6f81e417a1 --- /dev/null +++ b/published/20180206 Power(Shell) to the people.md @@ -0,0 +1,158 @@ +给大家安利一下 PowerShell +====== + +> 代码更简洁、脚本更清晰、跨平台一致性等好处是让 Linux 和 OS X 用户喜爱 PowerShell 的原因。 + +![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BUSINESS_lightbulbs.png?itok=pwp22hTw) + +今年(2018)早些时候,[Powershell Core][1] 以 [MIT][3] 开源协议发布了[正式可用版(GA)][2]。PowerShell 算不上是新技术。自 2006 年为 Windows 发布了第一版 PowerShell 以来,PowerShell 的创建者在[结合了][4] 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 命令和工具依赖于你使用和操控非结构化数据的能力。对于那些长期活在 `sed`、 `grep` 和 `awk` 环境下的人们来说,这可能是小菜一碟,但现在有更好的选择。 + +让我们使用 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` [属性][5] 则用来获取该类型的全称。 + +那么,这种对象导向的 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-Json` 或 `ConvertFrom-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 +``` + +因为 `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][6] 或其别称 `?`)。如果你有点怀旧的话,PowerShell 可以为你加载原来的本地工具。但是给自己足够的时间来适应 PowerShell 面向对象 cmdlet 的世界,然后你将发现自己会选择忘记回去的路。 + + +-------------------------------------------------------------------------------- + +via: https://opensource.com/article/18/2/powershell-people + +作者:[Yev Bronshteyn][a] +译者:[sanfusu](https://github.com/sanfusu) +校对:[wxy](https://github.com/wxy) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:https://opensource.com/users/yevster +[1]:https://github.com/PowerShell/PowerShell/blob/master/README.md +[2]:https://blogs.msdn.microsoft.com/powershell/2018/01/10/powershell-core-6-0-generally-available-ga-and-supported/ +[3]:https://spdx.org/licenses/MIT +[4]:http://www.jsnover.com/Docs/MonadManifesto.pdf +[5]:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties +[6]:https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/where-object?view=powershell-6 diff --git a/translated/tech/20180206 Power(Shell) to the people.md b/translated/tech/20180206 Power(Shell) to the people.md deleted file mode 100644 index 89553183fc..0000000000 --- a/translated/tech/20180206 Power(Shell) to the people.md +++ /dev/null @@ -1,164 +0,0 @@ -安利 Power(Shell) -====== - -![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BUSINESS_lightbulbs.png?itok=pwp22hTw) - -早些年,[Powershell Core][1] 在 [MIT][3] 开源协议下逐步开放。PowerShell 算不上是新技术。自 2006 年第一版 Windows 版的 PowerShell 发布以来,PowerShell 的创建者在合并 Unⅸ shell 的强大和灵活的同时也在弥补他们所意识到的缺点,特别是从组合命令中获取值时,所要进行的文本操作。 - -在 5 个主要版本发布之后,PowerShell 允许在所有主流操作系统上本地运行相同的 shell 和命令行环境(包括 OS X 和 Linux)。一些人(大多数)可能依旧在嘲弄这位 Windows 出生的闯入者为远古时期便存在强大 shell 环境的平台引荐自己。在本帖中,我希望可以将 PowerShell 的优势提供大部分人,甚至是那些经验老道的用户。 - -### 一致性跨平台 - -如果你计划将脚本从一个执行环境迁移到另一个平台时,你需要确保只使用了那些在两个平台下都起作用的命令和语法。比如在 GNU 系统中,你可以通过以下方式获取昨天的日期: - -``` -date --date="1 day ago" - -``` - -在 BSD 系统中(比如 OS X),上述语法将没办法工作,因为 BSD date 工具需要以下语法: - -``` -date -v -1d - -``` - -因为 PowerShell 具有宽松的许可证,并且为所有的平台都有构建,所以你可以和你的应用一起迁移 PowerShell。因此,你可以使用与你的测试环境相同的命令,将脚本运行在目标系统中。 - -### 对象和结构化的数据 - -*nix 命令和工具依赖于你的能力,来操控非结构化数据。对于那些长期活在 `sed` `grep` 和 `awk` 环境下的人们来说,这可能是小菜一碟,但现在有更好的选择。 - -让我们使用 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` [属性][5] 则用来获取该类型的全称。 - -那么,这种对象导向的 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-Json` 或 `ConvertFrom-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 -``` - -应为 `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][6] 或其别称 `?`)。如果你有点怀旧的话,PowerShell 可以为你加载本地工具。但是给自己足够的时间来适应 PowerShell 面向对象 cmdlet 的世界,然后你将发现自己会选择忘记回去的路。 - - --------------------------------------------------------------------------------- - -via: https://opensource.com/article/18/2/powershell-people - -作者:[Yev Bronshteyn][a] -译者:[sanfusu](https://github.com/sanfusu) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://opensource.com/users/yevster -[1]:https://github.com/PowerShell/PowerShell/blob/master/README.md -[2]:https://blogs.msdn.microsoft.com/powershell/2018/01/10/powershell-core-6-0-generally-available-ga-and-supported/ -[3]:https://spdx.org/licenses/MIT -[4]:http://www.jsnover.com/Docs/MonadManifesto.pdf -[5]:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties -[6]:https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/where-object?view=powershell-6