ときどきの雑記帖 RE* (新南口)
ディプロマシー
モンティ・ホール問題
Newton Hub (ニュートンハブ) - Quizカガク視点(かがくしてん) の今週の問題がこれだった
WITCH
イギリス生まれの魔女(WITCH)さん
— 魁竜 @ メカバレ語り部 (@kailyu) January 24, 2026
75年前に造られて今でも普通に動く、ギネス世界記録により世界最古の稼働中のデジタルコンピュータと認定されたらしい pic.twitter.com/0rIIEBnraQ
聞き覚えのない名前だったので調べてみた
- ハーウェル・コンピュータ - Wikipedia
- Harwell Dekatron Computer aka W.I.T.C.H. — The National Museum of Computing
- What is a Computer: Inside the WITCH — Google Arts & Culture
- 61年前のコンピューター「WITCH」、英博物館で再起動 - CNN.co.jp
Streem
- [B! AI] まつもとゆきひろが危惧する、ジュニア不要論の先に広がるIT業界「焼け野原」
- まつもとゆきひろが危惧する、ジュニア不要論の先に広がるIT業界「焼け野原」:「コードを書かない」未来、エンジニアは何者になるのか
“If you were to create a new language today”――いま新しい言語を作るとしたらどんなものを作りますか?
まつもとさんの答えは、「並列処理に特化したデータフロー言語」だった。
あれ、これって…と思ったら
まつもとさんはかつて、このアイデアを基に「Streem(ストリーム。「e」は2つ)」という言語のプロトタイプを作成したことがあるという。
やはり
【お知らせ】本記事を含む、まつもとゆきひろさんの提言をまとめたeBookを、 2026年2月4日にリリースします。eBookだけの特別付録として、 本インタビューの全文を書き起こした「ディレクターズカット」も収納します。楽しみにお待ちください(編集部)
ふむ
shebang
一見するとng.shは実行できなさそうですが、不思議なことに両スクリプトに実行権限を付けて(chmod +xなど) 実行してみると、どちらも正しく動いてしまいます。
気になったので(ry
まずはbash
/* Call execve (), handling interpreting shell scripts, and handling
exec failures. */
int
shell_execve (char *command, char **args, char **env)
{
int i, fd, sample_len;
char sample[HASH_BANG_BUFSIZ];
size_t larray;
SETOSTYPE (0); /* Some systems use for USG/POSIX semantics */
execve (command, args, env);
i = errno; /* error from execve() */
CHECK_TERMSIG;
SETOSTYPE (1);
/* If we get to this point, then start checking out the file.
Maybe it is something we can hack ourselves. */
if (i != ENOEXEC)
{
/* make sure this is set correctly for file_error/report_error */
last_command_exit_value = (i == ENOENT) ? EX_NOTFOUND : EX_NOEXEC; /* XXX Posix.2 says that exit status is 126 */
if (file_isdir (command))
#if defined (EISDIR)
internal_error ("%s: %s", command, strerror (EISDIR));
#else
internal_error (_("%s: is a directory"), command);
#endif
else if (executable_file (command) == 0)
{
errno = i;
file_error (command);
}
/* errors not involving the path argument to execve. */
else if (i == E2BIG || i == ENOMEM)
{
errno = i;
file_error (command);
}
else
{
/* The file has the execute bits set, but the kernel refuses to
run it for some reason. See why. */
#if defined (HAVE_HASH_BANG_EXEC)
READ_SAMPLE_BUF (command, sample, sample_len);
if (sample_len > 0)
sample[sample_len - 1] = '\0';
if (sample_len > 2 && sample[0] == '#' && sample[1] == '!')
{
char *interp;
size_t ilen;
interp = getinterp (sample, sample_len, (int *)NULL);
ilen = strlen (interp);
errno = i;
if (ilen > 0 && interp[ilen - 1] == '\r')
{
interp = xrealloc (interp, ilen + 2);
interp[ilen - 1] = '^';
interp[ilen] = 'M';
interp[ilen + 1] = '\0';
}
sys_error ("%s: %s: %s", command, interp, _("bad interpreter"));
FREE (interp);
return (EX_NOEXEC);
}
else
#endif
if (i == ENOENT)
{
errno = i;
internal_error (_("%s: cannot execute: required file not found"), command);
}
else
{
errno = i;
file_error (command);
}
}
return (last_command_exit_value);
}
/* This file is executable.
If it begins with #!, then help out people with losing operating
systems. Otherwise, check to see if it is a binary file by seeing
if the contents of the first line (or up to 80 characters) are in the
ASCII set. If it's a text file, execute the contents as shell commands,
otherwise return 126 (EX_BINARY_FILE). */
READ_SAMPLE_BUF (command, sample, sample_len);
if (sample_len == 0)
return (EXECUTION_SUCCESS);
/* Is this supposed to be an executable script?
If so, the format of the line is "#! interpreter [argument]".
A single argument is allowed. The BSD kernel restricts
the length of the entire line to 32 characters (32 bytes
being the size of the BSD exec header), but we allow up to 128
characters. */
if (sample_len > 0)
{
#if !defined (HAVE_HASH_BANG_EXEC)
if (sample_len > 2 && sample[0] == '#' && sample[1] == '!')
return (execute_shell_script (sample, sample_len, command, args, env));
else
#endif
if (check_binary_file (sample, sample_len))
{
internal_error ("%s: %s: %s", command, _("cannot execute binary file"), strerror (i));
errno = i;
return (EX_BINARY_FILE);
}
}
/* We have committed to attempting to execute the contents of this file
as shell commands. */
reset_parser ();
initialize_subshell ();
set_sigint_handler ();
/* Insert the name of this shell into the argument list. */
larray = strvec_len (args) + 1;
args = strvec_resize (args, larray + 1);
for (i = larray - 1; i; i--)
args[i] = args[i - 1];
args[0] = shell_name;
args[1] = command;
args[larray] = (char *)NULL;
if (args[0][0] == '-')
args[0]++;
#if defined (RESTRICTED_SHELL)
if (restricted)
change_flag ('r', FLAG_OFF);
#endif
if (subshell_argv)
{
/* Can't free subshell_argv[0]; that is shell_name. */
for (i = 1; i < subshell_argc; i++)
free (subshell_argv[i]);
free (subshell_argv);
}
dispose_command (currently_executing_command); /* XXX */
currently_executing_command = (COMMAND *)NULL;
subshell_argc = larray;
subshell_argv = args;
subshell_envp = env;
unbind_args (); /* remove the positional parameters */
#if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD)
clear_fifo_list (); /* pipe fds are what they are now */
#endif
sh_longjmp (subshell_top_level, 1);
/*NOTREACHED*/
}
execveに失敗してそのエラーコードがENOEXECで、 かつファイルに実行ビットが立っていたら、 バイナリファイルかどうか調べて バイナリファイルでなければ ファイルの中身をシェルスクリプトとみなして実行する。 かな
We have committed to attempting to execute the contents of this file as shell commands.
もうひとつzsh
zsh/Src/exec.c at master · zsh-users/zsh
static int
zexecve(char *pth, char **argv, char **newenvp)
{
int eno;
static char buf[PATH_MAX * 2+1];
char **eep;
unmetafy(pth, NULL);
for (eep = argv; *eep; eep++)
if (*eep != pth)
unmetafy(*eep, NULL);
buf[0] = '_';
buf[1] = '=';
if (*pth == '/')
strcpy(buf + 2, pth);
else
sprintf(buf + 2, "%s/%s", unmeta(pwd), pth);
zputenv(buf);
#ifndef FD_CLOEXEC
closedumps();
#endif
if (newenvp == NULL)
newenvp = environ;
winch_unblock();
execve(pth, argv, newenvp);
/* If the execve returns (which in general shouldn't happen), *
* then check for an errno equal to ENOEXEC. This errno is set *
* if the process file has the appropriate access permission, *
* but has an invalid magic number in its header. */
if ((eno = errno) == ENOEXEC || eno == ENOENT) {
char execvebuf[POUNDBANGLIMIT + 1], *ptr, *ptr2, *argv0;
int fd, ct, t0;
if ((fd = open(pth, O_RDONLY|O_NOCTTY)) >= 0) {
argv0 = *argv;
*argv = pth;
memset(execvebuf, '\0', POUNDBANGLIMIT + 1);
ct = read(fd, execvebuf, POUNDBANGLIMIT);
close(fd);
if (ct >= 0) {
if (ct >= 2 && execvebuf[0] == '#' && execvebuf[1] == '!') {
for (t0 = 0; t0 != ct; t0++)
if (execvebuf[t0] == '\n')
break;
if (t0 == ct)
zerr("%s: bad interpreter: %s: %e", pth,
metafy(execvebuf + 2, -1, META_STATIC), eno);
else {
while (inblank(execvebuf[t0]))
execvebuf[t0--] = '\0';
for (ptr = execvebuf + 2; *ptr && *ptr == ' '; ptr++);
for (ptr2 = ptr; *ptr && *ptr != ' '; ptr++);
if (eno == ENOENT) {
char *pprog;
if (*ptr)
*ptr = '\0';
if (*ptr2 != '/' &&
(pprog = pathprog(ptr2, NULL))) {
if (ptr == execvebuf + t0 + 1) {
argv[-1] = ptr2;
winch_unblock();
execve(pprog, argv - 1, newenvp);
} else {
argv[-2] = ptr2;
argv[-1] = ptr + 1;
winch_unblock();
execve(pprog, argv - 2, newenvp);
}
}
zerr("%s: bad interpreter: %s: %e", pth,
metafy(ptr2, -1, META_STATIC), eno);
} else if (*ptr) {
*ptr = '\0';
argv[-2] = ptr2;
argv[-1] = ptr + 1;
winch_unblock();
execve(ptr2, argv - 2, newenvp);
} else {
argv[-1] = ptr2;
winch_unblock();
execve(ptr2, argv - 1, newenvp);
}
}
} else if (eno == ENOEXEC) {
/* Perform binary safety check on classic shell *
* scripts (shebang wasn't introduced until UNIX *
* Seventh Edition). POSIX says we shall allow *
* execution of scripts with concatenated binary *
* and suggests checking a line exists before the *
* first NUL character with a lowercase letter or *
* expansion. This is consistent with FreeBSD sh. */
int isbinary, hasletter;
if (!(ptr2 = memchr(execvebuf, '\0', ct))) {
isbinary = 0;
} else {
isbinary = 1;
hasletter = 0;
for (ptr = execvebuf; ptr < ptr2; ptr++) {
if (islower((unsigned char) *ptr) || *ptr == '$' || *ptr == '`')
hasletter = 1;
if (hasletter && *ptr == '\n') {
isbinary = 0;
break;
}
}
}
if (!isbinary) {
char** args = argv;
if (argv[0][0] == '-' || argv[0][0] == '+') {
/*
* guard against +foo or -bar script paths being
* taken as options. POSIX says the script path
* must be passed as an *operand*. "--" would also
* make sure the next argument is treated as an
* operand with POSIX compliant sh implementations
* but "-" is more portable (to the Bourne shell in
* particular) and shorter.
*/
*--args = "-";
}
*--args = "sh";
winch_unblock();
execve("/bin/sh", args, newenvp);
}
}
} else
eno = errno;
*argv = argv0;
} else
eno = errno;
}
/* restore the original arguments and path but do not bother with *
* null characters as these cannot be passed to external commands *
* anyway. So the result is truncated at the first null char. */
pth = metafy(pth, -1, META_NOALLOC);
for (eep = argv; *eep; eep++)
if (*eep != pth)
(void) metafy(*eep, -1, META_NOALLOC);
return eno;
}
こっちは
execve("/bin/sh", args, newenvp);
と/bin/sh
に渡している
元記事を再度見たらコメントがついていて、 UNIXのv6やv7のシェルでも同様のことを行っていると
WG 14
今回はなかなかお面白かった
C semantics for contracts
とか
あとワーキングドラフトが
新刊近刊
2月27日(金)新連載。 pic.twitter.com/qHFtntWdZT
— スタジオセンゴク 宮下英樹 (@studio_sengoku) January 26, 2026
また来月号から買わねば
awk
gawk
- Update TODO some more. - gawk.git - gawk
- Sync minrx.c from upstream. - gawk.git - gawk
- Re: wchar.h vs. wctype.h on old mingw
ちょっと気になったのが Remove some too-old translations from po/LINGUAS. - gawk.git - gawk で削られた中に
* LINGUAS: Removed ca, da, fi, ja, ka, ms, vi. These translations are too out-of-date.
日本語が含まれているっぽい
翻訳メッセ―ジが含まれているファイル(ja.po)そのものはリポジトリに残っているけれども、 LINGUASというファイルからjaが削除されたので ビルドしても日本語メッセージは処理されないっぽい
んでtoo-old translationsとあるので
ja.po « po - gawk.git - gawk
をみると
# Japanese messages for gawk.
# Copyright (C) 2003, 2014 Free Software Foundation, Inc.
# This file is distributed under the same license as the gawk package.
# Makoto Hosoya <mhosoya@ozemail.com.au>, 2003.
# Yasuaki Taniguchi <yasuakit@gmail.com>, 2011, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: gawk 4.1.0b\n"
"Report-Msgid-Bugs-To: bug-gawk@gnu.org\n"
"POT-Creation-Date: 2026-01-18 09:31+0200\n"
"PO-Revision-Date: 2014-11-07 12:26+0000\n"
ふむ。
grep -F -e "Project-Id-Version" -e"PO-Revision-Date" *.po で
Project-Id-VersionとPO-Revision-Date
をすべての言語について抜き出してまとめてみると
| file | Project-Id-Version | PO-Revision-Date |
|---|---|---|
| bg.po | gawk-5.3.1b | 2025-02-28 |
| ca.po | gawk 4.1.3h | 2016-12-18 |
| da.po | gawk 4.1.1d | 2015-05-18 |
| de.po | gawk 5.3.1b | 2025-03-04 |
| es.po | gawk 5.3.1b | 2025-05-14 |
| fi.po | gawk 4.1.62 | 2017-08-19 |
| fr.po | gawk 5.3.1b | 2025-03-02 |
| he.po | gawk 5.2.60 | 2025-12-28 |
| id.po | gawk 5.3.1b | 2025-02-28 |
| it.po | gawk 5.4.0 | 2026-01-08 |
| ja.po | gawk 4.1.0b | 2014-11-07 |
| ka.po | gawk 5.2.63 | 2024-08-28 |
| ko.po | gawk 5.3.1b | 2025-03-01 |
| ms.po | gawk 4.0.75 | 2013-04-19 |
| nl.po | gawk 5.0.64 | 2020-03-20 |
| pl.po | gawk 5.3.1b | 2025-02-28 |
| pt.po | gawk 5.3.1b | 2025-03-23 |
| pt_BR.po | gawk 5.1.1e | 2021-09-04 |
| ro.po | gawk 5.3.1b | 2025-03-02 |
| sr.po | gawk-5.3.1b | 2025-05-20 |
| sv.po | gawk 5.3.1b | 2025-02-28 |
| tr.po | gawk 5.1.65 | 2022-08-23 |
| uk.po | gawk 5.2.1b | 2023-06-25 |
| vi.po | gawk 4.2.0e | 2018-01-30 |
| zh_CN.po | gawk 5.3.1b | 2025-05-29 |
確かに日本語メッセージはほかと比べて長いこと更新されてないっぽい
gnulib
glibc 2.43 now implements the functions bsearch, memchr, strchr, strpbrk, strrchr, strstr, wmemchr as macros that expand to something with _Generic, when the C compiler is in C23 mode.