>/dev/null 2>&1について

これがわかりにくくなってるのは、2に該当する標準エラー出力とは?というのを説明している人があまりいないことなんじゃないかと思ってるので

$ cd /tmp/
$ ls
cmclist-20260225  
$

例えばこの時に、
"hoge"って単語がcmclist-20260225 内に入ってないとエラーになります。これが標準出力1に該当しています。
grepの場合は、対象ワードが見つけられれば標準出力0、見つけられないと標準出力1となるようになってます。

$ grep "hoge" cmclist-20260225
$ echo $?
1
$


次に、cmclist-20260225じゃなくてcmclist-20260226にgrepしたらどうでしょう?

$ grep "hoge" cmclist-20260226
grep: cmclist-20260226: No such file or directory
$ echo $?
2
$

これが標準エラー出力2に該当しています。"grep: cmclist-20260226: No such file or directory"っていうメッセージは必ず出力されてしまいますが、
これを出力させたくないケースのときに>/dev/null 2>&1を使います。

$ grep "hoge" cmclist-20260226 > /dev/null 2>&1
$ echo $?
2
$

こういうことです。

$ grep "y-super-1" cmclist-20260225
y-super-1.cmc
$ echo $?
0
$

grepでその行を見つけてこれれば見つけた行が返ってきます。これが標準出力0に相当しています。

$ grep "y-super-1" cmclist-20260225 > /dev/null
$ echo $?
0
$

grepの場合は見つけた行は出力されますが、それを出力させたくないときに>/dev/nullに結果を投げます。
これでも0が返ってきますので、cmclist-20260225の中に"y-super-1"が存在していることが分かります。

ちなみに、grepの場合は見つけた場合に出力させないオプションも存在しています。

$ grep -q "y-super-1" cmclist-20260225
$ echo $?
0
$

これでもいいんですけど。さて/dev/nullに投げるのとどっちのほうが挙動が早いんでしょうね???

paizaのB136問題をbashで

paiza.jp

bashは2次元配列ってどうやって作ればいいのかよくわからなかったので、x軸とy軸がこの問題だと100までということになってるので、
arr[1][1]とやりたいところをarr[1001]とするようにしてます。
arr[99][99]だったらarr[99099]ですね
arr[100][1]だったら、arr[100001]です。

力技ですね

#!/bin/bash


read N H W
read SY SX
read SS

for DATA_H in $(seq 1 $H)
do
read -a ARR
for DATA_W in $(seq 1 $W)
do
DATA=$((DATA_W+DATA_H*1000))
CHOCO[$DATA]=${ARR[$((DATA_W-1))]}
done

done


declare -p CHOCO

JIBUN=$((SY*1000+SX))

for MOGE in $(seq 2 $(echo $SS | wc -c))
do
SHIREI=${SS:$((MOGE-2)):1}
if [ $SHIREI == F ]; then
        JIBUN=$((JIBUN - 1000))
        echo ${CHOCO[$JIBUN]}
fi
if [ $SHIREI == B ]; then
        JIBUN=$((JIBUN + 1000))
        echo ${CHOCO[$JIBUN]}
fi
if [ $SHIREI == R ]; then
        JIBUN=$((JIBUN + 1))
        echo ${CHOCO[$JIBUN]}
fi
if [ $SHIREI == L ]; then
        JIBUN=$((JIBUN -1))
        echo ${CHOCO[$JIBUN]}
fi

done

一度read -a arrでチョコの数を入力しつつ、あとでさっきの配列番号ルールに置き換えてコピーしに行っています。
declare -p CHOCO
してるところはデバッグ用です。 何か配列に入ってないと表示されないのですね。何も入ってないところも表示されちゃうのかと思ってました。

下が実行結果サンプルの1つ目のほうだけやっておきます。

