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

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

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

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

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

bash のプロセス置換

続きを読む

置換ができない/複数ある場合に sed の終了コード0以外にする

本記事は、 シェルスクリプト Advent Calendar 2021 の 4日目 の記事だ。
そして、 且つ docker Advent Calendar 2021 4日目 の記事でもある。

どちらのカレンダーもまだまだスッカスカなので、禁じ手で埋めにかかってしまった。


Docker 公式イメージ などをベースにして、カスタムしてイメージをビルドして使おうとした際、 なるべくなら /etc/apt/apt.conf.d/ 等のように、設定用のファイルを追加して、ツール側がいい感じにマージして利用してくれるのが望ましい。
しかし、 場合によってはやむを得ず、既存のファイルを sed コマンドなどで編集せざるを得ないこともあるだろう。

カスタムイメージの Dockerfile をビルドする際に、当初は意図通り書き換えられていても、イメージが更新された結果、イメージのリビルド時にファイルの書き換えが意図しない結果となってしまう場合がある。 1

通常、 sed コマンドは、置換が発生してもしなくても、 終了コード 0 で終了する。
このため、書き換えの成否にかかわらず、 docker build 時にエラーにならないため、コンテナ実行時に初めて置換が意図しない結果だったことに気づくことがある。

そこで、sed コマンドの書き換えで適切なパターンが見つからなかった場合に 0以外の終了コードを返し、ビルド時にエラーとする方法を考える。

続きを読む

