Excel VBA で休日祝日判定(再掲)

Excel VBA で祝日判定(再掲)

再掲

ずいぶん前に記載していた、専用シートを使わない Excel VBA での祝日判定。
Excel で休日祝日判定 - KuroNeko666’s blog

2020年は、いろいろ特殊っぽいのがいまさらわかったので、改造ついでに再掲します。

つぎのソースをコピペして使ってください。

ソース

Option Explicit

Public Function chkHoliday(Serial, Optional RVFlag As Byte = 0)
' #########################################################################
' # 呼び出されると、引数のSerialから休日/祝日判定フラグを返すマクロ
' #########################################################################

' 戻り値の定義
' 0 = 平日
' 1 = 日曜日(vbSunday)
' 7 = 土曜日(vbSaturday)
' 8 = 祝日

' 変数の宣言
Dim RV As Byte
Dim DayName As String
Dim YYYY As Integer
Dim fSubstitute As Boolean ' 振替休日フラグ

' ### メイン ##############################################################

DayName = "平日"
YYYY = Year(Serial)

' ## 祝日判定 #####
'元日 1月1日
'成人の日 1月の第2月曜日
'建国記念の日 政令で定める日(2/11)
'春分の日 春分の日
'昭和の日 4月29日
'憲法記念日 5月3日
'みどりの日 5月4日
'こどもの日 5月5日
'海の日 7月の第3月曜日
'山の日 8月11日
'敬老の日 9月の第3月曜日
'秋分の日 秋分の日
'体育の日 10月の第2月曜日 (2020年からスポーツの日に名称変更)
'文化の日 11月3日
'勤労感謝の日 11月23日
'天皇誕生日 12月23日 → 2月23日(2019年 天皇の即位に伴う変更)
'国民の休日 祝日に挟まれた平日
'天皇の即位の日及び即位礼正殿の儀の行われる日を休日とする法律 2019年5月1日と2019年10月22日


' 規定の日付
Select Case Serial
  Case DateValue(YYYY & "/1/1")
    DayName = "元旦"
  Case DateValue(YYYY & "/1/2")
    DayName = "年始"
  Case DateValue(YYYY & "/1/3")
    DayName = "年始"
  Case NumWeek(YYYY, 1, 2)
    DayName = "成人の日"
  Case DateValue(YYYY & "/2/11")
    DayName = "建国記念の日"
  Case DateValue(YYYY & "/2/23")
    If 2019 < YYYY Then
      DayName = "天皇誕生日"
    End If
  Case DateValue(YYYY & "/3/" & Int(20.8431 + 0.242194 * (YYYY - 1980) - Int((YYYY - 1980) / 4)))
    ' 参考URL http://www.wanichan.com/pc/excel/2010/5/page07.html
    DayName = "春分の日"
  Case DateValue(YYYY & "/4/29")
    DayName = "昭和の日"
  Case DateValue("2019/4/30")
    DayName = "国民の休日"
  Case DateValue("2019/5/1")
    DayName = "天皇の即位の日"
  Case DateValue("2019/5/2")
    DayName = "国民の休日"
  Case DateValue(YYYY & "/5/3")
    DayName = "憲法記念日"
  Case DateValue(YYYY & "/5/4")
    DayName = "みどりの日"
  Case DateValue(YYYY & "/5/5")
    DayName = "こどもの日"
  Case NumWeek(YYYY, 7, 3)
    DayName = "海の日"
  Case DateValue(YYYY & "/8/11")
    DayName = "山の日"
  Case NumWeek(YYYY, 9, 3)
    DayName = "敬老の日"
  Case NumWeek(YYYY, 9, 3) + 1
    If DateValue(YYYY & "/9/" & Int(23.2488 + 0.242194 * (YYYY - 1980) - Int((YYYY - 1980) / 4))) = NumWeek(YYYY, 9, 3) + 2 Then
      DayName = "国民の休日"
    End If
  Case DateValue(YYYY & "/9/" & Int(23.2488 + 0.242194 * (YYYY - 1980) - Int((YYYY - 1980) / 4)))
    ' 参考URL http://www.wanichan.com/pc/excel/2010/5/page07.html
    DayName = "秋分の日"
  Case NumWeek(YYYY, 10, 2)
    If YYYY <= 2019 Then
      DayName = "体育の日"
    Else
      DayName = "スポーツの日"
    End If
  Case DateValue("2019/10/22")
    DayName = "即位礼正殿の儀の行われる日"
  Case DateValue(YYYY & "/11/3")
    DayName = "文化の日"
  Case DateValue(YYYY & "/11/23")
    DayName = "勤労感謝の日"
  Case DateValue(YYYY & "/12/23")
    If YYYY < 2019 Then
      DayName = "天皇誕生日"
    End If
  Case DateValue(YYYY & "/12/31")
    DayName = "年末"