ume@fifteen:~/bin$ ./paiza_b136.sh
3 3 3
2 1
FRB
3 6 2
0 4 1
5 0 7
declare -a CHOCO=([1001]="3" [1002]="6" [1003]="2" [2001]="0" [2002]="4" [2003]="1" [3001]="5" [3002]="0" [3003]="7")
3
6
4
ume@fifteen:~/bin$
ume@fifteen:~/bin$ TEST="abcd1234xyz"
ume@fifteen:~/bin$ echo ${TEST:4:1}
1
ume@fifteen:~/bin$ echo ${TEST:6:3}
34x
ume@fifteen:~/bin$ echo ${TEST:0:1}
a
ume@fifteen:~/bin$

こういうのできるのね。こういうのってcut使うのが普通なのかと思ってた

ume@fifteen:~/bin$ echo ${TEST:1:3}
bcd
ume@fifteen:~/bin$ echo ${TEST} | cut -b 2-4
bcd
ume@fifteen:~/bin$

こういう感じです

paiza-c166

paizaのスキルチェックでは使えないbashで書いておくのは怒られないでしょ・・・ たぶん

素直に全部ばらして書くとこんな感じだと思う

#!/bin/bash

read X

N=0
while true
do
if [ $((500 * N)) -gt $X ]; then
break
fi
N=$((N+1))
done

N=$((N-1))
X=$((X-500*N))

M=0
while true
do
if [ $((100 * M)) -gt $X ]; then
break
fi
M=$((M+1))
done

M=$((M-1))
X=$((X-100*M))

L=0
while true
do
if [ $((50 * L)) -gt $X ]; then
break
fi
L=$((L+1))
done

L=$((L-1))
X=$((X-50*L))

K=0
while true
do
if [ $((10 * K)) -gt $X ]; then
break
fi
K=$((K+1))
done

K=$((K-1))
X=$((X-10*K))

J=0
while true
do
if [ $((5 * J)) -gt $X ]; then
break
fi
J=$((J+1))
done

J=$((J-1))
X=$((X-5*J))

I=0
while true
do
if [ $((1 * I)) -gt $X ]; then
break
fi
I=$((I+1))
done

I=$((I-1))
X=$((X-1*I))

echo "500en $N mai
100en $M mai
50en $N mai
10en $L mai
5 en $J mai
1 en $I mai
"

echo $((N+M+L+K+J+I))


たとえば、いっぱい出てくる

N=0
while true
do
if [ $((500 * N)) -gt $X ]; then
break
fi
N=$((N+1))
done

N=$((N-1))
X=$((X-500*N))

とかは関数とかでまとめられると思うし、500円100円で分かれてるだけなのでここを変数にしてforにでもしたほうが素直な感じもします。








てか剰余使えってことだろうな・・・

#!/bin/bash

read X

KOUKA="500
100
50
10
5
1
"
for YEN in $(echo $KOUKA)
do
        GOKEI=$((X/YEN+GOKEI))
        echo "$YEN -> $((X/YEN)) mai"
        X=$((X%YEN))
done

echo $GOKEI

たぶんこういう風にするのが正解なんだろうね

https://ume.hatenadiary.com/entry/2025/04/26/014333 続き

バージョンの問題ではないのかもしれない。
しばらく5.8.0で動いていたんですが、サーバを再起動したら元の問題と同じような状況が発生していました。
なんででしょうね。
とりあえず、5.9.4pre2をソースからmakeしてインストールしたらまた動くようになっていました。
なんででしょう・・・ 意味わからん@@ パケットをサーバが受け取ってsnmptrapdに渡すか、渡した直後くらいにその情報が消滅してるような気がしますが、
そんなのできないだろ とも思うのです。 chatGPTさんはこういう問題には役立たずでした@@

Ubuntu24.04のsnmptrapd (net-snmp 5.9.4pre2) だとなぜかうまく動いてくれないケース

KDDIのWMTAのtrap受信用にnet-snmpのsnmptrapd version5.2.3を使っていたんですが、あまりにも古いので
サーバ更新したついでにまるっとOSごと新しくしたら嵌った話を書いておきます。
まだ原因はよくわかってないです。

元の環境

$ /usr/sbin/snmptrapd  -v

