朝日新聞社 Advent Calendar 2021の第10日目を担当する清田です。
「Linux サーバーを使うことは多いが手元で使用しているのは Windows だ」
という方も多いかと思います。
そのような方は PowerShell を Linux コマンドのように使いこなせると、Windows でも CLI が非常に快適に扱えるようになります。
私は開発用 Mac にも PowerShell をインストールして適宜使用しています。
ということで、本記事では
UNIX コマンドにはある程度慣れている方向けの PowerShell を使いやすくするための環境構築
についてお伝えします。
インストール
Windows 10 では PowerShell 5.1 が標準でインストールされていますが、最新の PowerShell をインストールするのが良いです。
上記の記事にあるように、PowerShellをインストールする手段はいくつかあります。
- GitHub からダウンロード
- msi
- zip
- (自力でビルド)
- WinGet コマンド(msiインストールと同等)
- Microsoft Store
Microsoft Store からのインストールが最も手軽ではありますが、制限もあります。
常用するならば、GitHub のリリースページから msi ファイルをダウンロードしてインストールするのが推奨されています。
WinGet コマンドでインストールするならば、下記のコマンドで済むので簡単です。
(管理者として実行する必要があるかもしれません)
winget install Microsoft.PowerShell
msi でのインストールならば Windows Terminal は自動で認識してくれるはずです。
Mac ならば brew
を使うのが良いでしょう。
brew install --cask powershell
PowerShell を実行
インストールしてみたら、pwsh
を起動してみましょう。
Windows の PowerShell 5 までのコマンドは powershell
でしたが、マルチプラットフォーム化された PowerShell 6 からは pwsh
となっています。
pwsh という略称ですが、PowerShell 5 の頃は posh という略称が一般的でしたが、posh という名称のシェルが存在しているので pwsh となりました。
まず、バージョンを確認してみます。
PS C:\> $PSVersionTable
Name Value
---- -----
PSVersion 7.2.0
PSEdition Core
GitCommitId 7.2.0
OS Microsoft Windows 10.0.19041
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
PowerShell はシェルとしての側面と REPL としての側面があります。
たとえば、$PSVersionTable
は .NET の System.Management.Automation.PSVersionHashTable
クラスの値を保持している変数です。
.NET の REPL なので、C# と同じようなことができます。
var runtimeVersion = System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription;
PS C:\> $runtimeVersion = [System.Runtime.InteropServices.RuntimeInformation]::FrameworkDescription
PS C:\> $runtimeVersion
.NET 6.0.0-rtm.21522.10
ちなみに、System
名前空間は省略できます。
PS C:\> [Runtime.InteropServices.RuntimeInformation]::FrameworkDescription
.NET 6.0.0-rtm.21522.10
インスタンスメソッドも使用できます。
RuntimeInformation.FrameworkDescription
は文字列型なので Substring
メソッドが使えます。
PS C:\> [Runtime.InteropServices.RuntimeInformation]::FrameworkDescription.Substring(5, 5)
6.0.0
REPL なので電卓代わりにもなります。
PS C:\> 1 + 2 + 3 * 4
15
PowerShell 内蔵のコマンド以外(実行ファイルなど)は文字列でやりとりする、sh に近い動作です。
PS C:\> cmd /? | wsl grep ON
CMD [/A | /U] [/Q] [/D] [/E:ON | /E:OFF] [/F:ON | /F:OFF] [/V:ON | /V:OFF]
/E:ON Enable command extensions (see below)
/F:ON Enable file and directory name completion characters (see below)
/V:ON Enable delayed environment variable expansion using ! as the
delimiter. For example, /V:ON would allow !var! to expand the
reasons, /X is the same as /E:ON, /Y is the same as /E:OFF and /R is the
In a batch file, the SETLOCAL ENABLEEXTENSIONS or DISABLEEXTENSIONS arguments
takes precedence over the /E:ON or /E:OFF switch. See SETLOCAL /? for details.
particular invocation of CMD.EXE with the /V:ON or /V:OFF switch. You
In a batch file the SETLOCAL ENABLEDELAYEDEXPANSION or DISABLEDELAYEDEXPANSION
arguments takes precedence over the /V:ON or /V:OFF switch. See SETLOCAL /?
invocation of CMD.EXE with the /F:ON or /F:OFF switch. You can enable
If completion is enabled with the /F:ON switch, the two control
PS C:\> cmd /? | Where-Object { $_.Contains("ON") }
CMD [/A | /U] [/Q] [/D] [/E:ON | /E:OFF] [/F:ON | /F:OFF] [/V:ON | /V:OFF]
/E:ON Enable command extensions (see below)
/F:ON Enable file and directory name completion characters (see below)
/V:ON Enable delayed environment variable expansion using ! as the
delimiter. For example, /V:ON would allow !var! to expand the
reasons, /X is the same as /E:ON, /Y is the same as /E:OFF and /R is the
In a batch file, the SETLOCAL ENABLEEXTENSIONS or DISABLEEXTENSIONS arguments
takes precedence over the /E:ON or /E:OFF switch. See SETLOCAL /? for details.
particular invocation of CMD.EXE with the /V:ON or /V:OFF switch. You
In a batch file the SETLOCAL ENABLEDELAYEDEXPANSION or DISABLEDELAYEDEXPANSION
arguments takes precedence over the /V:ON or /V:OFF switch. See SETLOCAL /?
invocation of CMD.EXE with the /F:ON or /F:OFF switch. You can enable
If completion is enabled with the /F:ON switch, the two control
定番のモジュール
快適な PowerShell 環境の構築のために、定番のモジュールをインストールしてみます。
PowerShell を開いて
$PROFILE
と実行して表示されるパスにあるファイルが起動時に実行されます。
ここに起動時の設定を記述していきます。
bash の .bashrc
に近いものです。
ここにモジュールの読み込みなどの設定を書きます。
posh-git
git コマンドの補完をしてくれるモジュール posh-git
をインストールします。
あらかじめ PATH
に git.exe
のディレクトリを追加しておく必要があります。
インストールはコマンドひとつです。
Install-Module posh-git
PROFILE に下記の記述を追加して、起動時に読み込むようにしておきます。
Import-Module posh-git
oh-my-posh
fish shell の oh-my-fish のように表示をカスタマイズできるモジュールです。
Nerd font というフォントが必要なので https://www.nerdfonts.com/font-downloads から好きなものをダウンロードして、Windows Terminal や VSCode などに設定します。
ちなみに、VSCode なら terminal.integrated.fontFamily
がターミナルのフォント設定です。
Install-Module oh-my-posh
インストールが済んだら、テーマを決めます。Get-PoshThemes
を実行するとデフォルトのテーマを列挙してくれるので、この中から好きなテーマを選びます。
Get-PoshThemes
PROFILE で Set-PoshPrompt
を使って読み込みましょう。
Set-PoshPrompt paradox
テーマのカスタマイズもできるので自作しても良いと思います。
Set-PoshPrompt "$PSScriptRoot\mytheme.json"
Nerd font をインストールしない場合は minimal なテーマを読み込むと良いです。
Set-PoshPrompt hotstick.minimal
タブ補完
.NET SDK(dotnet
) や AWS CLI(aws
) などは PowerShell 用のタブ補完機能を備えています。
- AWS CLI
- .NET SDK
PROFILE に書いておくと便利です。
Register-ArgumentCompleter -Native -CommandName aws -ScriptBlock {
param($commandName, $wordToComplete, $cursorPosition)
$env:COMP_LINE = $wordToComplete
$env:COMP_POINT = $cursorPosition
aws_completer.exe | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
Remove-Item Env:\COMP_LINE
Remove-Item Env:\COMP_POINT
}
Register-ArgumentCompleter -Native -CommandName dotnet -ScriptBlock {
param($commandName, $wordToComplete, $cursorPosition)
dotnet complete --position $cursorPosition "$wordToComplete" | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
}
コマンド
UNIX コマンドとの対応
PowerShell にも UNIX と同様のコマンドが定義されていたりします。
特に Windows では対応する UNIX コマンドと同名のエイリアスが作成されていたりします。
UNIX コマンド | PowerShell コマンド | エイリアス | 備考 |
---|---|---|---|
ls |
Get-ChildItem |
dir , gci , ls (Windowsのみ) |
|
cd |
Set-Location |
chdir , sl , cd
|
|
cat |
Get-Content |
gc , type , cat (Windowsのみ) |
|
head |
Get-Content -Head {行数} |
なし | |
tail |
Get-Content -Tail {行数} |
なし | |
cp |
Copy-Item |
copy , cpi , cp (Windowsのみ) |
|
rm , rmdir
|
Remove-Item |
del , erase , rd , ri , rm (Windowsのみ), rmdir (Windowsのみ) |
rmdir でファイルも消せてしまう |
mv |
Move-Item |
copy , cpi , mv (Windowsのみ) |
|
diff |
なし | なし |
diff は Compare-Object にエイリアスがある(Windowsのみ)。かなり動作が異なる |
grep |
なし | なし |
ripgrep をインストールするのが良いと思います。 |
| |||
エイリアスの一覧は Get-Alias で取得できます。 |
|||
| |||
エイリアスを追加したい場合は Set-Alias を使います。 |
|||
| |||
たとえば、ll を Get-ChildItem のエイリアスにしたい場合は下記のようにします。 |
Set-Alias ll Get-ChildItem
便利な自作コマンド
Set-Alias
では収まらないようなコマンドを関数として PROFILE 内で定義しておくと便利です。
カレントの親ディレクトリに移動する bd
コマンド
function bd { Set-Location .. }
コマンドの定義を表示する which
コマンド
エイリアスならエイリアスの参照先、パスが通っている実行ファイルならそのフルパス、関数なら関数定義そのものなど、良い感じに表示されます。
function which { (Get-Command $args).Definition }
コマンドの引数を忘れたときは
Get-Command
コマンドに -Syntax
オプションをつけて実行するとコマンドの引数を表示してくれます。
PS C:\> Get-Command Push-Location -Syntax
Push-Location [[-Path] <string>] [-PassThru] [-StackName <string>] [<CommonParameters>]
Push-Location [-LiteralPath <string>] [-PassThru] [-StackName <string>] [<CommonParameters>]
ショートカットキー
Get-PSReadLineKeyHandler
でショートカットキーの一覧を確認できます。
他のシェルに使い勝手を近づけるため下記の設定を追加しています。
# タブ補完を zsh などのものと同様にする
Set-PSReadLineKeyHandler -Chord Tab -Function MenuComplete
# Ctrl+d で exit する
Set-PSReadLineKeyHandler -Chord Ctrl+d -Function DeleteCharOrExit
# Ctrl+w でカーソル左にある単語を削除
Set-PSReadLineKeyHandler -Chord Ctrl+w -Function ShellBackwardKillWord
# Ctrl+w で Get-Command などのハイフンに引っかかるのが気になったので引っかからないようにする
Set-PSReadLineOption -WordDelimiters (Get-PSReadLineOption).WordDelimiters.Replace("-", "")
その他のソフトウェア
PowerShell 専用ではないソフトウェアもインストールしておきましょう。
less
Windows には more
はあっても less
がありません。
そのため help Get-ChildItem
などで出るメッセージも読みづらくて困ります。
Git for Windows に内蔵されている less
をページャーとして使用するようにしましょう。
PROFILE で設定しても良いですが、システム環境変数で PAGER
の値を "C:\Program Files\Git\usr\bin\less.exe"
としてしまうのが良いと思います。
# これでも良いが、システム環境変数で設定してしまって良さそう。
$env:PAGER="C:\Program Files\Git\usr\bin\less.exe"
Vim
Vim をインストールしてパスを通せば、普通に使えます。
私は Neovim に乗り換えたので vim
は nvim.exe
のエイリアスにしています。
Set-Alias vim "C:\MyPrograms\Neovim\bin\nvim.exe"
ripgrep
ripgrep は grep
の進化版を意図して作られたソフトですが、Windows にはそもそも grep
が存在しないので代替品としてちょうどよいです。
ダウンロードしてパスを通すだけ使えます。
PS C:\> dir C:\ | rg Program
d-r-- 2021/11/30 11:00 Program Files
d-r-- 2021/11/30 11:01 Program Files (x86)
補完の定義も用意されているので PROFILE で読み込んでおきましょう。
. "C:\MyPrograms\ripgrep\complete\_rg.ps1"
活用する👍
ひととおりの環境構築ができたら PowerShell をどんどん使って行きましょう!
朝日新聞社では、技術職の中途採用を強化しています。
ご興味のある方は下記リンクから希望職種の募集ページに進んでください。
皆様からのご応募、お待ちしております!