14
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

PowerShellの.bashrc的な設定ファイルこと$Profileについての紹介

IPFactory Advent Calender 2019 21日目

IPFactory3年の @smicle です。
Advent Calenderは今年が初参加になります。
何卒よろしくお願いいたします。

目次

PowerShellでもaliasとか設定したくないですか?
というか設定しないとまともに作業できない…

PowerShellの.bashrcことprofileを設定しましょう!
詳細:Windows PowerShell Profiles

PowerShellScriptを実行する権限を付与

初期状態だとprofileを設定してもscriptを実行する権限がないので、適切な権限を付与しましょう。
色々ありますけど管理者権限で以下のコマンドを実行すれば大丈夫です。

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned

詳細:Set-ExecutionPolicy

profileの場所

profileの場所一覧

  • $Profile.AllUsersAllHosts
    • %windir%\system32\WindowsPowerShell\v1.0\profile.ps1
  • $Profile.AllUsersCurrentHost
    • %windir%\system32\WindowsPowerShell\v1.0\Microsoft.PowerShell_profile.ps1
  • $Profile.CurrentUserAllHosts
    • %UserProfile%\My Documents\WindowsPowerShell\profile.ps1
  • $Profile.CurrentUserCurrentHost
    • %UserProfile%\My Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

詳細:Understanding the Profiles

以下のコマンドで場所が確認できます。
表示されたPathの場所にファイルを作成し編集します。

echo $Profile.AllUsersAllHosts
echo $Profile.AllUsersCurrentHost
echo $Profile.CurrentUserAllHosts
echo $Profile.CurrentUserCurrentHost

CurrentUserの方が影響範囲が狭いので良いと思うのですが、自分はDocuments\WindowsPowerShellを作りたくないのでAllUsersの方に作っています。

profileからScriptを読み込む

直接profileに色々書き込むと場所が指定されてしまったり、管理者権限が必要など不都合が多いので、別ファイルを読み込むようにすると楽です。(しなくても良い)

単一ファイルの場合

$script = "$Home\profile.ps1"
if (Test-Path $script) {
  . $script
}

複数ファイルの場合

$script = @("$Home\profile.ps1", "$Home\function.ps1")
foreach ($s in $script) {
  if (Test-Path $s) {
    . $s
  }
}

aliasの設定

ようやくaliasの設定に入れます…
PowerShellにはtouchがないので設定してみます。(何故ない?)

Set-Alias -Name touch -Value New-Item

# 短縮した方が見やすい
Set-Alias touch New-Item

gitgにするならこれ

Set-Alias g git

以上です。
詳細:Set-Alias

ですがこのaliasには一つ問題があります。
引数込みの設定ができない点!

alias ..='cd ..'

みたいなことがPowerShellのaliasではできません。
でもご安心下さい!functionを使えば同じような事ができます。

functionの設定

ということでfunctionの設定です。
さっそく..を設定してみます。

function ..() {
  cd ../
}

# 1行でも良い
function ..() {cd ../}

以上です。
詳細:about_Functions

オススメの設定

エクスプローラーがカレントディレクトリで開きます。

function el() {explorer .}

カレントディレクトリのpathをクリップボードにコピーします。

function pwdc() {Set-Clipboard "$pwd"}

ディレクトリを作成したときの結果出力を非表示にします。(touchでも使える)

function mkd() {mkdir $args | Out-Null}

alias rm="rm -rf"を定義する

自分は過激派なのでrmrm -rfに上書きしています。
さっそくやっていきましょう!

PowerShellは普通にrm -rfと入力しても動きません。
そもそもPowerShellのrmはただaliasです。

試しに以下のコマンドを打ってみて下さい。

Get-Alias | ? {$_.Name -eq "rm"}

このようなメッセージが出たと思います。

CommandType  Name               Version  Source
-----------  ----               -------  ------
Alias        rm -> Remove-Item

rmRemove-Itemのaliasです。
cdSet-LocationlsGet-ChildItemと一般的に使いそうなaliasが元から掛かっています。(何故touchがない?)

PowerShellのrmは、皆さんの知っているrmに似てるようで違います。
Remove-Itemのドキュメントを見れば分かるはずです。

-r-Recurse-f-Forceが同様の機能みたいなので

rm -Recurse -Force

とやればrm -rfと同じ事ができます!

以下の関数を登録すれば完了です。

function rm() {Remove-Item -Recurse -Force $args}

実際に動作確認をしてみます。

rm .\test\

確認
C:\Users\smicle\test\ の項目には子があり、Recurse パラメーターが指定されていませんでした。続行した場合、項目と共にすべての子が削除されます。続行します
?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"):

Recurseは設定されているはずだが?

コマンドには優先順位が存在します。

コマンドの優先順位
1. Alias
2. Function
3. Cmdlet
4. Native Windows commands

詳細:About Command Precedence

なのでrmのaliasを削除しなければなりません。
aliasの削除にもremove-itemを使います。

remove-item alias:rm -Force

これでrmrm -rfで動くようになります!
なのでprofileには以下のコードを追加すればOKです。

remove-item alias:rm -Force
function rm() {Remove-Item -Recurse -Force $args}

わざわざrmを上書きする必要はないですが、PowerShellでrm -rfするのは面倒くさいので、rmrfとか登録しといた方が良いかも。

プロンプトをカラフルにする

image.png

白一色で見にくいのでカラフルにしたい!
PowerShellはpromptの値を書き換える事で表示を変えられます。

以下のコードを追加すればプロンプトがカラフルになります!

image.png

function prompt {
  Write-Host "$env:USERNAME " -ForegroundColor "Green" -NoNewline
    Write-Host "$pwd " -ForegroundColor Magenta -NoNewline
    Write-Host "$" -ForegroundColor "Green" -NoNewline
    return " "
}

-NoNewlineを外せば2行とかにもできるので、自分好みのプロンプトに変更しましょう。

ちなみに管理者権限か判断する場合、以下のコードで確認できます。

$isRoot = (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))

自分は管理者権限なら赤色、一般権限なら緑色にしたいので以下のようにしています。

image.png

function prompt {
  $isRoot = (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
  $color  = if ($isRoot) {"Red"} else {"Green"}
  $marker = if ($isRoot) {"#"}   else {"$"}

  Write-Host "$env:USERNAME " -ForegroundColor $color -NoNewline
    Write-Host "$pwd " -ForegroundColor Magenta -NoNewline
    Write-Host $marker -ForegroundColor $color -NoNewline
    return " "
}

詳細:prompt

キーボードバインド等を変更

以下の1行を追加するだけです。

Set-PSReadLineOption -EditMode Emacs -BellStyle None

-EditMode Emacsは、Emacsのキーバインドに変更します。
なので、Ctrl+uでキャレットより前の文字を全部消したりなど、bashと同じ感覚でショートカットが使えます。

-BellStyle Noneは、バックスペース押し続けた際のビープ音が鳴らなくなります。

詳細:Set-PSReadLineOption

所感

PowerShellは普通に使える!
もちろんWSL使った方が良いときもありますが、基本的にPowerShellで問題なく作業できます。
想像以上に機能が多く紹介しきれていない事も沢山あるので、気になったらPowerShell ドキュメントを見てみて下さい。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
14
Help us understand the problem. What are the problem?