ときどきの雑記帖 RE* (新南口)
神無月の巫女
ばね指
寒くなるとばね指っぽい症状がときどき起こるようになるんですが、先日今秋一回目が発生。
ということで先週末に一本仕上げようと思っていたのですができませんでした。と。
de facto
デファクトスタンダード (de facto standard)を 「デファクト」と略すのはもう止まらんだろうと諦めているんですが
https://t.co/FKACOudGK8
— さく (@sakuro) October 13, 2021
>事実上デファクト
はツッコミ待ちだろうか…
タイムアウトにご用心 / Timeout might break application state - Speaker Deck
本当にそう書いてあったw>「事実上デファクト」
Ć
WEB+DB PRESS
早売りをゲットできたんですが、 巻末の次号予告にあった 「21周年記念エッセイ 『今も読みつづける1冊の本』」 というのが気になる…
今週のしずえさん
選挙で一番目に投票する人が行う特別なこととは?
tr
trの範囲指定は POSIX準拠のシェルスクリプトなら 0-9 で動きます。だから [0-9] や 0123456789 と書く必要はなかったんですね - Qiita
この記事で
余談ですが GNU の tr の man ページにはこのように書かれています。
tr [OPTION]… SET1 [SET2]
CHAR1-CHAR2
CHAR1 から CHAR2 までを昇順に展開した文字列[CHAR1-CHAR2]
SET1 と SET2 の両方で指定した場合には CHAR1-CHAR2 と同じ一瞬 [] を使った書式に対応しているのかと思いきや「SET1 と SET2 の両方で指定した場合」という条件が付いています。 つまり置換の場合は無害で -d の場合には使えない(正確にはどう動くのか書いてない)というだけの事です。 この書き方はちょっとひどいですね。
とあったのでいくつかmanを見てみたところ件の記事にあったような記述は見当たらなかったんだけど、 どこのだろう?
Section: User Commands (1)
Updated: GNU Text Utilities
GNU Text Utilities とあるってことはベースはかなり昔のものかな?
範囲指定。
m-n' といった記述は、 m から n ま でのすべての文字を昇順に展開した文字列になる。 m は n の前 になければならず、これに反した場合はエラーとなる。例えば
0-9’ は0123456789' を指定したのと同じことになる。 System V 版の tr では範囲を指定する際に角括弧
[]’ を用いるが、 GNU 版 tr ではこの形式はサポートしていない。 ただしこの形式における変換指定は string1 と string2 の間で角括弧が対応していれば有効である。
だと
GNU coreutils 8.32 April 2020 TR(1)
で、POSIX云々という記載はないけど、
[CHAR1-CHAR2]
SET1 と SET2 の両方で指定した場合には CHAR1-CHAR2 と同じ
に該当するものもない。
Section: User Commands (1)
Updated: 7 October 2002
範囲指定
System V 版の tr では範囲を指定する際に角括弧 `[]’ を用いるが、 GNU 版 tr ではこの形式はサポートしていない。 ただしこの形式における変換指定は SET1 と SET2 の間で角括弧が対応していればちゃんと動作する。
これは最初のと同じかな。サイトは同じだし。
ところでGNUのツール類のドキュメントはmanではなくinfoにあたるべきなので GNU Coreutils 9.0 を見てみると
Ranges
The notation ‘m-n’ expands to all of the characters from m through n, in ascending order. m should collate before n; if it doesn’t, an error results. As an example, ‘0-9’ is the same as ‘0123456789’.
GNU tr does not support the System V syntax that uses square brackets to enclose ranges. Translations specified in that format sometimes work as expected, since the brackets are often transliterated to themselves. However, they should be avoided because they sometimes behave unexpectedly. For example, ‘tr -d ‘[0-9]’’ deletes brackets as well as digits.
やっぱり誤解を招くような記述はなし。
あと、-dオプション指定時はオペランドを一つしかとらないので
kbk@toybox4:/mnt/c/Users/kbk$ tr --version
tr (GNU coreutils) 8.28
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Jim Meyering.
kbk@toybox4:/mnt/c/Users/kbk$ tr -d '[a-z]' '[A-Z]'
tr: extra operand ‘[A-Z]’
Only one string may be given when deleting without squeezing repeats.
Try 'tr --help' for more information.
こうなる。
追記
などに問題の記述が見つかりました。
GNU’s Not Unix
もうひとつ。
Linux は POSIX の認証を 1 ドルで得られる申し出を断っていた(POSIX に完全準拠することに興味がないため) - Qiita
IEEE は標準規格の名前を IEEEIX にしようとしていたらしいのですが、POSIX と名前をつけた理由には、 IEEEIX の発音は恐怖の叫び声のようだ → 誰もそんな名前で呼ばないだろう → みんな Unix と呼ぶんじゃないか? → GNU のライバル、Unix という名前で呼ばれるのは嫌だ(※ GNU は GNU is Not UNIX の略)と書いてあって笑いました。
これ、
What is POSIX? Richard Stallman explains | Opensource.com
Since GNU’s Not Unix, and it was intended to replace Unix, I did not want people to call GNU a “Unix system.” I, therefore, proposed a concise name that people might actually use. Having no particular inspiration, I generated a name the unclever way: I took the initials of “portable operating system” and added “ix.” The IEEE adopted this eagerly.
It seemed to me that nobody would ever say “IEEEIX”, since the pronunciation would sound like a shriek of terror; rather, everyone would call it “Unix”. That would have boosted AT&T, the GNU Project’s rival, an outcome I did not want. So I looked for another name, but nothing natural suggested itself to me.
(プロジェクトとしての)GNUのライバルがAT&Tだということを言っているのであって、 (成果物としての)GNUのライバルがUNIXだとは言っていないと思う。
「GNU’s Not Unixというキャッチフレーズ」を誤解してんじゃないかなあ (面倒くさいので解説は書かない)。
mawk
ところで opensource.com の方を読んでいくとこんなのが
Mawk supported the feature first, but it was without a maintainer for several years, leaving gawk to carry the torch. (Mawk has since gained a new maintainer, so arguably credit can be shared for pushing this feature into the collective expectation.)
「新しいメンテナー」。なのかなあ🤔
mikeはmawkを放置はしていても「手放して」はいないと思うのだけど。 放置していたものをmike以外の人がforkし、手を入れたものを 「mawk」と呼べる(呼んでいい)のか?
あー、そこ。「お前が言うな」とか言わない😅
rm
そういや今の rm は / の削除を基本的に嫌がるようになってるみたいだけど、意味的にはルートだけど // とか ../../../../../(繰り返し)../ とかの場合ってどうなるんだろう。
— yoh2 (@yoh2_sdj) October 18, 2021
というツイートが目に留まったので(ry
まずは coreutils/rm.c at master · coreutils/coreutils を見たわけだけど、
uintmax_t n_files = argc - optind;
char **file = argv + optind;
if (prompt_once && (x.recursive || 3 < n_files))
{
fprintf (stderr,
(x.recursive
? ngettext ("%s: remove %"PRIuMAX" argument recursively? ",
"%s: remove %"PRIuMAX" arguments recursively? ",
select_plural (n_files))
: ngettext ("%s: remove %"PRIuMAX" argument? ",
"%s: remove %"PRIuMAX" arguments? ",
select_plural (n_files))),
program_name, n_files);
if (!yesno ())
return EXIT_SUCCESS;
}
enum RM_status status = rm (file, &x);
assert (VALID_STATUS (status));
return status == RM_ERROR ? EXIT_FAILURE : EXIT_SUCCESS;
}
と、rmという関数で実際の削除をやっているようなのだけど このファイル(rm.c)の中にその関数はなく、 coreutils/remove.c at master · coreutils/coreutils の中にあった。ファイルの先頭には
/* Extracted from rm.c, librarified, then rewritten twice by Jim Meyering. */
とあり、rmのほかにもmvなどからこのファイルにある関数が呼ばれているっぽい。で
/* Remove FILEs, honoring options specified via X.
Return RM_OK if successful. */
enum RM_status
rm (char *const *file, struct rm_options const *x)
{
enum RM_status rm_status = RM_OK;
if (*file)
{
int bit_flags = (FTS_CWDFD
| FTS_NOSTAT
| FTS_PHYSICAL);
if (x->one_file_system)
bit_flags |= FTS_XDEV;
FTS *fts = xfts_open (file, bit_flags, NULL);
while (1)
{
FTSENT *ent;
ent = fts_read (fts);
if (ent == NULL)
{
if (errno != 0)
{
error (0, errno, _("fts_read failed"));
rm_status = RM_ERROR;
}
break;
}
enum RM_status s = rm_fts (fts, ent, x);
assert (VALID_STATUS (s));
UPDATE_STATUS (rm_status, s);
}
if (fts_close (fts) != 0)
{
error (0, errno, _("fts_close failed"));
rm_status = RM_ERROR;
}
}
return rm_status;
}
xfts_openという関数はgithub上のミラーや coreutils.git - GNU coreutils にも見当たらないのだけど、 coreutilsのtar玉を開いてディレクトリ libを見るとxfts.cというファイル (たぶんパッケージ(tar玉)を作る手順の中で生成されるんだろうけど追いかけるの面倒くさい) があって、その中にある。
/* Fail with a proper diagnostic if fts_open fails. */
FTS *
xfts_open (char * const *argv, int options,
int (*compar) (const FTSENT **, const FTSENT **))
{
FTS *fts = fts_open (argv, options | FTS_CWDFD, compar);
if (fts == NULL)
{
/* This can fail in two ways: out of memory or with errno==EINVAL,
which indicates it was called with invalid bit_flags. */
assert (errno != EINVAL);
xalloc_die ();
}
return fts;
}
まあfts_openのラッパーぽいですね(「xほげほげ」という形式の名前で この種のラッパー関数はGNUのコードではよく見かける)。
fts_openを始めとしたfts_***な関数はGNU Lib(Gnulib - Wikipedia) にある模様。あと良く知らない関数だったので 検索して引っかかったものなど。
- Savannah Git Hosting - gnulib.git/tree - lib/
- Savannah Git Hosting - gnulib.git/blob - lib/fts.c
- fts でファイル階層をたどる - Qiita
- Man page of FTS
- Linux - fts_open()、fts_read()でディレクトリのファイルを探している例
- Man page of FTS
関数rmではxfts_openのあとでrm_ftsという関数を呼び出しているのだけど その実体は coreutils/remove.c at master · coreutils/coreutils にある。
が、
/* This function is called once for every file system object that fts
encounters. fts performs a depth-first traversal.
A directory is usually processed twice, first with fts_info == FTS_D,
and later, after all of its entries have been processed, with FTS_DP.
Return RM_ERROR upon error, RM_USER_DECLINED for a negative response
to an interactive prompt, and otherwise, RM_OK. */
static enum RM_status
rm_fts (FTS *fts, FTSENT *ent, struct rm_options const *x)
{
switch (ent->fts_info)
{
case FTS_D: /* preorder directory */
if (! x->recursive
&& !(x->remove_empty_directories
&& is_empty_dir (fts->fts_cwd_fd, ent->fts_accpath)))
{
/* This is the first (pre-order) encounter with a directory
that we cannot delete.
Not recursive, and it's not an empty directory (if we're removing
them) so arrange to skip contents. */
省略
case FTS_F: /* regular file */
case FTS_NS: /* stat(2) failed */
case FTS_SL: /* symbolic link */
case FTS_SLNONE: /* symbolic link without target */
case FTS_DP: /* postorder directory */
case FTS_DNR: /* unreadable directory */
case FTS_NSOK: /* e.g., dangling symlink */
case FTS_DEFAULT: /* none of the above */
{
/* With --one-file-system, do not attempt to remove a mount point.
fts' FTS_XDEV ensures that we don't process any entries under
the mount point. */
if (ent->fts_info == FTS_DP
&& x->one_file_system
&& FTS_ROOTLEVEL < ent->fts_level
&& ent->fts_statp->st_dev != fts->fts_dev)
{
mark_ancestor_dirs (ent);
error (0, 0, _("skipping %s, since it's on a different device"),
quoteaf (ent->fts_path));
return RM_ERROR;
}
bool is_dir = ent->fts_info == FTS_DP || ent->fts_info == FTS_DNR;
enum RM_status s = prompt (fts, ent, is_dir, x, PA_REMOVE_DIR, NULL);
if (s != RM_OK)
return s;
return excise (fts, ent, x, is_dir);
}
case FTS_DC: /* directory that causes cycles */
emit_cycle_warning (ent->fts_path);
fts_skip_tree (fts, ent);
return RM_ERROR;
case FTS_ERR:
/* Various failures, from opendir to ENOMEM, to failure to "return"
to preceding directory, can provoke this. */
error (0, ent->fts_errno, _("traversal failed: %s"),
quotef (ent->fts_path));
fts_skip_tree (fts, ent);
return RM_ERROR;
default:
error (0, 0, _("unexpected failure: fts_info=%d: %s\n"
"please report to %s"),
ent->fts_info,
quotef (ent->fts_path),
PACKAGE_BUGREPORT);
abort ();
}
}
どうも手ごわそうなので今日のところはここまで。
36DA5B7FEC924801
の続き。 と行きたいところだけどうまくまとまらなかったのであった。
ちょっとだけ書くと、バイト&ワードの風にのっての記事の変換文字列は 「M系列」から出てきたんじゃないか? というところからの展開。
あと、大元のツイートにあった36DA5B7FEC924801
がどこから来たのかわからんなあ
という話。こっちはツイート主に聞くべきなのかもしれないけど
(と言ったらバイト~の方も林さんに尋ねるか。って話ですわなあ。
窓口あるのかわからんけど)。
No. 49 36C80125B7FEDA49 0011000010111101001
No. 50 36C925B7FEDA4801 0011001011110100001
No. 51 36DA480125B7FEC9 0011010000101111001
No. 52 36DA4925B7FEC801 0011010010111100001
No. 53 36DA5B7FEC801249 0011010111100001001
No. 54 36DA5B7FEC924801 0011010111100100001
No. 55 36DB7FEC80125A49 0011011110000101001
No. 56 36DB7FEC925A4801 0011011110010100001
前回の手順で3(0011)を種に始めても出てこないんだよねえ>36DA5B7FEC924801