2020-01-29

Windowsのパス文字列扱いを観察してみたので、備忘録。

パス文字列長は260文字以下。259文字まで。

PS C:\01234567890123456789012345678901234567890123456789\01234567890123456789012345678901234567890123456789\01234567890123456789012345678901234567890123456789\01234567890123456789012345678901234567890123456789> new-item -ItemType file -Path 12345678901234567890123456789012345678901234567890123
new-item : パス 'C:\01234567890123456789012345678901234567890123456789\01234567890123456789012345678901234567890123456789\01234567890123456789012345678901234567890123456789\01234567890123456789012345678901234567890123456789\1234567890123456789012345
6789012345678901234567890123' の一部が見つかりませんでした。
発生場所 行:1 文字:1
+ new-item -ItemType file -Path 123456789012345678901234567890123456789 ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (C:\012345678901...901234567890123:String) [New-Item], DirectoryNotFoundException
    + FullyQualifiedErrorId : NewItemIOError,Microsoft.PowerShell.Commands.NewItemCommand


PS C:\01234567890123456789012345678901234567890123456789\01234567890123456789012345678901234567890123456789\01234567890123456789012345678901234567890123456789\01234567890123456789012345678901234567890123456789> new-item -ItemType file -Path 1234567890123456789012345678901234567890123456789012

ここで、フォルダのC:\0...89\までで3文字 + 51文字 x4 = 207文字
作成したファイルが52文字である。


PS C:\01234567890123456789012345678901234567890123456789\01234567890123456789012345678901234567890123456789\01234567890123456789012345678901234567890123456789\01234567890123456789012345678901234567890123456789> Get-ChildItem | % {$_.FullName} | % {$_.Length}
259

さて、260文字制限は、フルパスの文字数なのでネットワークドライブとしてマウントすると、さらに深い階層に出来る。

 例えば、C:\01234567890123456789012345678901234567890123456789\01234567890123456789012345678901234567890123456789\01234567890123456789012345678901234567890123456789\01234567890123456789012345678901234567890123456789をネットワークドライブZ:にマウントして、Z:に長いパス名のフォルダを格納する事が出来る。
 無論、260文字を超えるパスのフォルダやファイルはC:から始まるパス表記を指定して削除する事は出来ない。

