从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) {