2021年11月02日(火) [長年日記]
■ [windows] WSLメモ
WSLについていくつかメモ。
wsl.exe
wsl.exeコマンドによりWindowsからLinuxコマンドを呼び出すことができる。
PS C:\> wsl uname Linux
wsl.exeにはディストリビューションの管理(インストールしたり停止したり)を行う機能もある。多機能なので詳しくはヘルプやドキュメントを参照のこと。
PS C:\> wsl --help
- WSL のコマンド リファレンス (docs.microsoft.com)
環境変数WSLENV
環境変数WSLENVに環境変数名を指定することで、WindowsとLinuxで環境変数を共有することができる。
$ abc=100 def=200 cmd.exe /C echo %abc% %def% %abc% %def% $ abc=100 def=200 WSLENV=abc cmd.exe /C echo %abc% %def% 100 %def% $ abc=100 def=200 WSLENV=abc:def cmd.exe /C echo %abc% %def% 100 200
WSLENVに指定する環境変数名にはフラグを付けられるが、/p と /l を使うと現在の自分の環境だとコアダンプしてしまう…。このissueが近い気がするけれどこれは修正済みだと思われる。
$ abc=100 def=200 WSLENV=abc/w:def cmd.exe /C echo %abc% %def% 100 200 $ abc=100 def=200 WSLENV=abc/u:def cmd.exe /C echo %abc% %def% %abc% 200 $ abc=100 def=200 WSLENV=abc/p:def cmd.exe /C echo %abc% %def% zsh: segmentation fault abc=100 def=200 WSLENV=abc/p:def cmd.exe /C echo %abc% %def% $ abc=100 def=200 WSLENV=abc/l:def cmd.exe /C echo %abc% %def% zsh: segmentation fault abc=100 def=200 WSLENV=abc/l:def cmd.exe /C echo %abc% %def%
- WSLENV を使用して Windows と WSL の間で環境変数を共有する (docs.microsoft.com)
/bin/wslpath
wslpathコマンドを使うとパスの形式をWindows用とLinux用に相互変換できる。
$ wslpath -u 'C:\abc\def' /mnt/c/abc/def $ wslpath -w /home \\wsl$\Debian\home $ wslpath -m /home //wsl$/Debian/home
- WSLのリリースノート#ビルド 17046 (docs.microsoft.com)
2021年11月05日(金) [長年日記]
■ [go] Goを複数バージョンインストールする
以前もやったが何も覚えていなかったのでメモしておく。と言っても
- Managing Go installations (golang.org)
にあるままだが。
インストールにgoコマンドを使用するので、事前にGoをインストールしておく必要があることに注意。
golang.org/dl のインストール
バージョン指定でのgoのインストールにはgolang.org/dlというパッケージを使う。go installコマンドを使ってインストールしたいGoのバージョンに対応する名前のパッケージをインストールする(go installコマンドが使えるのはGo 1.16からかもしれない。goコマンドが古い場合はgo getコマンドを使うと思われる)。
ここでは golang.org/dl/go1.17.3 (の最新バージョン)をインストールする。
$ go install golang.org/dl/go1.17.3@latest
こうすると $HOME/go/bin/go1.17.3 が作られる。これがgoコマンドのラッパーになるが、まだGo本体はインストールされておらずgoコマンドとしては使えない。
Goをインストールする
上で作られたgo1.17.3を使い次のようにすると対応バージョンのGoをインストールできる。
$ go1.17.3 download
これで $HOME/sdk/go1.17.3/ が作られここにGo 1.17.3がインストールされたようだ。
以上で $HOME/go/bin/go1.17.3 をGo 1.17.3のgoコマンドとして使えるようになる。
$ go1.17.3 version go version go1.17.3 linux/amd64
2021年11月10日(水) [長年日記]
■ [go] big.Rat
Goで有理数を扱えるbig.Ratを使ったのでちょっとメモ。Goのバージョンは1.17.3。
package main import ( "fmt" "math/big" ) func printRat(r *big.Rat, text string) { fmt.Println(text, r.FloatString(20), r.String()) } func main() { a := big.NewRat(-11, 10) b := new(big.Rat).SetFloat64(-1.1) c, _ := new(big.Rat).SetString("-1.1") printRat(a, "NewRat(-11, 10) : ") printRat(b, "SetFloat64(-1.1) : ") printRat(c, `SetString("-1.1") : `) }
NewRat(-11, 10) : -1.10000000000000000000 -11/10 SetFloat64(-1.1) : -1.10000000000000008882 -2476979795053773/2251799813685248 SetString("-1.1") : -1.10000000000000000000 -11/10
- SetFloat64() で値をセットすると誤差が入る可能性があることに注意。SetString() を使う場合は大丈夫そう。
- 値をコピーするときは Set() を使うようマニュアルに書かれている。
To "copy" a Rat value, an existing (or newly allocated) Rat must be set to a new value using the Rat.Set method; shallow copies of Rats are not supported and may lead to errors.
2021年11月28日(日) [長年日記]
■ [windows] コマンドラインでサービスの情報を確認する
Windowsのコマンドラインでサービスの情報を得る方法として
- sc.exe
- Get-Service (PowerShellのコマンドレット)
の2つがあることを知った。
sc.exeの方について少しメモ。sc.exeのちゃんとしたマニュアルは見つからなくて、上記のリンク先はWindows Server 2012のドキュメント。
sc.exeでサービスの情報を得られそうなサブコマンドとしてquery, queryex, qcがある。それぞれの実行結果を次に示す。
> sc query com.docker.service SERVICE_NAME: com.docker.service TYPE : 10 WIN32_OWN_PROCESS STATE : 4 RUNNING (STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN) WIN32_EXIT_CODE : 0 (0x0) SERVICE_EXIT_CODE : 0 (0x0) CHECKPOINT : 0x0 WAIT_HINT : 0x0
> sc queryex com.docker.service SERVICE_NAME: com.docker.service TYPE : 10 WIN32_OWN_PROCESS STATE : 4 RUNNING (STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN) WIN32_EXIT_CODE : 0 (0x0) SERVICE_EXIT_CODE : 0 (0x0) CHECKPOINT : 0x0 WAIT_HINT : 0x0 PID : 5028 FLAGS :
> sc qc com.docker.service [SC] QueryServiceConfig SUCCESS SERVICE_NAME: com.docker.service TYPE : 10 WIN32_OWN_PROCESS START_TYPE : 2 AUTO_START ERROR_CONTROL : 1 NORMAL BINARY_PATH_NAME : "C:\Program Files\Docker\Docker\com.docker.service" LOAD_ORDER_GROUP : TAG : 0 DISPLAY_NAME : Docker Desktop Service DEPENDENCIES : LanmanServer SERVICE_START_NAME : LocalSystem
- queryexはqueryで得られる情報にPIDとFLAGSが加わった結果になっている。
- 現在の状態(STATE)はqueryで得られる。
- 起動設定(START_TYPE)はqcで得られる。
2021年11月29日(月) [長年日記]
■ [windows] Zipファイルを作るPowerShellスクリプト
初めてPowerShellスクリプトを書いた。フォルダパスとZipファイルパスを指定すると、フォルダ内の.exeと.dllをアーカイブしたZipファイルを作成するスクリプト。
param( [Parameter(Mandatory=$true)][String]$srcDir, [Parameter(Mandatory=$true)][String]$zipFile ) try { # エラーが発生したら処理を止める $ErrorActionPreference = "Stop" Write-Host "$srcDir --> $zipFile" # 一時フォルダを作成 $tmpDir = New-TemporaryFile | % { Remove-Item $_; New-Item -ItemType Directory $_-d } # 一時フォルダへ必要なファイルだけをコピー Copy-Item -Include *.exe,*.dll $srcDir\* $tmpDir # zipファイルが存在している場合はそれを削除 if (Test-Path $zipFile) { Remove-Item $zipFile } # zipファイルを作成 Compress-Archive $tmpDir/* $zipFile # zipファイルの内容を出力 Add-Type -AssemblyName System.IO.Compression.FileSystem [System.IO.Compression.ZipFile]::OpenRead($zipFile).Entries | Format-Table -Property FullName,LastWriteTime } finally { # 一時フォルダを削除 if ($tmpDir) { Remove-Item -Recurse $tmpDir } }
PowerShellスクリプトの実行方法
PowerShellスクリプトはデフォルトの設定だとセキュリティエラーになり実行できない。
PowerShellコマンドにExecutionPolicyオプションと共にスクリプトを指定すれば実行できる。
> powershell -ExecutionPolicy unrestricted ./make-zip.ps1 test test.zip test --> test.zip FullName LastWriteTime -------- ------------- a.exe 2021/11/29 16:26:54 +09:00 b.dll 2021/11/29 16:20:18 +09:00
スクリプトのパラメータ
スクリプトのパラメータはparamで指定できる。ちゃんとした説明を見つけられないがParameters in scriptsで少し説明されている。
上のスクリプトではParameter属性を使って2つのパラメータ(srcDirとzipFile)を必須に設定している。
エラー時にスクリプトを終了する
処理中にエラーが発生したらそこでスクリプトは止まってほしい。それを実現するには、$ErrorActionPreferenceにStopを設定すればいいようだ。
メッセージの出力
メッセージを出力するにはWrite-HostまたはWrite-Outputが使える。
一時フォルダの作成と削除
PowerShellには一時フォルダを作成する機能はなさそう。上のスクリプトではStack Overflowにあった例を真似して、一時ファイルを生成 → その一時ファイルのパスを利用して一時フォルダを作成、という手順で作っている。
なお、一時フォルダ作成処理内にある「%」はForEach-Objectのエイリアス。
作成した一時フォルダの削除はtry/finallyステートメントのfinally内で行うようにしている。
Zipファイルの作成
Zipファイルの作成にはCompress-Archiveが使える。
Zipファイル内のファイル一覧を出力
Zipファイルの作成は上述のCompress-Archiveでできるが、Zipファイル内のファイル一覧を得るコマンドレットは無いみたい。Zipファイルを展開するのならExpand-Archiveを使えるのだけれど。
ファイル一覧を得るには、.NETのライブラリを使う必要がありそう。System.IO.Compression.ZipFileというクラスが使える。
PowerShellでは、Add-Typeを使うとDLLを読み込んで.NETのクラスを使えるようになる。上のスクリプトではSystem.IO.Compression.FileSystem.dllを読み込んで ZipFile#OpenRead() を呼び出し、更にFormat-Tableを使って出力を行っている。
2021年11月30日(火) [長年日記]
■ [windows][howto] PowerShell上でコマンドの実行時間を計る
PowerShell上でコマンドの実行時間を計るにはMeasure-Commandを使える。
> measure-command { sleep 5; echo hello | out-default } hello Days : 0 Hours : 0 Minutes : 0 Seconds : 5 Milliseconds : 18 Ticks : 50180649 TotalDays : 5.80794548611111E-05 TotalHours : 0.00139390691666667 TotalMinutes : 0.083634415 TotalSeconds : 5.0180649 TotalMilliseconds : 5018.0649
- 計測対象の出力を表示したい場合はOut-Defaultへパイプすればよい。