PowerShell 教程(特别针对讨厌 PowerShell 的人)
前言
这篇文章很长。为了方便不耐烦的读者,我在这里放了一个目录,方便你找到自己想看的部分。
我与终端(尤其是 Windows PowerShell)的关系就像坐过山车一样。
我第一次发现终端是在我听说 Python 的时候,当时我对它一无所知。就像普通人一样,我使用电脑玩游戏、运行 Excel 和 PowerPoint 之类的应用程序,我访问了Python 网站,下载了安装程序,安装了它,然后点击了图标。想象一下,当弹出这样的信息时,我有多害怕:
按钮在哪儿?字体怎么这么老旧?我的鼠标该怎么用?
随着编程经验的积累和终端的使用,我开始爱上 Bash。它过时了吗?是的。它的命令不够直观,难以记忆吗?当然是的。不知为何,这让我更加喜欢它了。
我不得不费尽心思,输入一堆看似官样文章却能带来强大效果的东西,感觉自己像个巫师。比如,输入du -sk * | sort -n | tail
“(看到了吗?官样文章!)”就能快速查看当前目录中最大的几个目录。
随着我了解的越来越多,我能够自定义它的外观并获得字体、颜色和提示,让终端更加吸引人。
于是我决定把我新学到的编程能力运用到工作中。只不过我是一名机械工程师,这通常意味着要用到 SolidWorks 和 Windows。于是我打开了推荐的终端 PowerShell。结果,又一次让我惊恐万分:
没问题,我想。我直接去设置界面就行了。
哦,不。我们已经不在堪萨斯了。跟我以前习惯的不太一样。所以我打开PowerShell,试着做了一些简单的操作。有些操作正常!ls
,,cd
其他mkdir
都像我以前习惯的那样。但我不明白为什么设置$PATH
这么难。还有,这些反斜杠是怎么回事?我怎么搞不定sudo
?
越来越多的小麻烦不断出现,提醒我根本没用过 Bash。我放弃了,安装了Cygwin,这样我就能在 Windows 7 电脑上体验 Bash 了。只是没有引用。我尝试过的所有方法都无法在 Windows 电脑上使用 Bash……不太对劲。
最后,我尝试了另一种方法,从一开始就以正确的方式学习 PowerShell,就像学习另一门语言一样。随着学习的深入,我发现自己越来越认同 PowerShell 的整体理念,并且注意到它比使用 Bash 时好用得多。请记住,就像所有东西一样,PowerShell 只是工具箱里的一个工具,它是否是最好的工具,实际上取决于具体情况。
我不会给你上一堂完整的 PowerShell 基础课程,也不会花太多时间告诉你如何安装它。这套文档已经相当全面了,而且也是一份很好的备忘单,以后可以参考。
我的目标是向您展示如何从其他 shell 转换内容并帮助您开始自己的 PowerShell 之旅,因此我假设您至少对 Bash 等 shell 语言有一点经验。
PowerShell 入门
当你开始学习 PowerShell 时,你可能会对类似 Bash 的 shell 的操作方式产生一些想法上的转变。如果你能克服最初看到这些差异时的厌恶情绪,你可能会发现它们实际上能让你更有效率。
一切皆对象
这或许是你必须理解的最大区别。在 Unix shell 中,所有内容都是纯文本。这让事情变得很好,因为你可以预期所有脚本都会有文本输入,而且你知道,如果你输出文本,那么一切可能都没问题。
然而,缺点是,这使得检查特定数据成为文本解析的噩梦,并且使得处理文本以外的任何东西(浮点数,有人吗?)都变得非常痛苦。
在 PowerShell 中,它实际上是建立在.NET之上的,一切皆对象。如果你有 Python、Ruby、JavaScript 或类似的语言背景,这会让你感觉非常轻松。让我们看一些示例,并亲自动手实践。打开你的 PowerShell 解释器。
附注:我
PS>
在每个命令前面都添加了一个 PowerShell 提示符 ( ),以便您可以知道输出的内容。以 开头的每一行PS>
都是需要您输入的内容。其他所有内容都是输出。
PS> Get-Process
你应该会看到一串很长的文本。我们没必要忍受这些!我们是终端人。代码在我们的血管里流淌!试试这个:
PS> Get-Process | Sort-Object CPU -descending | Select-Object -first 10
现在你应该看到一个更短的列表,按 CPU 时间反向排序。如果你已经因为这些命令和选项太长而感到烦躁,我会在接下来的几节中解决这个问题。请继续往下看。
这里需要重点关注的是每列顶部的标题。这个表的每一行实际上都是一个System.Diagnostics.Process
对象,而不仅仅是表格中的一行。不信?去查查就知道了!
PS> (Get-Process)[0] | Get-TypeData
看到了吗?该Get-Process
命令返回了一个对象列表Process
,我们可以通过索引选择第一个(无需使用 \n! 拆分输出),然后通过Get-TypeData
命令进行随机排序。这些项目是对象,这给了我们一些权力。如果我们只想要它们的 呢ProcessName
?
PS> Get-Process | Sort-Object CPU -descending | Select Object ProcessName -first 10
看看访问起来有多简单!我们不用切分制表符或冒号分隔的字段,也不用数数需要哪个字段(1...2...3...4...5!)。我们只需要告诉它我们想要的ProcessName
属性即可。无需再进行解析、拆分、连接、格式化输出等操作。
对象有类型
在 .NET 之上,所有东西都是对象,另一个副作用是所有东西都必须有类型。对于只包含字符串以及可能被解释为命令的字符串的 Bash Shell 来说,这可能会造成混淆。以下是它为我们做了什么。
PS> 2 + 2
4
啊!你惊讶吗?这在 Bash 里可要费劲得多!更别提了:
PS> 4.2 / 3
1.4
PowerShell 通常能够很好地识别你所需的类型,因此你可以像使用其他 Shell 和脚本语言一样灵活地使用它们,而不必对所有对象都严格指定类型。但是,如果你确实需要强制指定类型,可以通过在对象前面加上方括号来指定其类型。
PS> "2" + 2
22 # A string
PS> [Int]"2" + 2
4 # An integer. The conversion only applies to the "2"
可预测的指挥结构
这是我刚开始使用 PowerShell 时注意到的第一件事之一。我当时在 StackOverflow 上查看示例命令,一直对 PowerShell 命令与 Bash 命令相比的冗长感到恼火。例如,要在 Bash 中列出当前目录的内容:
$ ls -l
在 Powershell 中:
PS> Get-ChildItem
这么长!还用大写字母?拜托。好消息是,如果你不想打,可以不打。不过,在解释之前,我先解释一下背后的原理。
为什么这么久?
PowerShell 的创建者希望命令极其直观,以至于你几乎可以猜出你需要的命令。这在 Bash 中几乎不可能实现。你根本猜不到这cat
是将文件读取到终端的常用命令。一旦你学会了它,你就会明白它是“concatenate”的缩写,但它本身并不直观。
PowerShell 命令的设计遵循一种简单的模式:“动词-名词”。PowerShell 的创建者试图将动词的数量保持在最低限度。常见的动词有Get, New, Add, Clear, Export, Remove, Set, Update, and Write
。名词通常也非常直观:Process, Item, Object, Date, Job, and Command
例如 。
这种一致的模式允许某人查看包含他们从未使用过的命令的脚本,并且仍然对脚本的作用有所了解。
保持一致模式的另一个好处是,PowerShell 可以检测命令的“动词”和“名词”部分。例如,你想查看所有包含动词“New”的命令吗?
PS> Get-Command -verb New
事实上,如果你知道自己想做什么,但又记不住命令,Get-Command 就是几个能帮上忙的命令之一。如果你想看看能对“Job”对象执行哪些操作,该怎么办?
PS> Get-Command -noun Job
是的,这些命令的输入时间比等效的、通常是简洁的 Bash 命令要长,但这种额外的冗长性带来了易用性、更少的命令记忆以及有用的工具来提高您的工作效率。
别名让你的生活更轻松
尽管命令冗长繁琐,但 PowerShell 知道使用终端的人很懒(这是好事!),它不想妨碍你。它有大量内置别名,让你的操作更轻松、更舒适,而且它实际上可以即时设置一些别名。
还记得我们之前运行的查看目录中所有文件的命令吗?
PS> Get-ChildItem
# You can also do:
PS> gci
PS> dir
# And just to make you feel a little bit more at home...
PS> ls
想要查看所有可用的别名吗?现在,你应该不会对命令感到惊讶了:
PS> Get-Alias
在 shell 会话期间使用这些别名可以提高您的工作效率并避免手指磨损,同时又不放弃它们所代表的较长命令的功能和可读性。
脚本编写的最佳实践
关于最佳实践,我只想说一句:当你独自一人进行命令行工作时,请随意使用任意数量的别名。设置好别名,提升你的工作效率。
但是,如果你正在编写脚本或与他人共享代码,最好还是把完整的命令和标志名称都写出来。相信我,你未来的自己和同事都会感谢你的。
一些有用的入门命令
虽然学习 PowerShell 的最佳方法是深入研究和练习,但我将在这里与您分享一些命令,当您遇到困难时,这些命令非常有用。
当您不确定使用哪个命令时
PS> Get-Command
此命令将为您提供有关可用命令的更多信息。您可以通过指定 -verb 或 -noun 参数来精确定位所需内容。为了获取有关一两个特定命令的更多信息,请将输出通过管道传输到Format-List
。这将为您提供选项、位置和其他一些有用的功能。
PS> Get-Command Get-Alias | Format-List
当你不确定命令的作用时
PS> Get-Help command
# You can also get help by adding the ? parameter
PS> command -?
Get-Help
大致就是man
PowerShell 的世界。你开始感受到直观命令的好处了吗?实际上,Get-Help
它还包含不少实用的标志。不妨用我们上面讨论的方法来看看它们:
PS> Get-Command Get-Help | Format-List
# Or, if you're feeling cheeky:
PS> Get-Help Get-Help
我最喜欢的是,你可以专门询问它仅用于示例用法。
PS> Get-Help Get-Alias -examples
当你不确定对象有哪些属性时
PS> Get-Process | Get-Member
# Another similar command:
PS> (Get-Process)[0] | Format-List
如果您知道您想要什么数据,但只是不知道它叫什么,或者您甚至不确定有哪些数据可供您使用,这些命令将帮助您更好地“看到”您的对象。
当你想获取部分数据时
PS> Get-Process | Select-Object Id, ProcessName -last 20
Select-Object
是你的通用削材工具。你可以指定所需的特定属性以及数量。
当你想过滤数据时
PS> Get-Process | Where-Object WS -gt 150MB
该命令有几种使用方法Where-Object
,但这是最简单的一种。在上面的示例中,我仅选择了工作集(内存使用量)大于 150MB 的进程。(另外,我们可以稍微介绍一下 PowerShell 如何进行 KB/MB/GB 的计算吗?)
告诉我怎么做!
最后一节只是为那些不耐烦的读者提供的几个片段。如果你只是想用 PowerShell 完成一件小事,却无法成功,这些技巧应该能帮到你。
基本 Unix 命令翻译
# pwd
PS> Get-Location # or gl or pwd
# ls
PS> Get-ChildItem # or gci or dir or ls
# cd
PS> Set-Location # or sl or chdir or cd
# cp
PS> Copy-Item # or copy or cpi or cp
# mv
PS> Move-Item # or move or mi or mv
# cat
PS> Get-Content # or gc or type
# mkdir
PS> New-Item -ItemType Directory # or ni -ItemType Directory or mkdir
# touch
PS> New-Item -ItemType File # or ni
# rm
PS> Remove-Item # or del or erase or ri or rm
# rm -rf
PS> Remove-Item -Recurse -Force # or rm -recurse -force
# head or tail
PS> Select-Object -first # or -last
# usage: Get-Process | Select-Object -first 10
# find
PS> Get-ChildItem -filter *.rb -recurse .
# but, for a slightly easier to read version:
PS> Get-ChildItem -filter *.rb -recurse . | Select-Object FullName
访问路径(和其他环境变量)
在 PowerShell 中,很多东西都会被当作文件位置来处理——环境变量也不例外。这些特殊的类文件变量组被称为 PSDrive。就像你可以用 询问 C: 盘“\Users\ryan\desktop”下的文件一样,你也可以用(环境变量 PSDrive)Get-ChildItem C:\Users\ryan\Desktop
来做同样的事情。env:
PS> Get-ChildItem env:
# and to get a specific one
PS> Get-Content env:PATH
PSDrive 的一个超级妙处是,你可以像读取变量一样读取文件位置。所以,你也可以这样获取环境变量:
PS> $env:PATH
第二种方法可能是获取 PATH 变量最流行的方法。
自定义您的个人资料
如果你喜欢命令行,并且像我一样,你可能想知道如何自定义它们。答案就在$profile
……
查找个人资料
实际上,有多个配置文件,具体取决于您使用哪个“主机”与 PowerShell 交互。例如,如果您只是使用常规的 PowerShell 命令行,则配置文件的名称将是 Microsoft.PowerShell_profile.ps1。但是,如果您在 PowerShell 集成脚本环境 (ISE) 中工作,则配置文件的名称将是 Microsoft.PowerShellISE_profile.ps1。您通常可以忽略这一点,因为如果您想知道,只需询问即可:
PS> $profile
但是,还有其他选项。如果您要创建适用于 ISE 或常规命令行的配置文件,则需要$profile.CurrentUserAllHosts
。或者,如果您要为计算机上的所有用户配置配置文件,则需要$profile.AllUsersCurrentHost
。有几个选项,您可以使用以下命令查看所有选项:
PS> $profile | Get-Member -type NoteProperty
创建自定义
您的配置文件的工作方式与 Bash 中的一样.bash_profile
。它只是一个在您开始使用 PowerShell 之前运行的脚本。您可以添加别名(尽管请参阅下面的注释)、函数、变量以及设置自定义设置。检查您是否已有配置文件的最简单方法是:
PS> Test-Path $profile
并开始创建您的个人资料:
# Use whichever editor you love best
PS> code $profile
以下是您可能会喜欢的一些有用的设置:
# Microsoft.PowerShell_profile.ps1
# You can customize the window itself by accessing $Host.UI.RawUI
$window = $Host.UI.RawUI
$window.WindowTitle = "Pa-pa-pa-pa-pa-pa-POWERSHELL"
$window.BackgroundColor = "Black"
$window.ForegroundColor = "Gray"
# You can define functions (remember to follow the Verb-Noun convention!)
function Count-History {
(Get-History | Measure-Object).count
}
function beep {
echo `a
}
function Edit-Profile {
[CmdletBinding()]
[Alias("ep")]
PARAM()
vim $profile
}
# You can set aliases.
# NOTE: In PowerShell, you can only alias simple commands.
# Unlike Bash, you can't alias commands with arguments flags.
# If you want to do that, you should define a function instead.
Set-Alias touch New-Item # old habits die hard, amirite?
# You can customize your prompt!
function prompt {
# ... see the next section for details
}
自定义您的提示
有两种方法可以做到这一点:简单的方法和复杂的方法。
简单的提示
自定义提示最简单的方法是prompt
手动或在配置文件中定义函数。例如:
function prompt {
$histCount = (Get-History | Measure-Object).count
return "POWERSHELL LEVEL OVER $histCount THOUSAND! >"
}
这是一种很有趣的方式,可以打印出你在提示符中已经输入的次数。你返回的字符串将被设置为提示符。
复杂的提示
基本上,你可以在 prompt 函数中做任何你想做的事情,只要它在末尾返回一个字符串即可。例如,这是一个更复杂的提示。
function prompt {
$loc = (Get-Location).Path.Replace("$HOME", "~")
$gitBranch = git branch | Select-String "\*"
if (!$gitBranch) {
$gitBranch = ""
} else {
$gitBranch = $gitBranch.ToString().Replace("`* ", "")
}
$hisCount = (Get-History | Measure-Object).count
WriteHost -ForegroundColor yellow "`n $loc"
WriteHost -NoNewLine "PS [$histCount] $gitBranch ->"
return " "
}
Write-Host
你可以看到,我通过使用多次操作实现了多行提示符。最后,我只需返回一个空格即可。我的提示符最终如下所示:
~/Documents/blog
PS [102] master ->
让它看起来不那么丑
这个问题比较棘手。正如我上面提到的,在 Windows 上,PowerShell 的运行窗口非常小,自定义选项也很少。尤其对于习惯于随意操作文本编辑器的人来说,这简直是痛苦的。不过,有两个不错的替代方案。
-
Cmder:这款工具基于 ConEmu 构建,ConEmu 是一款非常流行的 Windows 终端模拟器。如果你喜欢 Notepad++,我想你一定会喜欢它,因为它的使用体验很相似。
-
Hyper:对于那些对 Electron 应用没有敌意,并且更偏向前端的人来说,Hyper 是一个不错的选择。所有自定义和设置都使用 JavaScript 和 CSS 完成,这使得寻求帮助变得非常便捷。正如 JavaScript 社区所预料的那样,它提供了大约数不胜数的插件,其中一些非常稳定且性能出色。Hyper 目前仍在进行大量开发,因此您可能会遇到一些稳定性问题,但在过去的几个月里,它的速度确实大幅提升,故障也更少了。
查找更多资源
最好的去处绝对是官方文档。那里内容丰富,应该能找到你需要的答案。由于 PowerShell 现在是开源的,你也可以查看他们的GitHub 仓库。那里也有一些很棒的文档和入门指南。
对于喜欢通过书籍学习的朋友,我推荐Lee Holmes 的《Windows PowerShell Cookbook》,以及Bruce Payette 和 Richard Siddaway 合著的《Windows PowerShell in Action》 。这两本书的知识点非常丰富。
学习爱上 PowerShell
本文的目的是表明,PowerShell 与您习惯的不同并不一定意味着它是坏的。
如果你花时间深入研究这些差异,并了解其背后的原因和设计决策,你就会开始发现它们的优势和价值。当你回到其他 shell 时,你可能会怀念在命令行中处理输入对象。
解析文本流可能会让你感觉有些过时。你可能会发现自己到处都在使用更长、更一致的函数名,因为你意识到,写完脚本六个月后还能读懂是多么好的事情。
或者,您可能只是不再告诉别人您有多么讨厌 PowerShell。
最初发表于Simple Programmer
文章来源:https://dev.to/rpalo/powershell-tutorial-special-for-people-who-hate-powershell-2g25