ぶていのログでぶログ

思い出したが吉日

シグナルマスクのビット列をシグナル名に変換する

psコマンドの -o sigmask や、/proc/$pid/statusのSig〜は16進数の文字列で表示されていて、該当するbit数のシグナルにフラグが立っているというような見方になっている。 例えば、ps -o sigmaskで1の位が3ならHUP(1)とINT(2)がマスクされていることになる。 んで、本題。 bashやfishがどういうシグナルマスクを設定しているか気になってたのでps -o sigmaskしてみていたのだが表示される値が 00000000812810040000000080384004 で一瞬でどのシグナルか判断できなかった。 なので、Rubyでスクリプトを書いてみた。

❯ cat sigbits.rb
#!/usr/bin/env ruby

puts "Input signal bits(e.g. 0000000081281004)"
print "-> "
sigbits = gets.chomp.to_i(16)

(1..32).select {|b| (sigbits & (1 << (b - 1))).zero?.! }
  .map {|b| n = Signal.signame(b); "%-9s" % "#{n}(#{b})"}
  .each_slice(6) {|s| puts s.join(" ") }

実際に実行すると↓な感じ。

❯ ruby sigbits.rb
Input signal bits(e.g. 0000000081281004)
-> 0000000080384004
QUIT(3)   TERM(15)  TSTP(20)  TTIN(21)  TTOU(22)  (32)

❯ ruby sigbits.rb
Input signal bits(e.g. 0000000081281004)
-> 0000000081281004
QUIT(3)   PIPE(13)  TSTP(20)  TTOU(22)  XFSZ(25)  (32)

便利。 (32)のシグナル名が表示されていないのは、Linuxにおいて*1NPTLが予約しているシグナルのようだ。

参考: * linux - Why does kill -l not list signal numbers of 32 and 33? - Unix & Linux Stack Exchange * Man page of SIGNAL