End Select

' 振替休日
' 「国民の祝日」が日曜日に当たるときは、その日後においてその日に最も近い「国民の祝日」でない日を休日とする
' なので「国民の祝日」の翌日が月曜日だったときも、振替休日となる
Select Case Serial
  Case DateValue(YYYY & "/1/1") + 1
    If Weekday(Serial) = vbMonday Then fSubstitute = True
  Case DateValue(YYYY & "/2/11") + 1
    If Weekday(Serial) = vbMonday Then fSubstitute = True
  Case DateValue(YYYY & "/2/23") + 1
    If YYYY > 2019 And Weekday(Serial) = vbMonday Then fSubstitute = True
  Case DateValue(YYYY & "/3/" & Int(20.8431 + 0.242194 * (YYYY - 1980) - Int((YYYY - 1980) / 4))) + 1
    If Weekday(Serial) = vbMonday Then fSubstitute = True
  Case DateValue(YYYY & "/4/29") + 1
    If Weekday(Serial) = vbMonday Then fSubstitute = True
  Case DateValue(YYYY & "/5/5") + 1
    ' 5月5日が日曜~火曜日だったら、振替休日確定
    If vbSunday <= Weekday(DateValue(YYYY & "/5/5")) And Weekday(DateValue(YYYY & "/5/5")) <= vbTuesday Then fSubstitute = True
  Case DateValue(YYYY & "/9/" & Int(23.2488 + 0.242194 * (YYYY - 1980) - Int((YYYY - 1980) / 4))) + 1
    If Weekday(Serial) = vbMonday Then fSubstitute = True
  Case DateValue(YYYY & "/11/3") + 1
    If Weekday(Serial) = vbMonday Then fSubstitute = True
  Case DateValue(YYYY & "/11/23") + 1
    If Weekday(Serial) = vbMonday Then fSubstitute = True
  Case DateValue(YYYY & "/12/23") + 1
    If YYYY < 2019 And Weekday(Serial) = vbMonday Then fSubstitute = True
End Select
If fSubstitute = True Then
  DayName = "振替休日"
End If

' 2020年特殊対応
Select Case Serial
  Case DateValue("2020/7/20")
    DayName = "平日"
  Case NumWeek(2020, 10, 2)
    DayName = "平日"
  Case DateValue("2020/8/11")
    DayName = "平日"
  Case DateValue("2020/7/23")
    DayName = "海の日"
  Case DateValue("2020/7/24")
    DayName = "スポーツの日"
  Case DateValue("2020/8/10")
    DayName = "山の日"
  Case DateValue("2020/9/22")
    DayName = "秋分の日"
End Select

' 祝日値判定
If DayName = "平日" Then
  ' ## 曜日選択 #####
  If IsDate(Serial) Then
  Select Case Weekday(Serial)
  Case vbSunday
    RV = vbSunday
  'Case vbMonday
  ' RV = vbMonday
  'Case vbTuesday
  ' RV = vbTuesday
  'Case vbWednesday
  ' RV = vbWednesday
  'Case vbThursday
  ' RV = vbThursday
  'Case vbFriday
  ' RV = vbFriday
  Case vbSaturday
    RV = vbSaturday
  End Select

  'RV = Weekday(Serial)
  Else
    Exit Function
  End If
