この連載では、Microsoftが提供している新しいシェル、Windows Power Shellの使い方を解説します。前回に引き続きPowerShellにおける関数の取り扱いとして、変数と関数のスコープ、プロファイルの登録、パイプライン処理などについて取り上げます。

はじめに

 この連載では、Microsoftが提供している新しいシェル「Windows Power Shell」の使い方を解説します。今回は、関数をファイルに作成する方法、関数のプロファイルへの登録方法、パイプライン引数、begin/process/endについて説明します。

対象読者

  • Windows PowerShellでコマンドレット操作ができる方
  • 何らかのプログラミング経験があればなお良い

必要環境

  • Windows PowerShell

関数をファイルに作成する

 PowerShellの関数をファイルに作成するには、テキストエディタがあれば十分です。

 まずは、テキストエディタを開いて下記のように入力し、「MyFunction.ps1」として保存してください(説明の都合上、「C:\Work」に保存するものとします)。

MyFunction.ps1
function funcA
{
Write-Host "funcAです"
}

 では、この「MyFunction.ps1」にあるfuncAを実行するにはどうしたらよいでしょうか?

 1つの方法としては、この「MyFunction.ps1」に下記のように1行追加すると関数funcAを呼び出すことになります。

MyFunction.ps1に1行追加
function funcA
{
Write-Host "funcAです"
} funcA #この行を追加することでfuncAを呼び出す

 この「MyFunction.ps1」は function funcA { ~ } までが関数の定義で、ファイルにこの部分が書かれているだけでは実行されません。関数を実行するには、最後に追加した行のように、関数を呼び出す必要があります。

 「MyFunction.ps1」はfuncAを呼び出すように1行追加したので、下記のようにすれば、funcAが実行されることとなります(PowerShell入門(3) スクリプト編の「スクリプトファイルの実行とセキュリティ」を参照ください)。

関数を実行する
PS C:\Work> ./MyFunction.ps1
funcAです

 では、この関数をコマンドラインから、コマンドレットであるかのように関数名を指定するだけで呼び出すにはどうしたら良いでしょうか?

 「C:\Work」の下に「MyFunction.ps1」がある状態で、関数名を記述して[Enter]を押すと、

関数を実行する
PS C:\Work> funcA
用語 'funcA' は、コマンドレット、関数、操作可能なプログラム、またはスクリプト ファイルと
して認識されません。用語を確認し、再試行してください。
発生場所 行:1 文字:5
+ funcA <<<<

 のようにエラーが表示され実行することができません。関数名を記述するだけではだめなようです。

 では、いったいどのようにすればよいでしょうか?

 実は、コマンドラインから直接関数を呼び出すには、関数名の先頭にglobal修飾子が必要です。「MyFunction.ps1」を下記のように修正してください。

global修飾子をつけたfuncA
function global:funcA
{
Write-Host "funcAです"
}

 そして関数を使用するために、下記のようにしてPowerShellに関数を登録します。

PS C:\Work> ./MyFunction.ps1
PS C:\Work>

 これで準備はOKです。後は下記のように、コマンドラインで関数名を記述すれば実行されます。

PS C:\Work> funcA
funcAです

 このようにして登録を行った関数はGet-ChildItemコマンドレットで確認することができます。

PS C:\Work> Get-ChildItem function:

