本シリーズのトップページ |
---|
https://qiita.com/robozushi10/items/0b0605257ad39bc22895 |
はじめに
CI/CD のひとつとして、自動対話処理 (いわゆる expect 相当) を実装することになったので書き残しておく.
このとき、パラメータ定義ファイルに XML を用いた.
Python とは異なり、PowerShell は XML の取り扱いに優れているので併せて記しておく.
環境
Windows 10 Pro
PowerShell バージョン 6系
プログラムについて
処理概要
次の 1 〜 5 の処理をするコードである.
1. 挙動パラメータを記した XML ファイルを読み込む.
2. 上記 1 のパラメータを使ってシリアルポートを開く (接続先は Linux 端末とする).
3. 上記 1 のパラメータを使ってシリアルポートにコマンド「ls -ltr」を書き込む.
4. 上記 3 のコマンド結果を読み出す.
5. 上記 4 で読み出した結果をコンソールとログファイルの2つに書き込む.
コード
config.xml
挙動パラメータを記した XML ファイルである.(1, 2, 3)
<?xml version="1.0" encoding="UTF-8"?>
<MY>
<COM>COM3</COM> <!-- COM番号 -->
<BPS>115200</BPS> <!-- ボーレート -->
<PRT>None</PRT> <!-- パリティ-->
<LEN>8</LEN> <!-- データ長 -->
<FLC>one</FLC> <!-- フロー制御 -->
<COMMAND>
<EXEC>cd /tmp; echo 'EOL'</EXEC> <!--「EOL」が表示されたらコマンド終了と見なす -->
</COMMAND>
<COMMAND>
<EXEC>ls -ltr; echo 'EOL' </EXEC> <!--「EOL」が表示されたらコマンド終了と見なす -->
</COMMAND>
</MY>
sample.ps1
下記🛑の「^[
」と「^M
」は制御文字である.
# XML ファイルを読み込む.
$XML = [xml]( Get-Content config.xml )
# 「.」区切りで要素にアクセスする.
$COM = $XML.MY.COM
$BPS = $XML.MY.BPS
$PRT = $XML.MY.PRT
$LEN = $XML.MY.LEN
$FLC = $XML.MY.FLC
# <COMMAND> が複数あるので、配列としてインデックスで指定する
$CMD = [string] $XML.MY.COMMAND[1].EXEC
# シリアル端末の設定を取得する
$port= New-Object System.IO.Ports.SerialPort $COM,$BPS,$PRT,$LEN,$FLC
# ポートをすでに開いているか判定する. 多重で開こうとすると例外が起きる.
if( $port.IsOpen )
{
Write-Host "エラー: すでにポート $COM は使用中であるか、あるいは存在しないポートです"
exit $False
}
# シリアル端末にコマンド「ls -ltr」を入力して実行する.
# $port.WriteLine の方が確実に改行コードの入力ができることもある.
$port.Write( $CMD + "`r")
# コマンド「ls -ltr」の実行結果を 1秒間隔で 1行ずつ読み出す
do
{
# コマンド「ls -ltr」の実行結果を 1行読み出す
$line = $port.Readline()
# 🛑読み出したログに ANSI Color コードがあるとジャマなので削除する🛑
$line = $line | % { $_ -replace '\[\d+(;\d+)?m' } | % { $_ -replace '^[' } | % { $_ -replace '^M' }
# 今回は「EOL」という文字列が出たら、読み込み待ちを終了する
if( $line -match "EOL" )
{
break
}
# 表示結果を log.txt に追加書き込みする
$line | Out-File -Encoding Default -Append log.txt
# ついでに標準エラーにも出力する (Bash での「echo "〜" 1>&2」に相当する)
Write-Host "$line"
# 1秒待機する
Start-Sleep 1
}
while($line)
以上.