NET-SNMP Version:  5.2.3
Web:               http://www.net-snmp.org/
Email:             net-snmp-coders@lists.sourceforge.net

$


これをサーバ側はUbuntu24.04、snmptrapdのバージョンは2025/4/25現在、デフォルトだと5.9.4+dfsg-1.1ubuntu3.1というバージョンのパッケージが割り当たります。

$ dpkg --list | grep snmptrapd
ii  libnetsnmptrapd40t64:amd64           5.9.4+dfsg-1.1ubuntu3.1                 amd64        SNMP (Simple Network Management Protocol) trap library
ii  snmptrapd                            5.9.4+dfsg-1.1ubuntu3.1                 amd64        Net-SNMP notification receiver
$


そうしたら、正常にsnmptrapdにtrapパケットが割り当たってないような動きになっていました。
snmptrapd.logには何も吐かれず、パケットキャプチャするとパケット自体は問題なくサーバには到達しています。
chatGPTさんはufwiptablesを見ろっていってるけど、いや両方とも非アクティブなんだとさんざん言ってるだろ・・ 
なんかchatGPTさんはこの問題ひたすら回答ループしてましたね。質問方法がまずいんですかね??


それはさておき、最近のsnmptrapdもsystemdで動かすのが通常っぽいので、それの設定でも間違えたかとかいろいろみてたんですが、
そもそも、systemd経由でsnmptrapdを起動せずに手動でうごかしても標準出力にもでてこないので、systemdの問題というわけではなくて、snmptrapdそのものになにか原因があるのだろうというところまではわかりました。
なのでとりあえずnet-snmpのバージョンを落としてみることにしていました。
source-forgeから拾ってきた、5.8.0をmake make installしたところ、
このバージョンなら特に問題なく(?) snmptrapdを直接動かせば標準出力にそのtrap情報が吐き出されるので

5.9.4+dfsg-1.1ubuntu3.1  だけ何か問題があるのか、もしかしたら飛んできているtrapはsnmp version 1なのでそれのフォーマットが何か違くて5.9.4+dfsg-1.1ubuntu3.1 で弾かれてしまうみたいなことがおそらく考えられそうです。


テスト用で作ったsnmptrapコマンドでは5.9.4+dfsg-1.1ubuntu3.1  でも特に問題なく動いていたんですが、、、なんなんでしょうね




でその過程でchatGPTさんに教えてもらいましたが、
snmptrapdのログをファイル出力させるときに、

/opt/net-snmp-5.8.0/sbin/snmptrapd -d -LOw -Lf /var/log/snmp/snmptrapd.log -f -c /etc/snmp/snmptrapd.conf udp:162

こんな感じで-Lf ログファイル名 という感じで書きますが、こうするとsnmptrapdが再起動するたびに、ログファイルが初期化されてしまうので、そのファイル初期化を防ぐために、teeを使って標準出力を常に追記し続けるようにするといいってchatGPTさんに教えてもらいました。
つまりsystemdだとこんな感じに書くようです。

ExecStart=/bin/sh -c '/opt/net-snmp-5.8.0/sbin/snmptrapd -f -Lo -c /etc/snmp/snmptrapd.conf udp:162 | tee -a /var/log/snmp/snmptrapd.log'

うわぁ、かしこい@@

docsis version 0.9.9-dev を ubuntu 24.04.01で動かす方法

とりま普通に実行するとエラーになる。

ume@fifteen:~$ docsis -d test-MAX 
docsis: error while loading shared libraries: libnetsnmp.so.35: cannot open shared object file: No such file or directory
 127 ume@fifteen:~$


libnetsnmp.so.35がない。
/usr/lib/x86_64-linux-gnu/


うちのdocsis環境

