添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
首发于 ⑩六进制
从Shell到Powershell(Powershell简易入门)

从Shell到Powershell(Powershell简易入门)

(题图是夏目佳子,P站ID为90010228)

一直以来用的都是shell命令,但是windows上的要用shell命令还是有点麻烦的。WSL2下的IO效率低,而MSYS2总有一些违和感……所以 整理了一下Powershell中shell命令的替代品,做为powershell的简易入门手册……


类似Bash的快捷键配置

Powershell中起类似 .bashrc .zshrc 的配置文件可以通过变量 $PROFILE 来查看

下面是我的配置

Invoke-Expression (&starship init powershell)
Set-PSReadLineOption -EditMode Emacs
Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete
# Autocompletion for arrow keys
Set-PSReadlineKeyHandler -Key UpArrow -Function HistorySearchBackward
Set-PSReadlineKeyHandler -Key DownArrow -Function HistorySearchForward

第一行是 starship项目 ,可以在回显中显示git branch,在有脚本的目录中自动提示python和ruby版本之类的。具体可以看Github

效果如下:

第二行是 引入bash的快捷键(也就是emacs的快捷键啦~) 。也就是ctrl-d退出、ctrl-a跳转到行首、ctrl-d跳转到行末之类的,让你可以使用bash下的快捷键。这个是 powershell内置的PSReadline模块提供的

如果没有这个模块,可以看 GitHub - PowerShell/PSReadLine: A bash inspired readline implementation for PowerShell 来安装或升级

第三行是 设置补全风格为菜单选择样式 ……就是按tab补全会弹出一个菜单让你选择

后两行是 历史命令搜索 ,比如之前执行过 nvim $PROFILE ,下次打个 nvim 再按上方向键,就会补全出 nvim $PROFILE

下载Powershell命令手册

Linux下我们常用 man 来查看命令手册,在Powershell中我们可以用 help 来查看命令的帮助。需要注意的是, 即使是内置的命令 help 也可能显示不全 (提示“ 在此计算机上找不到该 cmdlet 的帮助文件。它仅显示部分帮助 ”)……

我们可以用 Update-Help Microsoft.PowerShell.* 下载内置命令的手册。注意要在管理员权限下运行

Powershell中 连命令行参数都可以补全 ,考虑到powershell中烦琐的语法,善用补全能极大地提高你的效率。

命令行参数补全

get-help <命令> -examples 可以帮助手册中命令的使用示例

浏览和查找命令

Powershell中 ls find 的替代品是 Get-ChildItem 不过你也可以直接用 ls 来调用 …… 在powershell中,有一些命令有和shell命令一样的别名 ,但是功能和输出有所不同,还是需要注意的。下面是一些示例。因为powershell的命令都很易懂,我就不解释了……

Get-ChildItem C:\Test
Get-ChildItem b*.rb -Recurse #递归查找当前目录下所有的以b开头的rb文件
Get-ChildItem -Path C:\Test\* -Include *.txt  #Path里的*是必须的
Get-ChildItem -Path C:\Test\Logs\* -Exclude A* #Path里的*是必须的
Get-ChildItem -Path C:\Parent -Depth 2
Get-ChildItem -Path HKLM:\HARDWARE #注册表也可以用这个命令来查看……

简单的命令

这些命令就自己去用help看帮助吧……

get-help <命令> -examples 可以查看官方的例子

  • pwd 的替代品是 Get-Location , 不过用 pwd 也可以调用,因为微软内置了这个别名……
  • cd 的替代品是 Set-Location ,也可以用 cd 调用……
  • which 的替代品是 Get-Command
  • cp 的替代品是 Copy-Item ,也可以用 cp 调用
  • rm , rmdir , 和 del 都是 Remove-Item 的别名
  • mkdir New-Item 的别名,也可以跟 touch 一样新建文件……
  • cat tail head 可以用 Get-Content 配合命令行参数实现。用 cat 就可以调用了。

Powershell中的管道

Powershell中的管道和bash有所不同, 传递的是对象而不是字符串 ……

解释起来很麻烦(其实是我自己不太懂Powershell的管道……),就记住几个常用的例子就可以啦~

命令输出取列

这个在shell中通常是用 awk 来实现的,powershell中是用 Select-Object -Property 实现

(注意,powershell中管道传递的是对象,其实 这个并不是字符串取列而是取了对象或对象的属性

命令输出取行

在shell中我们通常用 grep 实现,在powershell中可以用 Where-Object 实现。就用官方示例来说明吧……

(注意,powershell中管道传递的是对象,其实 这个并不是字符串取行而是选择集合中的对象

    #--------------- Example 1: Get stopped services ---------------
    Get-Service | Where-Object {$_.Status -eq "Stopped"}
    Get-Service | where Status -eq "Stopped"
    #-------- Example 2: Get processes based on working set --------
    Get-Process | Where-Object {$_.WorkingSet -GT 250MB}
    Get-Process | Where-Object WorkingSet -GT (250MB)
    #-------- Example 3: Get processes based on process name --------
    Get-Process | Where-Object {$_.ProcessName -Match "^p.*"}
    Get-Process | Where-Object ProcessName -Match "^p.*"
    #-------- Example 4: Use the comparison statement format --------
    Get-Process | Where-Object -Property Handles -GE -Value 1000
    Get-Process | where Handles -GE 1000

文件过滤

在shell中我们也是用 grep 实现,powershell中用 Select-String 实现。 这个命令可以过滤文件,也可以过滤对象 。还是一样,用例子来展现。

#大小写敏感的过滤
'Hello', 'HELLO' | Select-String -Pattern 'HELLO' -CaseSensitive -SimpleMatch
#多文件正则查找
Select-String -Path .\*.txt -Pattern 'Get-'
#反向查找
Select-String -Path .\Command.txt -Pattern 'Get', 'Set'  -NotMatch
#对当前目录下所有的ruby脚本查找base64,这个是我想出来的示例=v=
ls *.rb -Recurse  | Select-String -Pattern "base64"
#对管道传入的对象的属性进行过滤,这个是我想出来的示例=v=
ls | Select-String -InputObject {$_.Name} -Pattern '\.zip'

powershell脚本基本语法

可以参考我写的脚本

下面是一些基础的语法……

$ALGORITHMS = @("MD5", "SHA1", "SHA256") #定义数组
$ALGORITHMS | ForEach-Object {
  echo $_ #for each写法
#定义函数
function hashFile ($filePath) {
    return $ALGORITHMS | ForEach-Object {
        Get-FileHash $filePath -Algorithm $_ | Select-Object -ExpandProperty Hash
#foreach循环与if
function addFilesToListView ($filePaths) {
    foreach ($filename in $filePaths)
        if (-Not [System.IO.File]::Exists($filename)) {
            continue
#for循环
for (($i = 0), ($j = 0); $i -lt 10; $i++)
    "`$i:$i"
    "`$j:$j"
#if语句
if ($a -gt 2) {
    Write-Host "The value $a is greater than 2."
elseif ($a -eq 2) {