Else
  RV = 8
End If

' ### 終了処理 ############################################################

Select Case RVFlag
  Case 0
    chkHoliday = RV
  Case 1
    chkHoliday = DayName
End Select

End Function

Public Function NumWeek(Year, Month, Weeks)
' 参考資料
' http://www.relief.jp/itnote/archives/003241.php

Dim MonNum As Byte
Dim FirstMonDay As Date

' 第1週目の月曜日を求める
Select Case Weekday(DateValue(Year & "/" & Month & "/1"))
  Case vbSunday ' 1
    MonNum = 1
  Case vbMonday ' 2
    MonNum = 0
  Case vbTuesday ' 3
    MonNum = 6
  Case vbWednesday ' 4
    MonNum = 5
  Case vbThursday ' 5
    MonNum = 4
  Case vbFriday ' 6
    MonNum = 3
  Case vbSaturday ' 7
    MonNum = 2
End Select
FirstMonDay = DateValue(Year & "/" & Month & "/" & 1 + MonNum)

' 第1週目月曜日から何週間後なのか、シリアル値を出力
NumWeek = DateValue(Year & "/" & Month & "/" & 1 + MonNum) + 7 * (Weeks - 1)

End Function

ここしばらくは

ここしばらくは、ツイッター(microblogging)ばかり更新していたのだけれど、思ったことを少し。

すごく、怨嗟の言葉が多いです。

愚痴を吐き出す場所という感じ。
僕自身がそういう使い方をしなかったわけでもないけど、そればっかりが増幅するので精神に影響をきたしそう、という感触があった。

いろいろ考えてたらマイナス思考になっていたので、それは全部カット。

Twitter は感情の増幅回路。

言い得て妙。

amazonaws を iptables で拒否

自宅サーバで公開しているサイトへの amazonaws からのアクセスが、かなりうざい。

amazonaws は、amazon がサービスしているウェブサービス aws からのアクセスとのこと。
そのサービスを使ってアクセスしてきているのは理解したけど、まともにページを表示するようなマネはしていなかった。
具体的には /js/lightbox.min.js のような、Web サービスを行うためのスクリプトだけが狙われてた。
思うに、google アナリティクスのようなサービスに検知されないための処理なんだろう。
あれは通常のページを開いて解析サイトにトラフィックを飛ばさないと解析できないもんだろうし。
それに、普通のユーザはコンテンツをすっ飛ばしてサイト情報を集めたりはしない*1

うん。これは amazonaws を拒否しておこう。

とは思ったものの、IPアドレスの範囲はかなり広い上に細かい。
なので、iptables で拒否するのを躊躇していたんだけど、amazon で情報が出てた。

https://docs.aws.amazon.com/ja_jp/general/latest/gr/aws-ip-ranges.html

Amazon Web Services (AWS) は、その現在の IP アドレス範囲を JSON 形式で公開します。現在の範囲を参照するには、.json ファイルをダウンロードします。

ということなので、時々チェックしないとダメみたい。
とりあえず肝心のデータは、次の URL で取得できた。

https://ip-ranges.amazonaws.com/ip-ranges.json

とはいえ、僕は JSON 形式のデータを解析する方法を知らないんだけど……
と思っていたら、同じページに jq コマンドによる解析例があった。
素晴らしい。

jq コマンドって、リポジトリにあるかな?

$ type apt-file || sudo apt install apt-file
$ sudo apt update
$ sudo apt-file search jq | grep "\/jq$"
jq: /usr/bin/jq

あった。

$ sudo apt install jq
(以下略)

うん、さくっとインストールできた。

