※本記事は PowerShell Advent Calendar 2012 の 11 日目です。
どういうわけかお誘いを頂いたので書いてみることにします。
本当は先週末にやろうと思っていたんですが WiiU に夢中になってすっかり忘れていました。
PowerShell、便利ですよね。何が便利って .NET Framework をそのまま使えるのがいい。
もうスクリプトを JavaScript とか MS-DOS バッチファイルなんかで書く気にはなれません。
というわけで、様々なタスクの自動処理に使われるわけですが、しばしば、よくわからないポイントでハマります。
PowerShell コンソールを立ち上げて、その中だけで完結する処理であればいいのですが、他のアプリから PowerShell を実行して処理をさせたい場合とかに困ります。
具体的にどういう場合かというと…やっぱりここで言うのはやめておきます。お察しください。
なお、俺は PowerShell を日頃からゴリゴリいじっているわけでもないので、詳しくありません。はっきり言って素人です。
そのため、「こんなことでハマりました」というのは書いているものの、「ハマらないためにはどうしたらいいか」はわかりません。
きっと、日々PowerShell を操っている諸兄から見ると、当然の挙動なのやもしれません。
教えてエロい人。
というわけで、以下、本編(前編)です。
こんなスクリプトを用意します。単純に引数を1つずつ表示するだけです。
test1.ps1
'Length: ' + $args.Length for ($i = 0; $i -lt $args.Length; ++$i) { "[{0}]: {1}" -f $i, $args[$i] }
まずはこれを、PowerShell コンソールから実行してみます。
call1.ps1
'(1) -----' .\test1.ps1 a b c '(2) -----' .\test1.ps1 'a b' c '(3) -----' .\test1.ps1 "a b" c
結果はこうなります。当然ですね。
call1.ps1 結果
(1) ----- Length: 3 [0]: a [1]: b [2]: c (2) ----- Length: 2 [0]: a b [1]: c (3) ----- Length: 2 [0]: a b [1]: c
何も疑問を挟む余地はありません。
次にこれを、別の powershell.exe プロセスを立ち上げて実行してみます。
fork1.ps1 (A)
'(1) -----' powershell.exe .\test1.ps1 a b c '(2) -----' powershell.exe .\test1.ps1 'a b' c '(3) -----' powershell.exe .\test1.ps1 "a b" c
結果はこうなります。…どうしたことでしょう。
fork1.ps1 (A) 結果
(1) ----- Length: 3 [0]: a [1]: b [2]: c (2) ----- Length: 3 [0]: a [1]: b [2]: c (3) ----- Length: 3 [0]: a [1]: b [2]: c
他にもいろいろ試してみましょう。
fork1.ps1 (B)
'(4) -----' powershell.exe .\test1.ps1 'a b c' '(5) -----' powershell.exe .\test1.ps1 "a b c" '(6) -----' powershell.exe .\test1.ps1 "'a b' c" '(7) -----' powershell.exe .\test1.ps1 '"a b" c'
結果はこうなります。
fork1.ps1 (B) 結果
(4) ----- Length: 3 [0]: a [1]: b [2]: c (5) ----- Length: 3 [0]: a [1]: b [2]: c (6) ----- Length: 2 [0]: a b [1]: c (7) ----- Length: 3 [0]: a [1]: b [2]: c
(6)だけ差が出ました。
ちなみに(6)は
powershell.exe ".\test1.ps1 'a b' c"
としても、同じ結果になりました。
powershell.exe のコマンドラインオプションには -File というものもあります。
これをつけてみましょう。
fork1.ps1 (C)
'(8) -----' powershell.exe -File .\test1.ps1 a b c '(9) -----' powershell.exe -File .\test1.ps1 'a b' c '(10) -----' powershell.exe -File .\test1.ps1 "a b" c '(11) -----' powershell.exe -File .\test1.ps1 'a b c' '(12) -----' powershell.exe -File .\test1.ps1 "a b c" '(13) -----' powershell.exe -File .\test1.ps1 "'a b' c" '(14) -----' powershell.exe -File .\test1.ps1 '"a b" c'
結果はこうなりました。
fork1.ps1 (C) 結果
(8) ----- Length: 3 [0]: a [1]: b [2]: c (9) ----- Length: 2 [0]: a b [1]: c (10) ----- Length: 2 [0]: a b [1]: c (11) ----- Length: 1 [0]: a b c (12) ----- Length: 1 [0]: a b c (13) ----- Length: 1 [0]: 'a b' c (14) ----- Length: 2 [0]: a b [1]: c
-File のありなしで結果が全然違いますね。参った…。
とはいえ、概ね、そうなるだろうと(素人考えで)期待したように実行されているように思われます。
一点、(13) と (14) の結果が非対称なのが気になるところですね…。
最後に、MS-DOS のバッチ (.cmd) ファイルから実行した場合の結果も載せておきます。
call1.cmd
@echo off echo (1) ----- powershell.exe .\test1.ps1 a b c echo (2) ----- powershell.exe .\test1.ps1 "a b" c echo (3) ----- powershell.exe .\test1.ps1 'a b' c echo (4) ----- powershell.exe -File .\test1.ps1 a b c echo (5) ----- powershell.exe -File .\test1.ps1 "a b" c echo (6) ----- powershell.exe -File .\test1.ps1 'a b' c
こいつの結果は、今までのどれとも異なります。
call1.cmd 結果
(1) ----- Length: 3 [0]: a [1]: b [2]: c (2) ----- Length: 3 [0]: a [1]: b [2]: c (3) ----- Length: 2 [0]: a b [1]: c (4) ----- Length: 3 [0]: a [1]: b [2]: c (5) ----- Length: 2 [0]: a b [1]: c (6) ----- Length: 3 [0]: 'a [1]: b' [2]: c
本記事はひとまず、ここでおしまいです。
が、実はまだ本題に入っていなかったりします。
しかしながら、アドベントカレンダーという性質上、日付が変わる前に掲載しないといけませんので、一旦区切らせて頂きます。
後編は、param を使ってパラメーターを宣言したファイルを外部から呼び出したりしてみます。配列型の引数とか使います。
WiiU とペーパーマリオに気を取られていなければ、きっと今週中には書くはずです。
# はてなブログって PowerShell のシンタックスハイライトには対応してないんですかね…