ume@fifteen:~$ docsis -v
DOCSIS Configuration File creator, version 0.9.9-dev
Copyright (c) 1999,2000,2001 Cornel Ciocirlan, ctrl@users.sourceforge.net
Copyright (c) 2002,2003,2004,2005 Evvolve Media SRL, docsis@evvolve.com
Copyright (c) 2014 - 2015 Adrian Simionov, daniel.simionov@gmail.com
ume@fifteen:/usr/lib/x86_64-linux-gnu$ ls -al libnetsnmp*
lrwxrwxrwx 1 root root      20  3月 31  2024 libnetsnmp.so -> libnetsnmp.so.40.2.1
lrwxrwxrwx 1 root root      20  3月 31  2024 libnetsnmp.so.40 -> libnetsnmp.so.40.2.1
-rw-r--r-- 1 root root  875024  3月 31  2024 libnetsnmp.so.40.2.1
lrwxrwxrwx 1 root root      25  3月 31  2024 libnetsnmpagent.so -> libnetsnmpagent.so.40.2.1
lrwxrwxrwx 1 root root      25  3月 31  2024 libnetsnmpagent.so.40 -> libnetsnmpagent.so.40.2.1
-rw-r--r-- 1 root root  465288  3月 31  2024 libnetsnmpagent.so.40.2.1
lrwxrwxrwx 1 root root      27  3月 31  2024 libnetsnmphelpers.so -> libnetsnmphelpers.so.40.2.1
lrwxrwxrwx 1 root root      27  3月 31  2024 libnetsnmphelpers.so.40 -> libnetsnmphelpers.so.40.2.1
-rw-r--r-- 1 root root   14112  3月 31  2024 libnetsnmphelpers.so.40.2.1
lrwxrwxrwx 1 root root      24  3月 31  2024 libnetsnmpmibs.so -> libnetsnmpmibs.so.40.2.1
lrwxrwxrwx 1 root root      24  3月 31  2024 libnetsnmpmibs.so.40 -> libnetsnmpmibs.so.40.2.1
-rw-r--r-- 1 root root 1431392  3月 31  2024 libnetsnmpmibs.so.40.2.1
lrwxrwxrwx 1 root root      25  3月 31  2024 libnetsnmptrapd.so -> libnetsnmptrapd.so.40.2.1
lrwxrwxrwx 1 root root      25  3月 31  2024 libnetsnmptrapd.so.40 -> libnetsnmptrapd.so.40.2.1
-rw-r--r-- 1 root root   63832  3月 31  2024 libnetsnmptrapd.so.40.2.1
ume@fifteen:/usr/lib/x86_64-linux-gnu$

シンボリックリンクばっかりなので、シンボリックリンクでいけそう

ln -s   libnetsnmp.so.40  libnetsnmp.so.35

これで使えるようになります。

gzipで固めたときのタイムスタンプについて

ume@fifteen:~$ ls -al testdhcp01.pkt
-rw-r--r-- 1 ume ume 1940  5月 30  2017 testdhcp01.pkt
ume@fifteen:~$

こうなってるファイルをgzipで固めると gzip testdhcp01.pkt
ですが

ume@fifteen:~$ gzip testdhcp01.pkt
ume@fifteen:~$ ls -al testdhcp01.pkt*
-rw-r--r-- 1 ume ume 554  5月 30  2017 testdhcp01.pkt.gz
ume@fifteen:~$

タイムスタンプは元のファイルのタイムスタンプになっています。普通の場合はこれでよいのですが、これをgzipで固めたときの時間に変えられないものか
と思って調べましたがそういうのはなさそう。-nや-Nはたぶんそういうことじゃないっぽい。

なのでしょうがないから別のファイルにcpすることで対応する

ume@fifteen:~$ gzip testdhcp01.pkt
ume@fifteen:~$ cp testdhcp01.pkt.gz testdhcp01.pkt.gzhoge
ume@fifteen:~$ ls -al testdhcp01.pkt*
-rw-r--r-- 1 ume ume 554  5月 30  2017 testdhcp01.pkt.gz
-rw-r--r-- 1 ume ume 554 11月  7 15:37 testdhcp01.pkt.gzhoge
ume@fifteen:~$

しょうもない@@ こういうオプションだって存在してそうなのに