VSCode で C# のブロック {} 前後の改行の設定を変更する 2023

本記事は C# Advent Calendar 2023 の2日目の記事だ。

1日目は @RyotaMurohoshi 氏の 【Allって】LINQ、この場合どうなる?【空配列は?】 #C# - Qiita だった。

以前バズった空配列議論のツイートを例に、 .NET の LINQ の各エッジケースでどう振る舞うかまとめた記事になっている。
なかなかのボリュームで読み応えがある。

慣れていないと迷ったり勘違いしやすい話なので、参考になる。

C# を K&Rスタイル で整形したい

さて、 C# の既定のコードフォーマットでは、名前空間やクラス、メソッドなど、各種ブロックの {} (中括弧・波括弧) の手前に改行が入る。(所謂、オールマンスタイル)

namespace MyNamespace
{
    class Class1
    {
        static void Main(string[] args)
        {
            if (args.Length > 0)
            {
                ;
            }
            else
            {
                ;
            }
            try
            {
                ;
            }
            catch
            {
                ;
            }
            finally
            {
                ;
            }
        }
    }
}

言語の既定に従うのも悪くは無いとは思う。思うのだが、 Java, JavaScript, Go, Rust 等々、他のメジャーな C言語 スタイルの言語では、 Java のコーディング規約に則って改行を入れないの(K&Rスタイル)が一般的なので、 C# で改行を入れるこのコードスタイルはどうにも気持ちが悪い(主張の強い個人の感想です)

手癖で改行を入れない書き方をしていても、 Shift+Alt+F でドキュメントのフォーマットをすると改行されてしまう。

…と言うことで、 Visual Studio Code (VSCode) を使って C# の開発する際に、各種ブロックの {} (中括弧・波括弧) の手前に改行が入らない形でフォーマットする方法を紹介する。

omnisharp.json は機能しない

vscode でこの設定を変更する場合、古くは omnisharp.json が使われていた。

ところが、 2023年中頃の VSCode の C# 拡張機能の更新 (v2.0.320) で、既定で Roslyn と Razor をベースとした新しい言語サーバーを利用するようになったため、 OmniSharp が使われなくなった。
このため、明示的に OmniSharp を有効 にしない限り、 omnisharp.json に書かれた設定は機能しなくなっている。

.editorconfig を使おう

続きを読む

後ほどミュートを解除しておく PowerShell スクリプト

本記事は シェルスクリプト&PowerShell Advent Calendar 2023 の1日目の記事だ。
如何にハードルを下げるかを考え、しょーもない内容となることを意識している…と言い訳しておこう。

何故ミュートを解除したいのか

さて、一時的に PC をミュートにしておきたい事がある。

コロナ禍を経て、 Cisco や Polycom といったテレビ会議システムに替わって、 Zoom などのWeb会議ソフトが普及した。
しかし、近年出社を強要されるのが一般化してくると、結局以前のように会議室に集まって、離れた拠点の相手とビデオ会議を行うことになる。
このとき、全員各々のPCでビデオ会議には参加するものの、音声は卓上マイク&スピーカー使う事があり、ハウリングを避ける為に卓上マイクを使う人以外はスピーカー・マイクをミュートにするだろう。

ところが、会議終了後ミュートしっぱなしにしてしまい、通知等に気づきにくくなることがあるので、一定時間後にミュートを簡単に解除できるようにしておきたい。

それだけのために、スクリプト経由で MMDevice API 呼ぶのも仰々しいなぁと思っていた所、よく考えたらキーボードにあるミュート状態をトグルキーを仮想的に押せばいいじゃないかと気づいた。

ということで、早速 PowerShell でキーボードのマルチメディアキーを押すスクリプトを書いてみる。

早速コード例

続きを読む

Pester v3 & v5 互換のテストコードを書く (PowerShell)

PowerShell のテストフレームワークである Pester は、単体テストや自動テストなどを手軽に書けるので、スクリプトやコードの品質を保つのに役立つ。

しかし、 Pester は v3 から v5 にかけてかなり大きな破壊的変更がある。

この記事では、 Pester v3 と v5 の両方に互換があるテストコードの書き方について紹介したい。

何故 v3 と v5 で互換を取りたいか

Windows 10 や 11 では、デフォルトで Windows PowerShell 5.1 がインストールされており、更にそこには Pester モジュールの v3.4.0 もインストールされている。
Windows 上の PowerShell モジュールディレクトリはシステム全体で共通のため、たとえ別途 PowerShell 7.3 LTS などをインストールしていたとしても、既定では Pester v3.4.0 が読み込まれるわけだ。