次に、上記サイトで「例 3.すべての IPv4 アドレスを取得します」とのサンプルがあるので、試しに参照してみる。

$ wget -q -O /tmp/ip-ranges.json https://ip-ranges.amazonaws.com/ip-ranges.json
$ jq -r '.prefixes | .[].ip_prefix' < /tmp/ip-ranges.json
18.208.0.0/13
52.95.245.0/24
99.77.142.0/24
52.194.0.0/15
54.155.0.0/16
54.196.0.0/15
99.78.170.0/23
52.94.22.0/24
52.95.255.112/28
(以下略)

かなり長いな……
ってことで、行数をカウント。

$ jq -r '.prefixes | .[].ip_prefix' < /tmp/ip-ranges.json | wc
   1682    1682   25080

……重複とか、無いよね?
少し表示された内容を読んでて、重複がありそうだったので確認してみる。

$ jq -r '.prefixes | .[].ip_prefix' < /tmp/ip-ranges.json | sort -un | wc
    360     360    5140

……えーと。
こんなに重複があるとか、なんかの嫌がらせ?
と一瞬思ったけど、リージョン違いによる重複なんだろうな。

create-time を見れば更新されているかどうか分かるとのことなので、定期的に観測するなら create-time を参照すればよさそう。
このサイトだと、また amazonaws がログに表示されるようになったら更新を掛ける程度で。
Raspberry Pi だから、ファイルの更新が結構致命傷に繋がりやすいんだよね……。

iptables への設定については、シェルの for 文で一括登録しておく。

$ pTarget="$(jq -r '.prefixes | .[].ip_prefix' < /tmp/ip-ranges.json | sort -un)"
$ for s in ${pTarget}
do
  sudo iptables -A OUTPUT -d ${s} -o eth0 -j DROP
done
$ sudo iptables -n -L

確認コマンドとして iptables -L だけだと、名前の逆引きが行われてかなり表示が遅くなったので -n を加えた。

しばらく様子見。


あと、分割された CIDR をコマンドラインでまとめ直す方法があれば、調べておきたい。
たとえば、こんな CIDR 表記。

52.56.0.0/16
52.57.0.0/16
52.58.0.0/15
52.60.0.0/16
52.61.0.0/16
52.62.0.0/15

これって、連続してるんだから、CIDR として次のように書けるはずなんだよね。

52.56.0.0/13

もしかすると、IPアドレス 10 個をネットワークアドレス/ブロードキャストアドレスに消費しているのかもしれないけど、サイト管理者としては設定行数が増えるだけなのでメリットを感じられない。

*1:例を言えば、天気を知りたいのに、予報ではなく予報サイトの構成から調べるとか、なかなかトリッキーな性格の持ち主と思われる。

debian 系 iptables 設定