2020-01-12

 これは詳しい方々が散々書かれているので、備忘録。

  例えば、C:\TEST配下に以下の様なフォルダを作成する。
 NTFSでは[]は禁則文字ではないので、A[、[AB]といったフォルダ、ファイルは作成可能である。滅多にこの様な命名は無いと思いますが。

A                                                                                                                     AA                                                                                                                          AB                                                                                                                           A[                                                                                                                            B[                                                                                                                            [A                                                                                                                            [AB]                                                                                                   

 ここで、フォルダ名をフィルタ後、削除する簡単なスクリプトを実行してみる。

 これは Where-Objectで正しく[Aフォルダをフィルタする。それをRemove-Itemに渡してくれる。しかしながらRemove-Itemは[Aの[をワイルドカードとして扱うため、閉じる]が存在しないとして、エラーとなってしまう。

 PS C:\TEST> Get-ChildItem -Name | Where-Object {$_ -eq '[A'} | ForEach-Object {Remove-Item $_}
Remove-Item : コマンドレットの動的パラメーターを取得できません。指定されたワイルドカード文字パターンは無効です: [A
発生場所 行:1 文字:68
+ ...  -Name | Where-Object {$_ -eq '[A'} | ForEach-Object {Remove-Item $_}
+                                                           ~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Remove-Item]、ParameterBindingException
    + FullyQualifiedErrorId : GetDynamicParametersException,Microsoft.PowerShell.Commands.RemoveItemCommand



 これはWhere-Objectで正しく[AB]フォルダをフィルタする。それをRemove-Itemに渡してくれる。しかしながらRemove-Itemは[AB]を「[]がワイルドカードのため、A または B」として扱う。結果[AB]フォルダは削除せず、Aフォルダを削除してしまう。

PS C:\TEST> Get-ChildItem -Name | Where-Object {$_ -eq '[AB]'} | ForEach-Object {Remove-Item $_}

 解決するには{Remove-Item -LiteralPath $_}とする。

2020-01-11

 Powershellのヒアドキュメント改行コードではまったので、備忘録。  以下の様にSQL実行結果をログに出力するコードを作成。SQL実行結果の前に日時などをログに事前に出力させる。 日時などはまとめてヒアドキュメントで変数を作成しておく。

 出力結果のファイルをメモ帳で開くと、DATA,SHELL,SQLの文字列が改行されていない。サクラエディタでは改行されている。
 良く観察すると日時などの部分の改行はLFだが、SQL実行結果の部分の改行はWIndows標準のCR&LFになっている。
 そのためWindowsメモ帳ではLFだけの行が改行表示されないのであった。

 対応策は、ヒアドキュメントの各行の行末に
 `r  
と明示的にエスケープシーケンスのCRを追加した。


 謎なのはコードを一部修正する前はヒアドキュメントの部分もCR&LFのログが出力されていた事である。

2019-12-18

仕事上で他人のPowershellスクリプトを観察して感じたことを。

「Windowsバッチ臭い」のである。
例えば、バッチでパラメータを与える時、パラメータはスペース区切りで任意の複数個を記述できる。一見柔軟性が高い様だが、バッチ作成者以外から見ると厄介である。
不完全な設計書やプログラム本体を観察して、受け入れらるパラメータは何個なのか、パラメータの書式はどの様なものかを確認しないとバッチは利用できない。

対してPowershellであれば、利用者に負担を掛けずに使いやすいものを作成できる。

例えば以下のコードであれば、こんな感じで動いてくれる。
これであれば、指定が必須のパラメータは何なのか、パラメータはどの様な形式なのか、指定のものから選択する必要があれば、どの様な候補があるのか、等が対話的に表示できる。
一般的に他人のプログラムは「詳細設計書はあるが、このプログラムは何が出来るのか?」が判らないので、この様なものが必要と思うが、如何だろうか。


PS C:\Users\doctor_d\Desktop> C:\Users\doctor_d\Desktop\1.ps1
コマンド パイプライン位置 1 のコマンドレット 1.ps1
次のパラメーターに値を指定してください:
(ヘルプを表示するには、「!?」と入力してください。)
Number: !?
Number のヘルプはありません。
Number: 1
String: !?
YesまたはNoを選択
String: Yes
1
Yes


2019-11-09

旧CITI bankがSMBCに売却されて、CITI GoldはPRESTIA Goldに継承された。

 ATMカードであるCITI CardはGLOBAL PASSという名称のDebit機能を持つATMカードに順次置き換えられる。
 機能面では国内ATM兼海外ATMカード兼Visa Debitとなるので、大幅改善である。

 しかしながら、この券面は如何なものか。

 GOLDというよりは、茶色。1色刷りのために安っぽさが感じられる。全くプレミアム感が無い。この手のカードは見易さを考えて、文字と地色のコントラストを高めにするのが多いが、現物のカードは茶色も薄めのためコピーし損ねたカードの様である。

 ANAマイレージGLOBAL PASSは多色刷りで、こちらの方がずっとデザインが良い。

 通常のPRESTIA GLOBAL PASSもAMEXのパチモノみたいで、SMBCのデザイン能力は本当に良く判らない。

2019-10-14

 プログラムはN-BasicとZ80のアセンブラしか判りません。

 そこでPowershellでログ管理のプログラムを作成していた時に変数のスコープではまったので備忘録。

 N-Basicでは変数はプログラムのどこでも同様の働きをするし、同一のものとして扱われる。しかしながら、Powershellでは動きが異なる。

 例えば以下の様に、変数Switchを$TRUEとして、この変数を$FALSEへ切り替える場合を考えてみよう。
 ここで、N-Basic的にはサブルーチンの様な、functionであるChangeSwitchを呼び出せば変数Switchが$Falseに切替できると思うのだが、挙動は異なる。

 冒頭の変数Switchとfunctionの中にある変数Switchは同じ名称でも異なるものなってしまうのだ。
 functionの中にある変数Switchはfunction内だけで有効な変数なので、functionから抜けた時にはfunctionの中の変更は反映されない。




[Param](
[Boolean]$Switch = $TRUE
 )

function ChangeSwitch{

$Switch = $FALSE

}




 それではどうするのか?
 以下の様に 変数のスコープを明示的にスクリプト内に指定する。




[Param](
[Boolean]$Switch = $TRUE
 )

function ChangeSwitch{

$Script:Switch = $FALSE

}




2019-10-10

 また仕事の話題。既存の基幹系アプリケーションをAWSへ載せ替えた。
 この手のものは、アプリケーション移行よりも運用監視機能の移行が結構大変で「従来と同じ運用手順で」という要望が多い。

 そうすると、運用ジョブの移行で頭を悩ませる事になる。AWSはEC2&EBSのスナップショット取得がバックアップに相当するので、これを活用するのだが生憎これをJP1 AJSから制御するのは大変。

 そのため実装は以下の様にしてみた。

 下から説明していく。
 AWSのスナップショットはAWS CLIで制御可能だが、これを踏まえた新規開発は人月が必要なので、仮想アプライアンスであるN2WSを導入する。

 N2WSは内部でAWS CLIを発行して、EC2&EBSのスナップショット取得や世代管理を行うアプライアンスである。そしてWeb UIによる手動運転、アプライアンス内蔵のスケジューラによる自動運転、N2WS API経由の付属Pythonコマンド集による手動運転ができる。

 今回は、Powershell自作スクリプトが、最後のPythonコマンドを発行、ログ出力等を担っている。

 この構造で任意のジョブスケジューラで業務ジョブと運用ジョブ両方を制御できる。

JP1/AJS

Powershellの自作スクリプト

N2WS付属のPythonコマンド集

N2WS

AWS (AWS CLI)


 Powershellの自作スクリプトは2種類製造している。
 1個目は、バックアップの起動、2個目はバックアップ結果の確認である。
 Pythonコマンド集のバックアップの起動は「起動に成功した」というステータスしか戻ってこないため、別途結果確認のPythonコマンドを発行するPowershellスクリプトで確認している。

 最後に余談だが、AWSのスナップショットは「ストレージ最適化」中に取得できない制限がある。
 「ストレージ最適化」はEBSやRDSの領域拡張後に発生するが、意外に時間が必要である。処理中もサービスは継続するのだが、夜間のバックアップが何故か失敗している、という事象の際にはこの制限が起因か確認すると良い。

自己紹介

自分の写真
東京都, Japan
憂鬱な凍死家です。こちらではmixiとは異なり固めの話題中心です。

Total Page View

Categories

Powered by Blogger.

Popular Posts

Blog Archive