一方、 Linux 等のそれ以外のシステムで PowerShell をインストールした場合は、 Pester が自動的にインストールされることはないため、 Pester モジュールを追加でインストールすることになる。
このとき、普通は最新版の v5 が入るだろう。

Windows PowerShell の Pester を v5 に更新させたり、 Linux 等のシステムでインストールする Pester モジュールを v3.4 に抑えさせたりできればよいが、まぁなかなかそうも行かない時がある。

そんなのっぴきならん状況だと、多少苦労してでもテストコード側を Pester v3 と v5 どちらにも互換を取ってしまったほうが手っ取り早いかも…なんて状況が地球上の何処かには存在するかもしれない。

テストコードの書き方

v3 と v4 の間の破壊的変更で一番デカいのは、 Should 構文の変更で互換切りを行っている部分だ。

続きを読む

ミドルGPUで35億の女(RINNA AI)のローカル実行 ことはじめ

RINNA社が 5月17日 に、 rinna/japanese-gpt-neox-3.6b-instruction-sft という、対話言語 AI モデルを公開したと、プレスリリースを出した。
その後さらに 5月31日、人間の評価による強化学習したモデル rinna/japanese-gpt-neox-3.6b-instruction-ppo を追加リリースしている。

この AI モデルは、ご家庭にあるミドルレンジ GPU でもサクサク動く性能だったので、 AI 系に明るくない人にも導入できるように、詳しい導入手順を紹介しようと思う。

こう言うのって、登場して直ぐ情報がホットなうちに記事にすることに価値があって、こんな 1~2週間経ってから記事を書いたって誰にも届かないんだろうけど、とりあえず書いてみる。

この界隈の情報はコンテクストが高いというか、あんまりイチから導入方法を説明している記事って目にしないので、多少は需要があるかなと。

はじめに断っておくが、 Chat-GPT や 新しいBing 等と比べると数段落ちる回答精度となる。
ただ、個人がお手軽に購入できる程度の GPU を使って、完全にローカルで動かす事ができるという点が、一種の浪漫だ。

前提条件

以下のスペックを持った PC。

  • OS は Windows 10 または Windows 11
  • GeForce RTX 3060 以上、 VRAM 12GB 以上が載った NVIDIA の GPU
    • GPU ドライバはインストール済み
    • 具体的には 2023年5月現在 以下のいずれかモデル
      • GeForce RTX 3060 (12 GB)
      • GeForce RTX 3080 (12 GB)
      • GeForce RTX 3090
      • GeForce RTX 3090 Ti
      • GeForce RTX 4060 Ti (16 GB)
      • GeForce RTX 4070
      • GeForce RTX 4070 Ti
      • GeForce RTX 4080
      • GeForce RTX 4090
    • 3070 Ti, 3060 Ti, 3060 (8GB) だと VRAM が足りないので、多分動かすとエラーになる

導入手順

続きを読む

YAML の細かい仕様の話

YAML の細かい仕様の話

趣味アカウントのほうでバズった… ってほどでは無いけど、割と反響があったので、 YAML に関する話をいくつか。

YAML 1.2 では Boolean として扱うのは true, false だけ

https://yaml.org/type/bool.html

続きを読む

PowerShell で中身がランダムな大きめのファイルを高速に作る

色々テストをしていると、ユニークなランダムの中身で、任意サイズの、ダミーファイルが欲しくなることがままある。

デバイスを全てファイルとして扱う Unix や Linux なら、 /dev/urandom 擬似デバイスを使って dd if=/dev/urandom of=out.bin bs=1M count=64 みたいに任意サイズでファイルをコピーして作れば良い。

しかし API ベースの Windows だとそういうわけにいかないので、何らかのスクリプトから API を呼んでやる必要がある。

呼ばせるスクリプトは、 Windows に標準で搭載されていて追加でインストール不要な、毎度おなじみ PowerShell が良いだろう。
作りたいランダムなファイルのサイズが小さければ、 PowerShell 上で以下のような雑なコードを実行すればよい。

$Size = 16KB;
[byte[]]$bin = &{foreach($i in 1..$Size) { Get-Random -Maximum 255 }};
[System.IO.File]::WriteAllBytes((Join-Path (Get-Location) .\out.bin), $bin);

しかし、 MiB オーダーを越えてくると、上記のコードでは速度が実用的ではなくなる。

と言うことで、出力速度も気にしながら、大きめなランダムなファイルを作成するコードを考えてみる。

コード

続きを読む

Docker run の起動時に任意コードを実行後 bash や ash を終了しない

