ときどきの雑記帖 RE* (新南口)
季節の中で
今週のしずえさん
「プードル」
deploy
そうか、こういうのも「deploy」と言うのだねえ。
Russia has deployed roughly 190,000 conventional and irregular ground forces—in addition to naval and air forces and approximately 50,000 Belarussian soldiers—which could conduct operations in Ukraine.
— CSIS (@CSIS) February 20, 2022
Read CSIS's latest analysis on the buildup: https://t.co/3pMrPWjBZY pic.twitter.com/nAQHnh3yQS
ActivePerl
Struggling with ActivePerl installation on Windows : perl
そう言えばStrawberry Perlもしばらくバージョンアップがないような…
Strawberry Perl for Windows - Releases
Strawberry Perl 5.32.1.1 (2021-01-24)
行頭にスペース置くとヒストリーに記録されない
実はこの仕様知らなかった。
再起動/削除/変更コマンドの頭に空白をつける - ぶていのログでぶログ
bashやzsh、fishなどではコマンドラインの先頭に空白をつけることで、そのコマンドラインだけhistoryに残さないという機能がある。
ちゃんと設定があるという突っ込みを頂いたので追記、環境変数HISTCONTROLに ignorespace または ignoreboth が設定されていたらこの記事の挙動になる。
という事がmanにちゃんと書いてあった。
bash
BashはGNUのものなので、manではなくInfoを参照する(古事記にもそう書かれている)。
HISTCONTROL
A colon-separated list of values controlling how commands are saved on the history list. If the list of values includes ‘ignorespace’, lines which begin with a space character are not saved in the history list. A value of ‘ignoredups’ causes lines which match the previous history entry to not be saved. A value of ‘ignoreboth’ is shorthand for ‘ignorespace’ and ‘ignoredups’. A value of ‘erasedups’ causes all previous lines matching the current line to be r emoved from the history list before that line is saved. Any value not in the above list is ignored. If HISTCONTROL is unset, or does not include a valid value, all lines read by the shell parser are saved on the history list, subject to the value of HISTIGNORE. The second and subsequent lines of a multi-line compound command are not tested, and are added to the history regardless of the value of HISTCONTROL.
HISTIGNORE
A colon-separated list of patterns used to decide which command lines should be saved on the history list. Each pattern is anchored at the beginning of the line and must match the complete line (no implicit ‘*’ is appended). Each pattern is tested against the line after the checks specified by HISTCONTROL are applied. In addition to the normal shell pattern matching characters, ‘&’ matches the previous history line. ‘&’ may be escaped using a backslash; the backslash is removed before attempting a match. The second and subsequent lines of a multi-line compound command are not tested, and are added to the history regardless of the value of HISTIGNORE. The pattern matching honors the setting of the extglob shell option.
HISTIGNORE subsumes the function of HISTCONTROL. A pattern of ‘&’ is identical to ignoredups, and a pattern of ‘[ ]*’ is identical to ignorespace. Combining these two patterns, separating them with a colon, provides the functionality of ignoreboth.
コードだとこの辺だろうか。
bashhist.c
/* Check LINE against what HISTCONTROL says to do. Returns 1 if the line
should be saved; 0 if it should be discarded. */
static int
check_history_control (line)
char *line;
{
HIST_ENTRY *temp;
int r;
if (history_control == 0)
return 1;
/* ignorespace or ignoreboth */
if ((history_control & HC_IGNSPACE) && *line == ' ')
return 0;
/* ignoredups or ignoreboth */
if (history_control & HC_IGNDUPS)
{
using_history ();
temp = previous_history ();
r = (temp == 0 || STREQ (temp->line, line) == 0);
using_history ();
if (r == 0)
return r;
}
return 1;
}
いつ頃からある機能なのだろうかと調べてみると、かなり以前からのものらしい。 NEWSをみると
o. Bash now uses some new variables: LC_ALL, LC_MESSAGES, LC_CTYPE,
LC_COLLATE, LANG, GLOBIGNORE, HISTIGNORE.
というのがみつかるが、これは
This is a terse description of the new features added to bash-2.0 since
the release of bash-1.14.7. As always, the manual page (doc/bash.1) is
the place to look for complete descriptions.
2.0リリース時のもの。ここにはHISTIGNORE
しかないけれども、
HISTCONTROL
は遅れて3.0の辺りで入ったものらしい。
e. HISTCONTROL is now a colon-separated list of values, which permits
more extensibility and backwards compatibility.
f. HISTCONTROL may now include the `erasedups' option, which causes all lines
matching a line being added to be removed from the history list.
This is a terse description of the new features added to bash-3.0 since
the release of bash-2.05b. As always, the manual page (doc/bash.1) is
the place to look for complete descriptions.
じゃあ2.0ではどんな感じだったのだろうかと言うと
2.0/bashhist.c
/* Add LINE to the history list depending on the value of HISTORY_CONTROL. */
void
maybe_add_history (line)
char *line;
{
int should_add;
HIST_ENTRY *temp;
should_add = 0;
/* Don't use the value of history_control to affect the second
and subsequent lines of a multi-line command when
command_oriented_history is enabled. */
if (command_oriented_history && current_command_line_count > 1)
{
bash_add_history (line);
return;
}
switch (history_control)
{
case 0:
should_add = 1;
break;
case 1:
if (*line != ' ')
should_add = 1;
break;
case 3:
if (*line == ' ')
break;
/* FALLTHROUGH if case == 3 (`ignoreboth') */
case 2:
using_history ();
temp = previous_history ();
if (temp == 0 || STREQ (temp->line, line) == 0)
should_add = 1;
using_history ();
break;
}
if (should_add && history_should_ignore (line) == 0)
bash_add_history (line);
}
単純なだけにわかりやすいすな。 これが1.14.7だと
1.14.7 bashhist.c
/* Add LINE to the history list depending on the value of HISTORY_CONTROL. */
void
maybe_add_history (line)
char *line;
{
int h;
/* Don't use the value of history_control to affect the second
and subsequent lines of a multi-line command when
command_oriented_history is enabled. */
if (command_oriented_history && current_command_line_count > 1)
h = 0;
else
h = history_control;
switch (h)
{
case 0:
bash_add_history (line);
break;
case 1:
if (*line != ' ')
bash_add_history (line);
break;
case 3:
if (*line == ' ')
break;
/* FALLTHROUGH if case == 3 (`ignoreboth') */
case 2:
{
HIST_ENTRY *temp;
using_history ();
temp = previous_history ();
if (!temp || (STREQ (temp->line, line) == 0))
bash_add_history (line);
using_history ();
}
break;
}
}
…あれ? この時点でもう行頭のスペースを特別扱いしている? 関連する部分も見ると
variable.c
/* Initialize the shell variables from the current environment. */
void
initialize_shell_variables (env)
char **env;
{
....
#if defined (HISTORY)
if (interactive_shell && remember_on_history)
{
sv_command_oriented_history ("command_oriented_history");
if (find_variable ("history_control"))
sv_history_control ("history_control"); /* gone in next release */
else
sv_history_control ("HISTCONTROL");
}
#endif /* HISTORY */
subst.c
/* What to do after the HISTORY_CONTROL variable changes. */
void
sv_history_control (name)
char *name;
{
char *temp = get_string_value (name);
history_control = 0;
if (temp && *temp)
{
if (strcmp (temp, "ignorespace") == 0)
history_control = 1;
else if (strcmp (temp, "ignoredups") == 0)
history_control = 2;
else if (strcmp (temp, "ignoreboth") == 0)
history_control = 3;
}
}
…すでにHISTORY_CONTROL
を見ている?
ああ、そうか2.05b→3.0で変わったのは
now a colon-separated list of values
の部分で、それ以前(1.14.7時点でも)からこの環境変数を見ていたということか。
zsh
zshは関連する変数がたくさんある。 zsh: 16 Options
が、今回の件に関係するのはこの辺か。
16.2.4 History
HIST_IGNORE_SPACE (-g)
Remove command lines from the history list when the first character on the line is a space, or when one of the expanded aliases contains a leading space. Only normal aliases (not global or suffix aliases) have this behaviour. Note that the command lingers in the internal history until the next command is entered before it vanishes, allowing you to briefly reuse or edit the line. If you want to make it vanish right away without entering another command, type a space and press return.
Src/hist.c
/* A helper function for hend() */
static int
should_ignore_line(Eprog prog)
{
if (isset(HISTIGNORESPACE)) {
if (*chline == ' ' || aliasspaceflag)
return 1;
}
/* say we're done using the history mechanism */
/**/
mod_export int
hend(Eprog prog)
{
int flag, hookret, stack_pos = histsave_stack_pos;
/*
* save:
* 0: don't save
* 1: save normally
* -1: save temporarily, delete after next line
* -2: save internally but mark for not writing
*/
...
if (hptr < chline + 1)
save = 0;
else {
if (hptr[-1] == '\n') {
if (chline[1]) {
*--hptr = '\0';
} else
save = 0;
}
if (chwordpos <= 2 && !hist_keep_comment)
save = 0;
else if (should_ignore_line(prog))
save = -1;
else if (hookret == 2)
save = -2;
else if (hookret)
save = -1;
}
fish
Interactive use - fish-shell 3.3.1 documentation
Searchable command history
After a command has been executed, it is remembered in the history list. Any duplicate history items are automatically removed.
省略….
Prefixing the commandline with a space will prevent the entire line from being stored in the history.
Searchable history
Prefixing the commandline with a space will prevent the entire line from being stored in the history.
コードは省略。
csh / tcsh / ksh
んで、さらにcsh、tcsh、kshも見てみたんだけど こいつらには話題の機能はない?
lex(hp)
register struct wordent *hp;
{
register struct wordent *wdp;
int c;
lineloc = btell();
hp->next = hp->prev = hp;
hp->word = "";
alvecp = 0, hadhist = 0;
do
c = readc(0);
while (c == ' ' || c == '\t');
if (c == '^' && intty)
/* ^lef^rit from tty is short !:s^lef^rit */
getexcl(c);
else
unreadc(c);
wdp = hp;
int
lex(struct wordent *hp)
{
struct wordent *wdp;
eChar c;
int parsehtime = enterhist;
int toolong = 0;
histvalid = 0;
histline.len = 0;
if (!postcmd_active)
btell(&lineloc);
initlex(hp);
hadhist = 0;
do
c = readc(0);
while (c == ' ' || c == '\t');
if (c == (eChar)HISTSUB && intty)
/* ^lef^rit from tty is short !:s^lef^rit */
getexcl(c);
else
unreadc(c);
cleanup_push(hp, lex_cleanup);
wdp = hp;
/*
case S_BLNK: {
if (lp->lex.incase <= TEST_RE) continue;
// Implicit RPAREN for =~ test operator.
if (inlevel + 1 == lp->lexd.level) {
if (lp->lex.intest) fcseek(-LEN);
c = RPAREN;
goto do_pop;
}
continue;
}
まあインストールできるものであればインストールして実行してみれば早いんだろうけど めんd(ry
- Disable history for the current session ・ Issue #2376 ・ fish-shell/fish-shell
- Ignoring certain file(s) in fish shell history - Stack Overflow
- Why is bash not storing commands that start with spaces? - Unix & Linux Stack Exchange
- fish shellでhistoryを使いこなす - Qiita
- bashのhistory機能では先頭にスペースがあるとそのコマンドは記録されない(設定による)
bashでコマンドの先頭にスペースを入れるとヒストリに残らないの、れっきとした機能だったことを知らなかった…。しかも連続して重複するコマンドをヒストリに残さない機能とあわせてHISTCONTROLという環境変数で制御可能だったなんて https://t.co/rpDYoKc4M4
— 専門性・売上・原稿 (@golden_lucky) February 24, 2022
最初にこの機能(仕様)を実装したのがなんなのかが気になるけど、 (多分最初にヒストリ機能を実装した)cshとその後続のtcshにはなかったようだ ということを考えるとやはりbashなんだろうか?
追記
面倒くささを乗り越えてインストールして(まあ sudo apt-get install tcsj
しただけだけど)
試してみたところ、やはりスペースを行頭においても通常通り
ヒストリに登録された。
find
findコマンドで検索したファイルを削除する方法の速度を比較してみた - Qiita という記事で
ただファイルを消すだけなら-deleteを使う。
-deleteが使えない環境なら-exec rm -f {} +を利用するのがよさそう。(使えない環境が存在するのかは不明)
というのを見て、 そんなサブコマンド(オプション)もあったのかと思いつつ参考リンクも辿ると、 findのdeleteオプションはマイナーなの? | トドの日記2.0 で
deleteオプションが存在しないfindというのは、多分2015年現在では絶滅したと考えていいように思います。
というのを見つけたので(ry
まずは Open Groupのページから見てみるが、やはり(?)見当たらない。
どちらでも
The following primaries shall be supported:
のあとに使えるオプション(というかコマンドというかのアレ)が並んでいるのだけど
-delete
なるものは見当たらない。
じゃあやっぱりGNU拡張あたりなんじゃあないかと
Findutilsのドキュメントを見ると(当然のように)あった。
10.1.6 Using the -delete action
The most efficient and secure method of solving this problem is to use the ‘-delete’ action:
find /var/tmp/stuff -mtime +90 -delete
This alternative is more efficient than any of the ‘-exec’ or ‘-execdir’ actions, since it entirely avoids the overhead of forking a new process and using exec to run /bin/rm. It is also normally more efficient than xargs for the same reason. The file deletion is performed from the directory containing the entry to be deleted, so the ‘-delete’ action has the same security advantages as the ‘-execdir’ action has.
The ‘-delete’ action was introduced by the BSD family of operating systems.
最後にintroduced by the BSD family
とあるので、macosでもふつ―に使えるんですかね
(「どのBSD」から入ったのかは調べない)。
であれば、まあ
deleteオプションが存在しないfindというのは、多分2015年現在では絶滅したと考えていいように思います。
という話にもなるのかな。と。
が
ふと思いついてAIXのドキュメントを見たけど、こいつに-delete
は見当たらないすな。