CommandType     Name                                 Definition
----------- ---- ----------
Function prompt 'PS ' + $(Get-Location) + $(if ($...
Function Clear-Host $spaceType = [System.Management.A...
:
:長いので省略
:
Function funcA Write-Host "funcAです"...

 実は、この方法で登録した関数はPowerShellを終了すると無効になってしまいます。ということで、次はこの問題を解決する方法について説明したいと思います。

関数をプロファイルに登録する

 PowerShellコンソール上で直接入力して作成した関数は、PowerShellコンソールを閉じてしまうと利用できなくなります。この問題は、関数をプロファイルに登録することで解決することができます。

 まずは、プロファイルについて説明します。プロファイルはPowerShell起動時に1度だけ読み込まれる特別なスクリプトファイルです。このファイルは、あらかじめパスが決まっており、$Profileという自動変数に格納されています。

 試しにコマンドラインで$Profileを確認してみましょう(表示されるパスはお使いの環境によって異なります)。

プロファイルパスの確認
PS > $Profile
C:\Users\HIRO\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

 コマンドラインで下記のように入力し、メモ帳でプロファイルを開いてみましょう。

メモ帳を開く
PS > Notepad $Profile

 後は、下記のように入力して、先ほど確認したパス(ここでは「C:\Users\HIRO\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1」)に保存します。

function funcA
{
Write-Host "funcAです"
}

 保存が終わったら、PowerShellを再起動し、funcAを実行してみましょう。

PS > funcA
funcAです

 このように、プロファイルに関数を記述すると、毎回PowerShellに関数を手動で登録する必要がなくなります(スクリプトの実行にはセキュリティ設定が必要ですので、動作しない場合は「関連記事 Windows PowerShell 入門(3)-スクリプト編」を参考に設定してください)。

 しかし、多数の関数を「Microsoft.PowerShell_profile.ps1」に記述するのはメンテナンスが大変です。

 これを解決する方法としてよこけんさんのサイトの「プロファイル活用」でスマートな方法が紹介されています(よこけんさんの承諾を得て掲載しております。よこけんさん、ありがとうございます)。実は、筆者自身もこの方法を採用していて、関数の管理が容易になります。

 ただし、1点だけ注意してもらいたいことがあります。それは、プロファイルに記述する関数はスコープを指定しなくても問題ありませんが、ファイルに記述する関数はglobalスコープが必要であるということです。

 先ほどのfuncAを「MyFunction.ps1」というファイルにグローバルスコープを付けて保存する場合は、

MyFuntion.ps1
function global:funcA
{
Write-Host "funcAです"
}

 とします。

パイプライン引数

 PowerShellでの関数は、パイプラインからの値を受け取ることが可能です。パイプラインからの渡された値は$inputという自動変数に格納されます。

 まずは、コンソールで下記の通り入力し、pipe-func1という関数をPowerShellに登録しましょう。

pipe-func1
PS > function pipe-func1
>> {
>> foreach ($a in $input)
>> {
>> Write-Host $a
>> }
>> }
>>

 この関数は、パイプラインで受け取った値をforeachで1つずつ取り出し表示するという単純な関数です。

 次のようにして、この関数を実験してみてください。

PS > 1..10 | pipe-func1
1
2
3
4
5
6
7
8
9
10

 1..10というのは、1から10までを表します(Windows PowerShell 入門(4)-変数と演算子の範囲演算子を参照ください)。結果としてこの関数は、$inputに1から10までの数値を受け取り、その値を表示します。

 もう1つ実験してみましょう。

PS > "apple","banana","orange" | pipe-func1
apple
banana
orange

 こちらは"apple","banana","orange"という3つの値が$inputに渡され、結果その値を表示します。

begin, process, end

 PowerShellでは、パイプラインで受け取った値を処理する方法にbegin/process/endというものが存在します。まずは、下記スクリプトを入力してください。

PS > function f
>> {
>> begin { $local:cnt = 1 }
>> process { ("$local:cnt:$_"); $local:cnt += 1 }
>> end { $local:cnt }
>> }
>>

 このスクリプトには、begin/process/endがありますが、パイプラインから値を受け取ると

begin {最初の1回だけ実行}
process {パイプラインで受け取った値ごとに実行}
end {最後に1回だけ実行}

 という動作をします。

 つまり、先ほど入力した関数fは、

  1. 最初にローカル変数cntを1で初期化
  2. パイプラインから受け取った値($_に値が代入されている)を表示し、ローカル変数をインクリメント
  3. 最後にローカル変数の現在値を表示

 ということを行います。

 先ほど、パイプライン引数の値は$input自動変数に入ることを説明しました。process節でパイプラインの値を取得する場合は$_自動変数となりますので、使用には注意してください。

 実際に、この関数にパイプラインから値を渡してみましょう。

PS > "apple","banana","orange" | f
1:apple
2:banana
3:orange
4

 パイプラインからの値を処理する際、前処理と後処理を行いたい場合は、ぜひ使用してみてください。

まとめ

 今回は、前回に引き続きPowerShellでの関数の取り扱いを取り上げ、次の内容について解説しました。

  • 関数をファイルに作成する
  • 関数をプロファイルに登録する
  • パイプライン引数
  • begin, process, end

 次回もPowerShellでの関数の取り扱いについて取り上げると共に、変数のスコープについても説明したいと思います。

Windows PowerShell 入門(7)-関数編2的更多相关文章

  1. Windows PowerShell 入門(3)-スクリプト編

    これまでの記事 Windows PowerShell 入門(1)-基本操作編 Windows PowerShell 入門(2)-基本操作編 2 対象読者 Windows PowerShellでコマンド ...

  2. Windows PowerShell 入門(2)-基本操作編 2

    前回に引き続きMicrosoftが提供している新しいシェル.Windows Power Shellの基本操作方法を学びます.基本操作編第2弾の今回は.パイプの使用方法を中心としたコマンドレットの操作方 ...

  3. Windows PowerShell 入門(8)-関数編3

    この連載では.Microsoftが提供している新しいシェル.Windows PowerShellの使い方を解説します.今回は.フィルタ.スクリプトブロック.変数のスコープについて取り上げます. はじめ ...

  4. Windows PowerShell 入門(6)-関数編1

    この連載では.Microsoftが提供している新しいシェル.Windows Power Shellの使い方を解説します.今回は.関数の作成基礎と引数.戻り値.Switchパラメータについて説明します. ...

  5. Windows PowerShell 入門(10)-デバッグ編

    対象読者 Windows PowerShellでコマンドレット操作ができる方 何らかのプログラミング経験があればなお良い 必要環境 Windows PowerShell デバッグメッセージの出力 Po ...

  6. Windows PowerShell 入門(9)-エラー編

    対象読者 Windows PowerShellでコマンドレット操作ができる方 何らかのプログラミング経験があればなお良い 必要環境 Windows PowerShell エラーをリダイレクトする リダ ...

  7. Windows PowerShell 入門(4)-変数と演算子

    Windows PowerShellにおける変数と演算子の使用方法について学びます.今回は代表的な演算子として.算術演算子.代入演算子.論理演算子.比較演算子.範囲演算子.置換演算子.ビット演算子.型 ...

  8. Windows PowerShell 入門(1)-基本操作編

    Microsoftが提供している新しいシェル.Windows Power Shellの基本操作方法を学びます.インストール.起動終了方法.コマンドレット.命名規則.エイリアス.操作方法の調べ方について ...

  9. Windows PowerShell 入門(5)-制御構文

    Windows PowerShellにおける制御構文について学びます.数ある制御構文の中でもSwitch文は.他の言語に比べ豊富な機能が用意されています. 対象読者 Windows PowerShel ...

随机推荐

  1. CSS3 vmax的用法

    1. calc() calc():在流体布局上,可以通过calc()计算得到元素的宽度. 2. vw/vh/vmin/vmax的使用 vw/vh/vmin/vmax是视窗单位,也是相对单位.相对的不是 ...

  2. [NIO-2]通道和FileChannel

    通道是什么 通道式(Channel)是java.nio的第二个主要创新.通道既不是一个扩展也不是一项增强,而是全新的.极好的Java I/O示例,提供与I/O服务的直接连接.Channel用于在字节缓 ...

  3. vue使用字体图标转码问题

    使用iconfont字体之后,出现的是一个方框,而没有出现相应的图标 需要通过String.fromCharCode方法转成指定unicode编码对应的十六进制字符 <div class=&qu ...

  4. 细说shiro之七:缓存

    官网:https://shiro.apache.org/ 一. 概述 Shiro作为一个开源的权限框架,其组件化的设计思想使得开发者可以根据具体业务场景灵活地实现权限管理方案,权限粒度的控制非常方便. ...

  5. 上传文件服务与web服务分离

    业务场景:1. 后端服务为java web应用,使用tomcat容器,多实例集群化部署.2. 前端使用nginx作为后端应用的反向代理. 业务需求:现在需要在java web应用端上传文件,同时还要能 ...

  6. JAVA线程池ScheduledExecutorService周期性地执行任务 与单个Thread周期性执行任务的异常处理

    本文记录: 1,使用ScheduledExecutorService的 scheduleAtFixedRate 方法执行周期性任务的过程,讨论了在任务周期执行过程中出现了异常,会导致周期任务失败. 2 ...

  7. nmap学习之nmap -sP 【目标】

    一.通过arp包判断局域网内的主机状态 二.对于局域网外的主机通过向主机 1)发送普通ICMP请求包[类型字段为8,代码字段为0]: 2)发送时间戳ICMP请求包[类型字段为13,代码字段为0]: 3 ...

  8. GCC编译器原理(二)------编译原理一:ELF文件(2)

    四. ELF 文件格式分析 ELF文件(目标文件)格式主要四种: 可重定向文件: 文件保存着代码和适当的数据,用来和其他的目标文件一起来创建一个可执行文件或者是一个共享目标文件.(目标文件或者静态库文 ...

  9. [译]kendoui - 方法和事件

    原文 为了使用方法和事件,首先要获取到widget实例. 获取widget 一共有3种获取widget的方式. jQuery的data方法 将widget的名作为参数传给jQuery的data方法.( ...

  10. matplotlib-形状

    需要   import matplotlib.patches as mp import numpy as np import matplotlib.pyplot as plt import matpl ...