この記事は、 Docker Advent Calendar 2022 の 23日目の記事だ。

空いていたので埋めちゃうよ。

この記事では、 bash や ash で任意のコードの実行後、ターミナルを終了せずに入力待ちにする方法について紹介する。
特に、 docker run の実行後に、その環境を維持したまま入力待ちにすることを考える。

例えば、 Windows コマンドプロンプトや PowerShell であれば、 CMD /K *** オプションや、 -NoExit -Command *** オプションで実現できるような内容だ。

本来なら、 docker build にてその任意コードの実行後の内容をイメージにするべきだが、 わざわざ build するまでもないとか、 build できない事情などもあるかもしれない。

ということで、 bash の場合と、 alpine などで使われる BusyBox ash それぞれについて、 docker run 実行時に任意コード実行後、ターミナルの入力待ちにする方法を紹介する。

bash の場合

bash の場合、 --rcfile オプションにて、起動時に実行するコマンドを指定できる。

ただし、 --rcfile はファイルを指定する必要があるため、 替わりにプロセス置換で実行コードを与えてやる方法をとる。

user@hostmachine:~$ docker run --rm -it debian:bullseye bash -c "bash --rcfile <(echo 'ls && export '\''FOO=B A R'\'' && MY_TIME=\$(date)')"
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr
root@container:/# echo $FOO : $MY_TIME
B A R : Thu Dec 22 15:00:00 UTC 2022
root@container:/# 

プロセス置換はコンテナ内で実行される必要があるため、一旦 bash -c にてコンテナ内で bash 実行させ、その中で改めて --rcfile オプションを指定した bash を起動する流れとなる。

実際に実行したいコマンドは、 echo で文字列として書き出す。
上記例では、 ls && export 'FOO=B A R' && MY_TIME=$(date) と言う文字列を echo させている。

引用符が二重三重になっていて、エスケープが非常に難しくなっているので注意。

BusyBox ash

alpine 3.15 以降に含まれる BusyBox の ash であれば、意外にもプロセス置換が使える。

しかし、 --rcfile に相当するオプションは残念ながら無い。
替わりに、 ash には ENV という環境変数に記載されたファイルを ash 起動時に実行する機能がある。

これを使おう。

user@hostmachine:~$ docker run --rm -it alpine:3.15 ash -c "ash -c 'export ENV=\$1;ash' -s <(echo 'ls && export '\''FOO=B A R'\'' && MY_TIME=\$(date)')"
bin    etc    lib    mnt    proc   run    srv    tmp    var
dev    home   media  opt    root   sbin   sys    usr
/ # echo $FOO : $MY_TIME
B A R : Thu Dec 22 15:00:00 UTC 2022
/ # 

ash-c のコマンドに対して引数を与える -s オプションを使ってプロセス置換のファイルを与え、 それを $1 経由で ENV 環境変数にセット。 その状態で再度 ash を起動させれば、 bash と同様のことが行える。

ENV 環境変数に直接プロセス置換のファイルを指定せず、わざわざ一旦引数を経由させているのは、 入力を受け付ける ash プロセスが動いている間、 プロセス置換のファイルにアクセス可能にする必要があるためだ。
例えば、 export ENV=<(echo 'command');ash と実行しても、 ash 実行の段階ではプロセス置換のファイルが閉じられているので、コマンドは実行されない。

もうちょっと複雑で実用的な例

エスケープが何重にもなっていてややこしいが、書き方さえ気をつければ基本的にどんな内容でも実行可能だ。

apt パッケージマネージャーのリポジトリを書き換えた状態で、 bash を起動する方法 (Ubuntu):

docker run --rm -it ubuntu:22.04 bash -c "bash --rcfile <(echo 'sed -i -E '\''s%^(deb(-src|)\s+)https?://(archive|security)\.ubuntu\.com/ubuntu/%\1http://srv2.ftp.ne.jp/Linux/packages/ubuntu/archive/%'\'' /etc/apt/sources.list && apt update && FooBar=`date -uIs`')"

apk パッケージマネージャーのリポジトリを書き換えた状態で、 ash を起動する方法 (Alpine):

docker run --rm -it alpine:3.15 ash -c "ash -c 'export ENV=\$1;ash' -s <(echo 'sed -i -E '\''s%^https?://dl-cdn\.alpinelinux\.org/alpine/%https://ftp.udx.icscoe.jp/Linux/alpine/%'\'' /etc/apk/repositories && apk update && FooBar=`date -uIs`')"

