メモの日々


2021年11月02日(火) [長年日記]

[windows] WSLメモ

WSLについていくつかメモ。

wsl.exe

wsl.exeコマンドによりWindowsからLinuxコマンドを呼び出すことができる。

PS C:\> wsl uname
Linux

wsl.exeにはディストリビューションの管理(インストールしたり停止したり)を行う機能もある。多機能なので詳しくはヘルプやドキュメントを参照のこと。

PS C:\> wsl --help

環境変数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%

/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

2021年11月05日(金) [長年日記]

[go] Goを複数バージョンインストールする

以前もやったが何も覚えていなかったのでメモしておく。と言っても

にあるままだが。

インストールに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.

[windows][dev] Visual Studioでエディタのフォントサイズの拡大率を変更する

Visual Studio 2019を使っている。

VSのエディタのフォントサイズがいつの間にか小さくなっていることがたまにあって困っていたが、エディタの左下に拡大縮小用のプルダウンメニューがあることにやっと気づけた。Ctrlキーを押しながらのマウスホイール操作で拡大率を変更できることも知った。

変更用メニュー

2010年の記事だが@ITでこの機能が紹介されていた。


2021年11月28日(日) [長年日記]

[windows] コマンドラインでサービスの情報を確認する

Windowsのコマンドラインでサービスの情報を得る方法として

の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へパイプすればよい。