はじめに
べた書きのファイルをコマンドにして、さらにヘルプを付けるときに詰まったので書きました。
所々無理やり解決しているところがあります。
ここで言うスクリプトとは "関数になってない、処理がべた書きのモノ" を指します。
(そういうのをなんていえばいいんでしょうか?どなたか教えてください!)
事前知識
bash における .bashrc に当たるもの
自作コマンドを作るには、例えば Linux 等では .bashrc
に関数を書けばよい。
(誤解を与える表現だったので訂正すると、Linux ではふつうは新しくファイルを作りパスを通すことが多い。ただし .bashrc
に関数を書いても自作コマンドになる。)
Linux での例
ファイルを作りパスを通す例
-
~/commands/
に新しくファイルを作成する (例えばhoge
(拡張子なし)) - その中に以下のように記述する
#!/bin/sh
# repeat "hoge" for the given number
for ((i=1;i<=$1;i++));do echo "hoge"; done
.bashrc
に関数として書く書き方
-
.bashrc
に以下のように記述する
# .bashrc
hoge(){
# repeat "hoge" for the given number
for ((i=1;i<=$1;i++));do echo "hoge"; done
}
PowerShell では例えば \Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
などがそれにあたる。ただし複数種類があり、使い分けがされているようなので詳しくは以下を参照。
ちなみに私の環境では echo $PROFILE
と打つと出てくる \Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
をいつも使っている。
ドットソースによる別ファイルの展開
Powershell でもファイル分割をすることができ、
. "<ファイルパス>" # <ドット> <スペース> <ファイルパス> の順
以上のようにすると、その場で同じコンテキストで別ファイルを展開することができる。
(ファイルパスに空白がない場合は引用符は不要だが、つけておくと安心)
エイリアスの設定
Linuxと同様にコマンドに対して Powershell でもエイリアスを設定することができる。
Set-Alias -Name <エイリアス名> -Value <実際のコマンド名・パス>
# 簡略版
sal <エイリアス名> <実際のコマンド名・パス>
Set-Alias
のエイリアスは sal
で、また -Name
, -Value
オプションは明示しなくてもいい
例)
> Set-Alias -Name list -Value Get-ChildItem
# 簡略版
> sal list Get-ChildItem
case 01: 別ファイルにあるのは関数である → ドットソースで読み込み
この場合は簡単で、ドットソースで別ファイルを profile.ps1
等に展開 してあげればいい。
例)
# C:/hoge.ps1
function hoge{
Param([int]$num)
for ($i = 0; $i -lt $num; $i++) {
Write-Output "ほげ";
}
}
# profile.ps1
. C:/hoge.ps1 # ドットソースで読み込み
実行
> hoge 2
ほげ
ほげ
加えてこの場合は以下のようにすると、manコマンド用にヘルプなどを書いて表示させることができる。
(2024年8月6日 ファイルにミスがあったため修正)
<#
.Description
与えられた回数分 hoge って言います
#>
function hoge{
Param(
[int]$num
)
for ($i = 0; $i -lt $num; $i++) {
Write-Output "ほげ";
}
}
> man hoge # ちゃんとヘルプが表示される
名前
hoge
概要
構文
hoge [[-num] <Int32>] [<CommonParameters>]
説明
与えられた回数分 hoge って言います
<省略>
詳しくは以下参照
Operations Lab. "PowerShell スクリプトのコマンドヘルプの書き方(簡易版)"
追記: まとめて別ファイルの関数を登録する方法
@AWtnb さんのこの記事に、まとめて自作コマンドを登録するわかりやすい方法が乗っていたので追記しておきます!
case 02: 別ファイルにあるのはスクリプトである
解決策 01: alias でとりあえず別ファイルを実行する (簡単)
例
# C:/hoge.ps1
Param([int]$num)
for ($i = 0; $i -lt $num; $i++) {
Write-Output "ほげ";
}
# profile.ps1
Set-Alias hoge C:/hoge.ps1
実行
> hoge 2
ほげ
ほげ
しかしこの場合はたとえファイルにヘルプがかかれていたとしても、 man コマンドで参照することはできない。
# C:/hoge.ps1
<#
.Description
与えられた回数分 hoge って言います
#>
Param([int]$num)
for ($i = 0; $i -lt $num; $i++) {
Write-Output "ほげ";
}
> man hoge # 思ったようにはならない
Name : hoge
Category : Alias
Synopsis : hoge.ps1
Component :
Role :
Functionality :
ただし、この方法では Executionpolicy
が RemoteSigned
以上でないと失敗する。
解決策 02: profle.ps1
に新たに関数を作り、別ファイルを実行する
- profile.ps1 内に新たに関数
hoge()
を作り、パラメタを渡す(ヘルプ用のコメントも書く) - そのパラメタをまた
hoge.ps1
に渡して実行する
という回りくどいことをすることになる。(どなたかもっとスマートなやり方があればご教示願います!)
# C:/hoge.ps1
<#
.Description
与えられた回数分 hoge って言います
#>
Param([int]$num)
for ($i = 0; $i -lt $num; $i++) {
Write-Output "ほげ";
}
# profile.ps1
function hoge {
<#
.Description
与えられた回数分 hoge って言います
#>
Param([int]$num) # hoge関数がパラメタを受け取り
C:/hoge.ps1 $num # ps1ファイルに渡す
}
> hoge 2
ほげ
ほげ
> man hoge # ちゃんと出る
名前
hoge
概要
構文
hoge [[-num] <Int32>] [<CommonParameters>]
説明
与えられた回数分 hoge って言います
この方法も Executionpolicy
が RemoteSigned
以上でないと失敗する。
(追記:)解決策 03: 自作コマンド専用のディレクトリを作り、そこに Path を通す。
恥ずかしながらこの方法をすっかり忘れていたので追記します。
まんま Linux と同じような方法である。
- 自作コマンド専用のディレクトリを作る
- そこに先ほどのps1ファイルを持って来る
- ディレクトリにPathを通す
例)
-
D:\mycmd\
ディレクトリを作る -
そこに先ほどのファイルを持って来る
# D:\mycmd\hoge.ps1 <# .Description 与えられた回数分 hoge って言います #> Param([int]$num) for ($i = 0; $i -lt $num; $i++) { Write-Output "ほげ"; }
-
D:\mycmd
にパスを通す(GUIでやるのが一番楽だが、Powershell からでもできる) -
実行
> hoge 2 # hoge.ps1 2でも同じこと ほげ ほげ
-
man コマンド
> man hoge.ps1 名前 D:\mycmd\hoge.ps1 概要 構文 D:\mycmd\hoge.ps1 [[-num] <Int32>] [<CommonParameters>] 説明 与えられた回数分 hoge って言います [省略]
ただしこの方法も Executionpolicy
が RemoteSigned
以上でないと失敗する。
結論
別ファイルに自作コマンドを書くときは関数にしよう!!!
それか(実行時ポリシーを変更して)自作コマンド専用のディレクトリを作ろう
その他参考文献
2024年8月6日追記:
解決策03・一部ファイルのミス・実行時ポリシーについて追記