参考: https://stackoverflow.com/questions/74094552/how-not-to-terminate-after-carried-out-commands-in-bash

GNS3 に VyOS 仮想ルーターを追加する長い道のり③ 実践編

本記事は 【アットホームな現場です】🎄★☆ネットワーク系エンジニア★☆アレコレアウトプット★☆🎄 Advent Calendar 2022 17日目の記事だ。

GNS3 という OSS のネットワークエミュレータを、 Cisco の IOS などの取得なしに、無料のライセンス内で利用できるようにしようという話。

環境導入編、イメージ準備編に続く実践編。
以前の投稿はこちら。


実際に、 GNS3 上で VyOS を使ってみよう。

GNS3 プロジェクトを作成

GNS3 を開き、適当なプロジェクトを新規作成(ないし開く)する。

平行して、 GNN3 VM が起動するまで待とう。

VyOS の起動

GNS3 GUI 上で、テンプレート一覧から VyOS のデバイスをドラッグ&ドロップして、プロジェクトに追加する。

続きを読む

プロキシ環境下で Docker Desktop から Rancher Desktop への移行する

この記事は、 Docker Advent Calendar 2022 の 22日目の記事だ。

Windows 上や mac OS 上で、手軽に Docker や Kubernetes の環境を構築するための、 Docker Desktop というツールが存在する。

この Docker Desktop は、 2021年8月31日以降、営利企業での利用は基本的に有料サブスクリプションが必須 となった。
更に、 2022年10月27日以降、 Docker Team プランにて 100人のユーザー数上限が設けられ 、それ以上の場合は Docker Business プランの契約が必要となっている。

まぁ、営利企業ならそれぐらい払えよって話なんだが、のっぴきならん理由でなかなかそうもいかない諸兄も少なくないだろう。

正直、 Business プランで Docker Desktop 以外の機能を全く使わない(ないし使えない)場合、 $21/user/month はだいぶ高い。

ということで、代替?になるかわからんが、主に Windows での実行をスコープに、 同一コンセプトの Rancher Desktop への移行を紹介してみよう。


Rancher Desktop について

Rancher Desktop は、 Docker Desktop と同様 PC の仮想環境上にコンテナデーモンを起動させ、 デスクトップから手軽に Docker CLI (with Moby/dockerd) や nerdctl (with containerd) を利用できるようにするツールだ。

かつての SUSE Linux の開発元、 現在の openSUSE プロジェクトの主要スポンサーとなっている SUSE 社 が開発している、 Rancher ソリューションの一環として、 オープンソースで開発されているプロジェクトである。

WSL2 上に dockerd や containerd デーモンを立ち上げ、 他の WSL2 ディストリビューションや ホストOS から Docker CLI や nerdctl が使えるようになっている。

Windows の Docker CLI からも、 WSL 内の Docker CLI からも、 Docker outside of Docker (DooD) が問題なくできるなど、基本的な機能はしっかりしている。

Docker Desktop と比較すると、以下のような利点がある。

  • 無料で利用できる
  • nerdctl にも対応している
  • Kubernetes のバージョンが選べる
  • VPN 環境下でも問題が発生しにくい

一方で、使っているといくつかの問題が目につく。 (1.9.0 現在)

  • プロキシ環境下で イメージの pull させる公式手順がない
  • WSL 内からの CLI の実行にいくつか難がある
    • docker CLI の実行が、 2~3 テンポ遅い
    • docker run--interactive ( -i ) オプションを付けないと、標準出力がホスト側に表示されない

また、問題とまでは言わないまでも、いくつか注意点もある。

  • 付属の docker-compose が、 docker compose コマンドと同等の Compose V2 である
  • Hyper-V の仮想化に依存するため、 VPN 環境下と相性が悪い
    • ネットワークスタックの構造の変更で解消し、むしろ利点となった。

Docker Desktop から Rancher Desktop への移行

Windows 版に於ける、 Docker Desktop から Rancher Desktop への移行手順をまとめておく。

1. Docker Desktop を削除

続きを読む

bash で標準出力と標準エラーを 2つのコマンドに出し分ける

本記事は シェルスクリプトのカレンダー | Advent Calendar 2021 - Qiita 17日目の記事だ。

殆どカレンダーが埋まってなかったので、思いついたネタで埋めちゃえ埋めちゃえ。

今回は、 bash 系列 (bash, zsh 等) の プロセス置換 (process substitution) 機能の話だ。

このプロセス置換は POSIX 互換の機能では無いため、以降の例は ash 系列 (busybox hush (ash), dash 等) では利用できない。

bash のプロセス置換

続きを読む