というのがはてな界隈にあるらしいのであとで見に行く予定は未定
13557024 journal nemui4の日記: 本当にあった find コマンドの怖い話 26 日記 by nemui4 2018年03月22日 7時59分 というのがはてな界隈にあるらしいのであとで見に行く予定は未定
これか? (スコア:1)
【謎】本当にあったfindコマンドの怖い話【おもしろ現象】
http://www.kunst1080.net/entry/2018/03/20/120146 [kunst1080.net]
要約
100万個のファイルに対して、find コマンドから始めて mv コマンドでファイル名を変更するワンライナーを実行すると、 mv コマンドが約158万回実行されました。
ワンライナーでやろうとしてハマった?
Re:これか? (スコア:2)
findを実行した時点でのファイルだけをmvしたかったのに、mvされたあとのファイルもfindに引っかかってしまった。
って、よくあるお話。
当然やんとしか思わない。
Re:これか? (スコア:1)
なるほど、そういうもんなんすね。
findはファイルのオーナー変更か古いファイルを削除するときに使うくらいでmvってやったことなかったです。
どっちも
ワンライナーにもこだわらないので、一旦リストファイルを生成してそれで次の処理をすることも多い。
#賢いワンライナーを書ける技量が無い・・・だけか
Re:これか? (スコア:2)
私は一番使うのはfind - grepですね。
#makefileには find . -type f -name '*~' -print0 | xargs -0 rm -fはかかれてて、よく使うけど。
;で区切って1lineでやるもよし。(shellのヒストリのため)
Re:これか? (スコア:1)
私も一番よく使うのはgrepですが、
% find . なんやかんか -print | xargs grep 条件1 | less
↓
% find . なんやかんか -print | xargs grep -l 条件1 | xargs grep 条件2 | less
…
と、どんどん絞り込むことが多いです。-0をつけなくても大丈夫な状況限定。
あと、ファイルそのものに何か手を入れる場合は、そのままxargsで繋がずに、
% foreach f ( `find . なんやかんか -print | xargs grep -l 条件1 | xargs grep -l 条件2` )
> perl -i.bak -pe ワンライナー $f
> end
って感じで、対象ファイル一覧を確定させてからコマンド実行してますね。
今となってはなぜそうすることにしたのかぜんぜん覚えてないんですが、たぶん今回のネタのような何か痛い目にあったことがあったんだと思う。
Re:これか? (スコア:2)
そういえば、grepの-lに--print0とかほしいなぁ。macosとか最近めんどさいファイル名多いし。
Re:これか? (スコア:1)
grep で "-l" なんて使ったことがなかった(存在知らなかった)
へー、含まれていないファイルを探すんですね。
ファイルに文字列含まれている前提で、文字列の有る行(レコード)を引っ張ることばっかりやってたのでそっちの発想はまるでなかった次第。
grepとかオプションもほとんど知らない機能が多すぎる。
awkやsedも定型的作業ででしか使ってないし、そんなに複雑なことしてないし。
イロイロわかると面白そうなのは重々承知・・・
だけどいつまでも頭が追いつかないまま年老いていきそう。
#スマホしか使わない世代からしたら「グレップなにそれ、オイシイの?」って言われそうな予感。
Re:これか? (スコア:1)
>オプションもほとんど知らない機能が多すぎる。
実機がスマホやスピーカーしか手元にない若い世代の人も
man grep
とウェブ検索すればコマンド使用前に確認できる世の中。
だからそれはそれで全然構わないと思う。
かけてよいコスト次第ですが。
Re:これか? (スコア:2)
そういえば、まんまfor f in $(find . なんたら -print) ; do mv $f $f.back ; doneって何度もやったことある。
#bash派です。
Re:これか? (スコア:1)
>そういえば、まんまfor f in $(find . なんたら -print) ; do mv $f $f.back ; doneって何度もやったことある
ちょうどさっき特定のlogファイルだけをアーカイブしようとして↑これを思い出したので
% for f in $(find . -type f -name "ほげ.180*" | grep -v ふが); do gzip $f; done
とやったらあっさり終わり。
これだと余計なtempファイルを残すこともないのですっきりしますね。
#普段決まった仕事ばかりやってるのであんまり頭使ってないのもあって知らなかった・・・
exp増えた、サンキューサー。
Re:これか? (スコア:1)
ログインシェルはtcsh派なんですが、tcshのforeachは中身がヒストリに残らないので、たまに
% sh -c 'for f in $(find . なんたら -print) ; do mv $f $f.back ; done'
とかやったりします。
#そこまでするぐらなら、とっととbashに乗り換えろよ、と自分でも思うのですが、20年以上使い込んだ.tcshrcが捨てられない…
Re:これか? (スコア:2)
> ログインシェルはtcsh派なんですが、tcshのforeachは中身がヒストリに残らないので
ですね。私もほぼ同じ理由でbashにうつりました。
だいたい、historyとreadlineのためにcshからtcshにしたんだから、historyに残らないとかtsch意味ないやんって。
Re:これか? (スコア:1)
foreach f ( `...` ) でいけるんですね、それいいな。
(たぶんよく知られてそうだけど知らなかった)
find . なんちゃら > list1
で一旦吐き出してからやってた。
便利だけどあとで消し忘れてごみになりやすい。
Re:これか? (スコア:1)
foreach でお手軽実現は
『UNIX C SHELLフィールドガイド』 [amazon.co.jp]
か類書のページをめくっていくとわりとすぐのあたりに載っていて真似した
という人が多いのではなかろうか?
Re:これか? (スコア:1)
お恥ずかしい話、実はその手の本はあまり読んだことがなかった。
shell scriot系は周りに聞いたり、軽くググって(浅い理解の元で)お手軽に使ってました。
1円(と送料)なら買ってみよう、紹介ありがとうございます。
#CGIとperlの入門書とリファレンスは仕事で必要になったときに読んでた。
Re:これか? (スコア:1)
c shell の本。だから今となってはそのまま真似しない良い部分が多々ある。
書籍コレクターを目指すんでなかったらbashとかzshとかtcsh寄りの記述の本
の方がいいですよ。
書き誤り orz (Was: Re:これか?) (スコア:1)
s/そのまま真似しない良い/そのまま真似しない方が良い/
Re:これか? (スコア:2)
この本読んで、一番思ったこと、
「c-shellでshell scriptを書くのはやめよう。(b|k|ba)shにしよう」
です。
まあ、login shellとしては(実際にはtcsh)は長く使いましたが。
Re:書き誤り orz (Was: Re:これか?) (スコア:1)
まぁ、基本方針を今更知るという方向で。
出先でもほとんど tcsh か bash でした。
たまにlogin shell が /bin/csh になってても /bin/tcsh へ link されてたり。
Re:これか? (スコア:1)
まだ会社のサーバーの中だと、csh基準で書かれている shell scriptが結構あります。
おそらく昔に書かれていて、それがモディファイされながら残ってるんだと思うけど、たまに記述内容がよくわからないのもあったりするので。
こちらでshibuyaさんに紹介してもらった本を読めば多少は理解進みそう。
プログラミングはしない(できない)ので、多少知ってるコマンドとスクリプトだけでなんとか仕事乗り切ってます。
Re:これか? (スコア:1)
ネット上で、C shellでスクリプトを書くべきではない、ってドキュメントを見た記憶があるんだけど、どこにあったっけ?
Re:これか? (スコア:1)
Csh Programming Considered Harmful [faqs.org]がそれでは?
日本語訳はhttp://www.speech-lab.org/~hiroki/csh-whynot.euc [speech-lab.org]など。
Re:これか? (スコア:1)
% find . なんやかんか -print | xargs grep 条件1 | less
この場合に「-print」を付ける意味ある?
Re:これか? (スコア:1)
言うほどよくある話ではない気がするけど。
FTS_MAX_READDIR_ENTRIES(既定では100,000)を超える数のファイルを対象にしたときに発生して、しかも発生するファイル数は一定ではない、ってわけでしょ?
ファイル数が多くても、複数ディレクトリにファイルが分散してる場合だとこの現象は発生しなさそうだし。
参考までに聞いときたいんだけど、どんな場合に発生したことがあるんですか?
Re:これか? (スコア:2)
つか、減る話はなんぼでもあるわけで、-depthオプションとかあることを考えるとfindがatomicでないことなんて自明でしょう。
まあ「よく」はないかもしれないけど、それは予想しておけって事ですね。
#大阪人は「まあ、ようある話」って「よう言います」から。ようしらんけど。
Re:これか? (スコア:1)
減る話はなんぼでもあるわけで
意味不明です。
-depthオプションとかあることを考えるとfindがatomicでないことなんて自明でしょう。
複数ディレクトリ間でアトミックでないのは自明だけど、
ディレクトリ内でアトミックでないことは、必ずしも自明じゃないでしょう。
なので、
findを実行した時点でのファイルだけをmvしたかったのに、mvされたあとのファイルもfindに引っかかってしまった。
って、よくあるお話。
は、ディレクトリ間でそういうことがあった、という違う話を、ディレクトリ内の話と混同したように見えます。
ディレクトリ内も非アトミックに実装されている可能性がある、
という意味で予測できる、と言うなら、確かにその通りですが、
経験したわけでも、コードレビューしたわけでもなければ、後知恵ですね。
仮に、その可能性を事前に考えていたとしても、
今回の検証で得られた知見は超えられてないですね。
FTS_MAX_READDIR_ENTRIESを一つでも超えれば発生する、というわけではないのだから。