自宅サーバで公開しているサイトへの SEO 関連の robot である semrush.com からのアクセスが、少しうざい。
(SEO 関連のロボットであるという根拠は、リファラー内情報 https://www.semrush.com/bot/ に記載されている)

robots.txt でクローリングを拒否しているけど、その robots.txt 自体はアクセス拒否ができない。
(これを拒否すると、アクセス拒否を伝えられない)

しばらく放置していたけど、/robots.txt へのアクセスが連日あるので iptables で拒否設定しようと思った。

まず、semrush.com が保有している IP アドレス帯域の調査から。

https://awebanalysis.com/ja/ip-lookup/46.229.168.158/

46.229.160.0/20 の帯域は、オランダに割り当てられている模様。
ちょっと範囲が広すぎるので、もう少し狭めてみる。

ドメイン名・IPアドレス検索 (ANSI Whois) - Asuka.IO

ここで、IPアドレスを入力。

https://ja.asuka.io/whois/46.229.168.149

一部を抜粋。

inetnum: 46.229.168.0 - 46.229.169.255
netname: ADVANCEDHOSTERS-NET
descr: Advanced Hosters B.V.
country: US
admin-c: AH36-RIPE
tech-c: AH36-RIPE
status: ASSIGNED PA

ふむ。
46.229.168.0/23 の帯域で、アメリカに割り当てられていることは分かった。

いったん、46.229.168.0/24 の帯域で、まるっと逆引きしてみる。

# for i in {1..254}; do
>   tmp=$(dig -x 46.229.168.$i +short)
>   if [ -n "$tmp" ]; then
>     echo "### 46.229.168.$i ### ${tmp}"
>   fi
> done
### 46.229.168.11 ### docker6-iad.ag1.thousandeyes.com.
### 46.229.168.14 ### ns2.z5o.net.
### 46.229.168.26 ### turanga-leela.ompr.io.
### 46.229.168.27 ### amy-wong.ompr.io.
### 46.229.168.49 ### leela.ompr.io.
### 46.229.168.56 ### mx3.xyzsmtpservice.com.
### 46.229.168.57 ### mx2.thewebsupports.su.
### 46.229.168.129 ### crawl1.bl.semrush.com.
### 46.229.168.130 ### crawl2.bl.semrush.com.
### 46.229.168.131 ### crawl3.bl.semrush.com.
### 46.229.168.132 ### crawl4.bl.semrush.com.
### 46.229.168.133 ### crawl5.bl.semrush.com.
### 46.229.168.134 ### crawl6.bl.semrush.com.
### 46.229.168.135 ### crawl7.bl.semrush.com.
### 46.229.168.136 ### crawl8.bl.semrush.com.
### 46.229.168.137 ### crawl9.bl.semrush.com.
### 46.229.168.138 ### crawl10.bl.semrush.com.
### 46.229.168.139 ### crawl11.bl.semrush.com.
### 46.229.168.140 ### crawl12.bl.semrush.com.
### 46.229.168.141 ### crawl13.bl.semrush.com.
### 46.229.168.142 ### crawl14.bl.semrush.com.
### 46.229.168.143 ### crawl15.bl.semrush.com.
### 46.229.168.144 ### crawl16.bl.semrush.com.
### 46.229.168.145 ### crawl17.bl.semrush.com.
### 46.229.168.146 ### crawl18.bl.semrush.com.
### 46.229.168.147 ### crawl19.bl.semrush.com.
### 46.229.168.148 ### crawl20.bl.semrush.com.
### 46.229.168.149 ### crawl21.bl.semrush.com.
### 46.229.168.150 ### crawl22.bl.semrush.com.
### 46.229.168.151 ### crawl23.bl.semrush.com.
### 46.229.168.152 ### crawl24.bl.semrush.com.
### 46.229.168.153 ### crawl25.bl.semrush.com.
### 46.229.168.154 ### crawl26.bl.semrush.com.
### 46.229.168.155 ### crawl27.bl.semrush.com.
### 46.229.168.156 ### crawl28.bl.semrush.com.
### 46.229.168.157 ### crawl29.bl.semrush.com.

おー。
見事に semrush.com が利用中なIPアドレスが表示されたね。

46.229.168.129 ~ 157 の 29 個ということは、おそらく /27 の 32 個を確保しているんじゃないかな……という予測がたつ。

46.229.168.128 は、おそらくネットワークアドレス
46.229.168.159 は、おそらくブロードキャストアドレス

TCP/IP の CIDR から、こうであろうという予測。

……46.229.168.158 だけが宙に浮いてるけど、この IP アドレス帯域を利用しているのは、上記の割当情報から US であり、つまりはアメリカの人たち。
サイトは日本語しかないし、拒否しても大丈夫かな?

一応、何に使われているのか調査してみる。

46.229.168.158 への ping は、応答あり。なきゃ良かったのに……
ICMP の他、www とか ssh とか 応答なし。

ん~、これに関してのみ、とりあえず許可する方向でいくか。


ということで、設定内容としては 46.229.168.128/27 を Drop することに。
ただし様子見のため、拒否設定の save はしない。
46.229.168.158 は ACCEPT を入れる。

それでは、拒否設定の投入。

# iptables -A OUTPUT -d 46.229.168.128/27 -o eth0 -j DROP
# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
DROP       all  --  anywhere             46.229.168.0/24
#
# iptables -A OUTPUT -d 46.229.168.158/32 -o eth0 -j ACCEPT
# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
DROP       all  --  anywhere             46.229.168.128/27
ACCEPT     all  --  anywhere             46.229.168.158
# 

ここまで設定してから「DROP と ACCEPT の優先順位ってどうなってたっけ?」と思って、ググってみた。

参考サイト様

https://www.virment.com/iptables-setting-example/

……見事に逆順で設定してたね。

初期化したいときは --flush か -F を使う。

# iptables -F
# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
#

初期化できた。

# iptables -A OUTPUT -d 46.229.168.158/32 -o eth0 -j ACCEPT
# iptables -A OUTPUT -d 46.229.168.128/27 -o eth0 -j DROP
# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             46.229.168.158
DROP       all  --  anywhere             46.229.168.128/27
#

順番が入れ替わってるね。

さて、しばらくこれで様子見。



一応、保存したくなった時のことを考えて、調べておく。

環境としては Raspbian を利用している。

# cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 9 (stretch)"
NAME="Raspbian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"

で、いろいろググってみたんだけど、RHEL (CentOS) の情報が多くて、適用できるかどうかが不明だった。
いちおう、これなら大丈夫かなという参照先を。

参考サイト:
https://wiki.debian.org/iptables

ここで書かれている iptables 設定情報の保存方法は2通り。

一つ目は、シェルスクリプトを作って起動時に読み込ませる方法。

Debian では、保存先のファイルを /etc/iptables.up.rules としているみたい。
すでに iptables コマンドで設定しているときは、iptables-save の標準出力を、ファイルにリダイレクトする。

# # ls -l /etc/iptables.up.rules
ls: '/etc/iptables.up.rules' にアクセスできません: そのようなファイルやディレクトリはありません
# iptables-save > /etc/iptables.up.rules

で、これをリストアするときは、次の簡単なシェルスクリプトを書けと。

/etc/network/if-pre-up.d/iptables

#!/bin/sh
/sbin/iptables-restore < /etc/iptables.up.rules

二つ目は、管理パッケージを使う方法。

iptables-persistent

# apt-cache search iptables-persistent
iptables-persistent - boot-time loader for netfilter rules, iptables plugin
netscript-ipfilter - Linux 2.6/3.x iptables management system.

「boot-time loader for netfilter rules, iptables plugin」は、意訳すると「起動時にフィルタルールを読み込む iptablesプラグイン」かな。

これをインストールしてから、次のファイルを作る。

iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6


うーん、やるならパッケージのインストールかな?

# dpkg -l iptables iptables-persistent
要望=(U)不明/(I)インストール/(R)削除/(P)完全削除/(H)保持
| 状態=(N)無/(I)インストール済/(C)設定/(U)展開/(F)設定失敗/(H)半インストール/(W)トリガ待ち/(T)トリガ保留
|/ エラー?=(空欄)無/(R)要再インストール (状態,エラーの大文字=異常)
||/ 名前                 バージョン      アーキテクチャ  説明
+++-====================-===============-===============-==============================================
ii  iptables             1.6.0+snapshot2 armhf           administration tools for packet filtering and
dpkg-query: iptables-persistent に一致するパッケージが見つかりません

ということなので、自分がやるなら次の手順。

$ sudo su -
# apt-get update
# apt-get install iptables-persistent
# 
# iptables -F
# iptables -A OUTPUT -d 46.229.168.158/32 -o eth0 -j ACCEPT
# iptables -A OUTPUT -d 46.229.168.128/27 -o eth0 -j DROP
# iptables -L
# 
# iptables-save > /etc/iptables/rules.v4
# ip6tables-save > /etc/iptables/rules.v6
#
# exit
$

Windows 10 は、ログインしておかないと RDP できない?

念のために、一度 Windows 10 を再起動して RDP を試してみた。
なんと ping に応答しない。
もちろん RDP では接続できない。

コンソールでログインしてから RDP すると、なんと接続できた。

もう一度 Windows 10 を再起動して、ping を流し続けてみたところ、コンソールログインして数分後でないと ping に応答してくれなかった。

コンソールログインしていないと、いろいろ動いてくれないとか。


まぢかよ!!
うがー!

追記。

もう一度 ping を打ちつつ Windows 10 を再起動してみたところ、ping が応答してくれた。

およ?

で、RDP は接続……できないよねえ。
念のため、コマンドプロンプトから mstsc /admin /v:xx.xx.xx.xx でアクセスしてみたら、なんと接続できた。

Windows 10 の挙動、意味が分からなすぎる!

さらに追記。

検証として、もう一度 Windows 10 を再起動。
ping が応答するまで待ってから、RDP 接続しても NG だったものの、もうしばらく待ってからもう一度普通に RDP すると、今度は接続できた。

Windows 10 が起動してから、各種サービスが起動するまでは、かなりのタイムラグがあるように見える。
スペック的には、

CPU Intel CORE i7-4790
メモリ 16 GB
SSD 110GB (空き容量22GB)

なので、そう悪くはないはず。

むぅ。

Windows Update の弊害?

Windows Update の弊害?

この間、Windows を、バージョン 1903 にアップデートした。

その直後だけはリモートアクセスできて安心していたんだけど、その後全く応答がなくなってしまった。

結論からいうと、イーサネット設定(有線LAN)が、プライベートネットワークからパブリックネットワーク接続に書き変わっていた。

以下、その原因究明と対処のあれこれ。

続きを読む

banner コマンドを使う

banner コマンドを使いたいと思ったけど、Raspbian にはインストールされてなかった。

ということで banner コマンドが含まれるパッケージを調べる。

事前設定

$ sudo apt install apt-file
$ sudo apt update

banner コマンドが含まれるパッケージの調査

$ sudo apt-file search banner | grep "\/banner$"
afterstep-data: /usr/share/afterstep/banner
afterstep-data: /usr/share/afterstep/ucf/banner
album-data: /usr/share/doc/album-data/examples/banner
eggdrop-data: /usr/share/eggdrop/text/banner
epic4-help: /usr/share/epic4/help/4_Misc/set/banner
fortunes-it: /usr/share/games/fortunes/banner
fortunes-it: /usr/share/games/fortunes/it/banner
qt4-demos: /usr/lib/qt4/examples/declarative/text/fonts/banner/banner
surfraw: /usr/share/doc/surfraw/banner
sysvbanner: /usr/bin/banner
$ 

ということで、sysvbanner をインストールすれば良さそう。

$ sudo apt-get install sysvbanner
$ banner test

  #####  ######   ####    #####
    #    #       #          #
    #    #####    ####      #
    #    #            #     #
    #    #       #    #     #
    #    ######   ####      #

使用例

うまくいったので、/etc/motd に書き込む。

$ sudo cp -p /etc/motd{,_$(date +%Y%m%d)}
$ ll /etc/motd*
-rw-r--r-- 1 root root 286  728  2017 /etc/motd
-rw-r--r-- 1 root root 286  728  2017 /etc/motd_20190704
$ sudo banner $(uname -n) > /etc/motd
-bash: /etc/motd: 許可がありません

えぇぇぇぇぇ!?

$ sudo su -
# banner $(uname -n) > /etc/motd
# cat /etc/motd
(出力内容は省略)
# ls -l /etc/motd*
-rw-r--r-- 1 root root 390  74 12:01 /etc/motd
-rw-r--r-- 1 root root 286  728  2017 /etc/motd_20190704
# exit
$

なぜうまくいく?