sed の ブロック {} 内で i, r, e コマンドを使うと “unmatched `{‘” とエラーになる

本記事は、 シェルスクリプト Advent Calendar 2021 の 3日目 の記事だ。
3日目が終わりそうになっても誰も書きそうにないので、最近 sed コマンドで ブロック {} を使っていたら、 "unmatched `{" というエラーにハマったので、そのメモ。


target.txt:

foo
bar
foo
bar
foo

insert.txt:

***

上記のような、2つのファイルがあったとする。

target.txt ファイルに対して、 正規表現アドレスbar から始まる行を選択し、 その後ろに r コマンド insert.txt のファイルの中身を挿入する。

するとこんな結果になる。

$ sed -e '/^bar/rinsert.txt' target.txt
foo
bar
***
foo
bar
***
foo

では、アドレス指定の後ろにブロック {} を追加し、以下のように bar が2回以上ヒットしたらエラーコード出して終了するようにしてみる。

$ sed -e '/^bar/{rinsert.txt;x;/./Q129;g}' target.txt
sed: -e expression #1, char 0: unmatched `{'
$ echo $?
1

はい、別のエラーで失敗した。
ちゃんと {} の数はマッチしているのに……

続きを読む

Samba が動く Docker Desktop のコンテナで、ボリューム内のファイルを見る

本記事は、 docker Advent Calendar 2021 2日目 の記事だ。
昨日は、 @subretu氏 の DockerfileにおけるCMDとRUNの挙動 だった。


docker のコンテナやボリュームの中身を見る際に、 ホスト PC から SMB ファイル共有で参照できると都合が良い。

と言うことで以前、以下のような記事を作成したが、 Docker Desktop では利用できない問題があった。

今回は、それを解消する手段について紹介したい。

先に断っておくが、私自身でいくつかの PC で試したところ、上手くいく PC とダメな PC がハッキリと分かれてしまい、現時点ではどのような条件だとダメなのかハッキリわかっていない。

続きを読む

Vagrant で Temporary failure resolving となる問題の解決 – イントラネット DNS 編

Vagrant で Ubuntu の VM を立ち上げたとき、 apt 等を行おうとすると、以下のようなエラーに遭遇した。

client: Err:1 http://security.ubuntu.com/ubuntu focal-updates/main amd64 libjpeg-turbo8 amd64 2.0.3-0ubuntu1.20.04.1
client:   Temporary failure resolving 'proxy.local.example'

上記のエラーの内容はプロキシに接続できないというものだが、 問題のポイントはプロキシかどうかはあまり関係が無く、 名前解決に失敗しているという部分だ。
こういうのはだいたい systemd-resolved のスタブリゾルバ周りの問題だと相場が決まっている。

…ということで、順番に確認しながら問題を解決していこう。

なお、 使った box は generic/ubuntu2004 で、 VirtualBox で VM をホストしている。

スタブリゾルバの確認

まず、 resolv.conf を確認してみる。

続きを読む

超簡単に大量の nanaco ギフトを自動登録するツール GUI 版

突然だが、自動車税や固定資産税などの税金や、公共料金などの払込票などを、どのように支払っているだろうか?
支払う額も大きくなりがちなので、なるべくお得に支払いたいのではないだろうか。

そこでオススメなのが nanaco ギフト だ。

(以下略)

この記事は、以前紹介した以下のツールの GUI 版を紹介するものだ。
nanaco ギフトのなんたるかは、以下のページをご参照をば。

端的に言うと、以下の通り:
税金や公共料金などに使える nanaco の残高を、 「ベネフィットワン」や「ちょコムショップ」などでお得に購入できる nanaco ギフトだが、 1,000 円単位で提供されることが多い。
大きな額の支払いだと、例えば 10万円 なら 100回 面倒なチャージ作業を繰り返す必要があり、その手間がお得分に見合わなくなる。
このため、 nanaco ギフトの登録を自動化してしまおうという話だ。

前回は、 PowerShell 版を作成して個人的にはこれで完全に事足りていたのだけれど、 ブログの記事にして公開したら、どうやら敷居が高かったらしく 「素人には難しい」とか「Excel で公開して」とかメールやらコメントやらを、いくつもいただいた。
確かに、昨年私が PowerShell 版の記事を出した頃、同じような時期に同じ目的の記事がいろんなブログで書かれるようになった気がするが、どれもこれも、いわゆる「プログラマ」なら簡単に使えるものの、それ以外の人には厳しそうなものばかりだった。

そこで、 専門的な知識がなくても使える、 みんなに易しい GUI (グラフィカルユーザーインターフェイス) で動くツールとして作り直してみたのが、今回のお話。

当初は、 PowerShell版 を流用して簡単に作れるかな~ とか目論んでいたのだけれど、色々うまくいかず、 結局イチから作り直している。

booth で販売中

続きを読む

.NET Interactive が vscode で使えるようになった

以前、.NET Interactive の C# REPL を Jupyter で などで紹介していた、 .NET Interactive が、 Visual Studio Code (VS Code) の Stable 版で使えるようになっていた。

まぁ、昨年 9月 の .NET Interactive Preview 3: VS Code Insiders and .NET Polyglot Notebooks | .NET Blog の時点で、 VS Code の Insiders ビルドでは使えていたのだが、 最近晴れて Stable 版の VS Code でも動作するようになったようだ。
……まぁ、 .NET Interactive Notebooks 拡張機能自体は、まだ Preview リリースではあるのだけれど。

Android版 Firefox (Fenix) で、任意のアドオンを使えるようにする

この記事では、 Android 版 Firefox Nightly に対して、 TampermonkeyGreasemonkey などの人気のアドオン(拡張機能)を動作させる手順を紹介する。

Firefox とアドオン

Mozilla Firefox (以下 Firefox) といえば、アドオン(拡張機能)と共にあったと言っても過言ではないだろう。

デスクトップ版 Firefox で、処理速度を大幅に向上させた Firefox Quantum の登場とともに、 それまでに使えていたブラウザのアドオンの多くが使えなくなった。
そのために、ただでさえ下降気味だったシェアの低下が更に加速した (筆者調べ) のも、記憶に新しい。

そして 2020年8月、 動作がかなり重かった 旧来 の Firefox for Android (~ v68.11 コードネームFennec) を、 これまた処理速度を大幅に向上させた GeckoView 版 Firefox for Mobile (v79~ コードネーム Fenix) に更新した際にも、 Mozilla は歴史を繰り返した。
それまで使えていた多くのアドオンが Firefox Fenix では使用できなくなり、 Mozilla が認めたごくごく一握りのアドオンしかインストールできなくなってしまったのだ。

誤解して欲しくはないが、 Chrome 等と比べても UI が洗練されていて 動作が軽快な Firefox Fenix を、私はとても気に入っている。
それでもやはり、どうしてもアドオンを使いたいときがあるのだ。

どうやら、 Firefox Fenix に関しては、 技術的に旧来のアドオンが全く動かなくなった訳ではなく、 ポリシー上制限しているだけのようだ。何故そうしているのかわからないけど。

そのためか、 Firefox の実験的なビルドを提供する開発チャンネルである Firefox Nightly に対して、 任意のアドオンをインストールする手段が用意されている。

先に断っておくが、 Nightly 版を常用することはオススメしない
不安定だし、予期しない問題が発生する確率が高いからだ。

それでも、 Stable チャンネルの Firefox Fenix にはインストールできないけど、どうしても動かしてみたい拡張機能がある場合は、有力な選択肢となるだろう。

Firefox に任意のアドオンをインストールする手順

続きを読む

PowerShell でインストール済プログラム一覧を取得する

PowerShell を Windows の管理ツールとしてみたときに、割と昔から意味がわからないと思っていることが 1点 ある。
Windows のインストール済みプログラム一覧を取得するコマンドがないことだ。

もう少し具体的に言うと、appwiz.cpl で開ける、コントロールパネルのプログラムと機能の一覧や、 設定の「アプリと機能」の一覧を取得するコマンドレットがない。
コマンドレットがないだけじゃなく、コードを書いて取得する確立して手段すら存在しないのだ。

とりあえず、それに近い情報がとれる代替方法として、レジストリのアンインストーラー一覧を取得する方法が知られている。
ただ、ググってもあまり PowerShell らしい綺麗 (?) なコードで書かれているサンプルが少なかったので、ワンライナーで書いてみる。

Get-ChildItem -LiteralPath (('HKLM:', 'HKCU:' | %{ "${_}\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" }) + 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall') | Get-ItemProperty -Name DisplayName, DisplayVersion, Publisher, InstallDate -ErrorAction Ignore;

これで取得した内容を | Sort-Object DisplayName, DisplayVersion| Select-Object DisplayName, DisplayVersion などにパイプしてから使うと良いだろう。


ちなみに WMI の Win32_Product クラスを使って取得する方法 (Get-CimInstance -ClassName Win32_Product) は、

  • MSI でインストールしたアプリしか取得できない
  • コンピューターはMSIがインストールされているすべてのアプリケーションを再検証するので、負荷がかかるし遅い

と言うことから使うべきではないとされている。

VPN に繋ぐと WSL2 や Hyper-V VM でネットワークに繋がらなくなる問題を解消する

OpenVPN や Cisco AnyConnect, GlobalProtect 等といった VPN に接続した際、 Hyper-V 仮想マシン内からや、 WSL2 のディストリビューション内、 Windows Sandbox 内、 WSL2 ベースの Docker コンテナ内 等々、 Hyper-V 系の技術を使った仮想環境から、 PC 外のネットワークにアクセスしようとすると、 以下のようなエラーが発生して失敗する。

$ # curl 利用時の例
curl: (6) Could not resolve host: example.com
curl: (5) Could not resolve proxy: proxy.example.com

$ # apt で更新しようとした場合の例
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/focal/InRelease  Temporary failure resolving 'archive.ubuntu.com'
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/focal/InRelease  Temporary failure resolving 'proxy.example.com'

エラーの内容からわかるとおり、アクセス先やプロキシーのドメイン名を DNS で解決できなくなっている。

このような問題が発生することは以前から知っていたのだが、このご時世で VPN 使うことが増えてきて、いい加減鬱陶しくなってきたので、なんとかしようと思う。

解決方法

とりあえず、まずは解決方法から。

続きを読む