translation finished

This commit is contained in:
sanfusu 2019-03-17 21:17:41 +08:00
parent 6fac4fbb0b
commit e06100e0f8
2 changed files with 164 additions and 157 deletions

View File

@ -1,157 +0,0 @@
sanfusu is translating
Power(Shell) to the people
======
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BUSINESS_lightbulbs.png?itok=pwp22hTw)
Earlier this year, [PowerShell Core][1] [became generally available][2] under an Open Source ([MIT][3]) license. PowerShell is hardly a new technology. From its first release for Windows in 2006, PowerShell's creators [sought][4] to incorporate the power and flexibility of Unix shells while remedying their perceived deficiencies, particularly the need for text manipulation to derive value from combining commands.
Five major releases later, PowerShell Core allows the same innovative shell and command environment to run natively on all major operating systems, including OS X and Linux. Some (read: almost everyone) may still scoff at the audacity and/or the temerity of this Windows-born interloper to offer itself to platforms that have had strong shell environments since time immemorial (at least as defined by a millennial). In this post, I hope to make the case that PowerShell can provide advantages to even seasoned users.
### Consistency across platforms
If you plan to port your scripts from one execution environment to another, you need to make sure you use only the commands and syntaxes that work. For example, on GNU systems, you would obtain yesterday's date as follows:
```
date --date="1 day ago"
```
On BSD systems (such as OS X), the above syntax wouldn't work, as the BSD date utility requires the following syntax:
```
date -v -1d
```
Because PowerShell is licensed under a permissive license and built for all platforms, you can ship it with your application. Thus, when your scripts run in the target environment, they'll be running on the same shell using the same command implementations as the environment in which you tested your scripts.
### Objects and structured data
*nix commands and utilities rely on your ability to consume and manipulate unstructured data. Those who have lived for years with `sed` `grep` and `awk` may be unbothered by this statement, but there is a better way.
Let's redo the yesterday's date example in PowerShell. To get the current date, run the `Get-Date` cmdlet (pronounced "commandlet"):
```
> Get-Date                        
Sunday, January 21, 2018 8:12:41 PM
```
The output you see isn't really a string of text. Rather, it is a string representation of a .Net Core object. Just like any other object in any other OOP environment, it has a type and most often, methods you can call.
Let's prove this:
```
> $(Get-Date).GetType().FullName
System.DateTime
```
The `$(...)` syntax behaves exactly as you'd expect from POSIX shells—the result of the evaluation of the command in parentheses is substituted for the entire expression. In PowerShell, however, the $ is strictly optional in such expressions. And, most importantly, the result is a .Net object, not text. So we can call the `GetType()` method on that object to get its type object (similar to `Class` object in Java), and the `FullName` [property][5] to get the full name of the type.
So, how does this object-orientedness make your life easier?
First, you can pipe any object to the `Get-Member` cmdlet to see all the methods and properties it has to offer.
```
> (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 ...
```
You can quickly see that the DateTime object has an `AddDays` that you can quickly use to get yesterday's date:
```
> (Get-Date).AddDays(-1)
Saturday, January 20, 2018 8:24:42 PM
```
To do something slightly more exciting, let's call Yahoo's weather service (because it doesn't require an API token) and get your local weather.
```
$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"
```
Now, we could do things the old-fashioned way and just run `curl $url` to get a giant blob of JSON, or...
```
$weather=(Invoke-RestMethod $url)
```
If you look at the type of `$weather` (by running `echo $weather.GetType().FullName`), you will see that it's a `PSCustomObject`. It's a dynamic object that reflects the structure of the JSON.
And PowerShell will be thrilled to help you navigate through it with its tab completion. Just type `$weather.` (making sure to include the ".") and press Tab. You will see all the root-level JSON keys. Type one, followed by a "`.`", press Tab again, and you'll see its children (if any).
Thus, you can easily navigate to the data you want:
```
> echo $weather.query.results.channel.atmosphere.pressure                                                              
1019.0
> echo $weather.query.results.channel.wind.chill                                                                      
41
```
And if you have JSON or CSV lying around (or returned by an outside command) as unstructured data, just pipe it into the `ConvertFrom-Json` or `ConvertFrom-CSV` cmdlet, respectively, and you can have your data in nice clean objects.
### Computing vs. automation
We use shells for two purposes. One is for computing, to run individual commands and to manually respond to their output. The other is automation, to write scripts that execute multiple commands and respond to their output programmatically.
A problem that most of us have learned to overlook is that these two purposes place different and conflicting requirements on the shell. Computing requires the shell to be laconic. The fewer keystrokes a user can get away with, the better. It's unimportant if what the user has typed is barely legible to another human being. Scripts, on the other hand, are code. Readability and maintainability are key. And here, POSIX utilities often fail us. While some commands do offer both laconic and readable syntaxes (e.g. `-f` and `--force`) for some of their parameters, the command names themselves err on the side of brevity, not readability.
PowerShell includes several mechanisms to eliminate that Faustian tradeoff.
First, tab completion eliminates typing of argument names. For instance, type `Get-Random -Mi`, press Tab and PowerShell will complete the argument for you: `Get-Random -Minimum`. But if you really want to be laconic, you don't even need to press Tab. For instance, PowerShell will understand
```
Get-Random -Mi 1 -Ma 10
```
because `Mi` and `Ma` each have unique completions.
You may have noticed that all PowerShell cmdlet names have a verb-noun structure. This can help script readability, but you probably don't want to keep typing `Get-` over and over in the command line. So don't! If you type a noun without a verb, PowerShell will look for a `Get-` command with that noun.
Caution: although PowerShell is not case-sensitive, it's a good practice to capitalize the first letter of the noun when you intend to use a PowerShell command. For example, typing `date` will call your system's `date` utility. Typing `Date` will call PowerShell's `Get-Date` cmdlet.
And if that's not enough, PowerShell has aliases to create simple names. For example, if you type `alias -name cd`, you will discover the `cd` command in PowerShell is itself an alias for the `Set-Location` command.
So to review—you get powerful tab completion, aliases, and noun completions to keep your command names short, automatic and consistent parameter name truncation, while still enjoying a rich, readable syntax for scripting.
### So... friends?
There are just some of the advantages of PowerShell. There are more features and cmdlets I haven't discussed (check out [Where-Object][6] or its alias `?` if you want to make `grep` cry). And hey, if you really feel homesick, PowerShell will be happy to launch your old native utilities for you. But give yourself enough time to get acclimated in PowerShell's object-oriented cmdlet world, and you may find yourself choosing to forget the way back.
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/2/powershell-people
作者:[Yev Bronshteyn][a]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者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

View File

@ -0,0 +1,164 @@
安利 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