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

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

続きを読む

次の○曜日 や 来週の○曜日 を取得する JavaScript

JavaScript の標準組込みオブジェクトは、日時関連の処理が非常に貧弱だ。

次の水曜日は何月何日? とか、 来週の月曜日は何月何日? といった値を取得しようと思ったら、タイムゾーン周りの処理と合わさって、思いのほか面倒だった。

とりあえず、動くコードができたので、記事にして紹介する。

続きを読む

puppeteer でファイルをダウンロードするときに、任意のパスと名前を指定して保存する

Puppeteer を使ってファイルをダウンロードする際に、任意のパスと名前で保存したい。

残念ながら、 現時点ではシンプルな方法は提供されていないようだ。
以下の Issue で何年にもわたって議論されているものの、 「コレ!」 という解決方法は無さそう。
Question: How do I get puppeteer to download a file? · Issue #299 · puppeteer/puppeteer

しかし、 この Issue の #issuecomment-668087154 のコメントで、 なかなか泥臭い方法で実現するヒントが書かれていた。
これを参考にして、任意のパスと名前でダウンロードファイルを保存してみよう。

実行方法

あらかじめ、 puppeteer の npm パッケージをローカルにインストールしておく。

npm install puppeteer --save

その状態で、後述の .js ファイルを nodejs で実行すれば OK だ。

node puppeteer-download-with-specify-name.js

コードと解説

続きを読む

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 リリースではあるのだけれど。

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がインストールされているすべてのアプリケーションを再検証するので、負荷がかかるし遅い

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

.NET Interactive で C# と PowerShell を股に掛ける

この記事は、「C# Advent Calendar 2020」 9日目の記事、かつ 「PowerShell Advent Calendar 2020」 9日目の記事だ。

スミマセン。横着した。

この時期になれば .NET Interactive の Preview 4 が出てるだろうしその記事でも書こうかな~ などと目論んでいたものの、 残念ながら登場しなかった。

このため、 .NET Interactive .NET 5 対応版の導入と、 Variable sharing の内容でお茶を濁そうと思う。

.NET Interactive のなんたるかについては、以前の以下の記事で取り扱っているので、そちらを参照願いたい。

.NET Interactive を .NET 5 で動かしてみる

いきなり本題とは関係ない話になるが、 せっかく .NET 5 がリリースされたところなので、 .NET Interactive を .NET 5 で動かしてみよう。

続きを読む