golang でシグナルを扱う

golang でシグナルを扱う

  • Go でシグナルを扱うには singal.Notify を使う
  • 以下のサンプルコードでは SIGINT = ^C を受信するとアプリケーションが停止する
  • sigC := make(chan os.Signal, 1) のように必ずバッファありチャネルが必要
  • os.Interrupt と os.Kill の2つはすべての OS で使えることが保証されている
package main

import (
    "log"
    "os"
    "os/signal"
    "sync"
    "time"
)

func main() {
    // 受信するシグナル
    // Interrupt Signal = syscall.SIGINT
    sigs := []os.Signal{os.Interrupt}

    // 必ずバッファありチャネルが必要
    // https://budougumi0617.github.io/2020/09/06/why_signal_notify_want_buffered_channel/
    sigC := make(chan os.Signal, 1)
    signal.Notify(sigC, sigs...)

    var wg sync.WaitGroup

    wg.Add(1)
    go func() {
        defer wg.Done()
        for {
            select {
            case <-time.After(2 * time.Second):
                log.Println("waiting...")
            case sig := <-sigC:
                log.Println("got signal", sig)
                return
            }
        }
    }()

    wg.Wait()
}

参考サイト

sed で置換する

実行例

  • 名前が チ で終わる犬に忠犬をつける
$ cat sample.xml 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <dog name="ソフィア" age="7" />
    <dog name="ポチ" age="5" />
    <dog name="コロ" age="10" />
    <dog name="ハチ" age="5" />
</root>
$ sed -i -E 's/([ア-ン]+チ)/忠犬\1/g' sample.xml
$ cat sample.xml 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <dog name="ソフィア" age="7" />
    <dog name="忠犬ポチ" age="5" />
    <dog name="コロ" age="10" />
    <dog name="忠犬ハチ" age="5" />
</root>

コマンド説明

  • sed -i -E 's/([ア-ン]+チ)/忠犬\1/g' sample.xml
    • -i で置換した結果を元ファイルに上書きする
    • -E 拡張正規表現を使用する
    • 後方参照は \番号 で行う。キャプチャには () を使用する

XPath で指定したノード名でない、ノードを取得する

XPath で指定したノード名でない、ノードを取得する

サンプルXML

<root>
    <animals>
        <dog>sophia</dog>
        <dog>koro</dog>
        <panda>xiangxiang</panda>
    </animals>
</root>

ノード名が panda でない animals の子ノードを取得する

  • /root/animals/*[not(self::panda)]
<dog>sophia</dog>
<dog>koro</dog>

参考

Ubuntu から VPN 経由で Windows へ接続したときのメモ

Ubuntu から VPN 経由で Windows へ接続したときのメモ

接続環境

UbuntuVPN クライアントをインストールする

  • L2TP/IPsec できるようにするため
  • sudo apt install network-manager-l2tp network-manager-l2tp-gnome

VPN を設定する

  • 設定 > ネットワーク > VPN から Layer 2 Tunneling Protocol(L2TP) を選択して作成する

Identify タブ

  • ゲートウェイ: VPN サーバーの IP アドレス
  • NT ドメイン: 空欄
  • IPsec Settings...
    • Enable IPsec tunnel to L2TP host: オン
    • Gateway ID: 空欄
    • Pre-shared key: 事前共有鍵を入力
    • Phase1 Algorithms: aes128-sha1-modp1536,aes128-sha1-modp1024,3des-sha1-modp1024
    • Phase2 Algorithms: aes128-sha1,aes128-sha1,3des-sha1
    • Enforce UDP encapsulation: オフ
  • PPP Settings...
    • 次の認証方式を許可します。: MSCHAP, MSCHAPv2
    • MPPE暗号を使用する: オン

IPv4 タブ

  • この接続はネットワーク上のリソースのためだけに使用: オン
    • オンにしておかないと、すべての通信が VPN 経由になる
  • DNS 自動: オフ
    • オンだと VPN 切断後に DNS がうまく動作しなかった

VPN ネットワークへの経路を設定する

  • /etc/ppp/ip-up.dスクリプトを書いておく
  • 本当は PPP_IFACE で ppp インターフェースを区別したほうがいい
$ cat /etc/ppp/ip-up.d/ppp0
#!/bin/bash

# 以下は設定例  
sudo route add -net 192.168.100.0/24 ppp0

Remmina から RDP で Windows へ接続する

  • 必要に応じて、共有フォルダや色数を設定する

参考にさせてもらったサイト