ls -fやls -Uをもっと布教したい。

Tue Nov 12 00:15:44 JST 2013 (modified: Sun Oct 1 10:50:27 JST 2017)
views: 3367, keywords:コマンド,シェルスクリプト,ls,寝る この記事は最終更新日が7年以上前のものです。

皆さん、上田です。だからなんなんだ。なんなんでしょう?

この前のシェル芸勉強会で扱ったls -fおよびls -Uについて今一度周知徹底を。

lsはけしからんコマンドです。何がけしからんか。余計なことをしすぎです。例えば、普通にディレクトリをlsすると、次のようにファイル名を横に並べます。

ueda@remote:~/work$ ls
   agent calendar.tbl ip referer request status time

と出てきますが、これをパイプにつなげると、

ueda@remote:~/work$ ls | cat
   agent
   calendar.tbl
   ip
   referer
   request
   status
   time

と縦に出てきます。私はここらへんは詳しく無いですが、lsは出力か端末に何か変な細工をしているわけです。まあこれは分からんでもありません。他のコマンドに通せば細工は消えるようですし。

そして、こっちの方が問題だと思うのですが、lsはファイル名を出力するときに、頼みもしないのにソートしくさります。これも端末で人が使うならば分かる気もしますが、ディレクトリにファイルがたくさんある場合に初心者を苦しめます。100万個ファイルを作ってlsしてみましょう。

ueda@remote:~/tmp$ seq 1 1000000 | xargs touch
   ueda@remote:~/tmp$ ls
   ^C

これ、Ctrl+cやってもなかなか返ってきません。ファイルシステムが絡むとすぐ中断できないことがあるのです。

ちなみにちゃんと最後までやると39秒もかかります(Ubuntu 12.04 on さくらのVPS 1G)。いや、昔なら終わらなかったので39秒で終わるの凄いというところですが・・・。

ueda@remote:~/tmp$ time ls 
   (中略)
   189997 279997 369997 459997 549997 639997 729997 819997 909997 999998
   189998 279998 369998 459998 549998 639998 729998 819998 909998 999999
   
   real    0m39.805s
   user    0m9.233s
   sys 0m11.809s

ディレクトリにファイルがたくさんある状態が、すでにあまりよい状態ではありませんが、いつもUNIXを弄っているような現場だと結構あります。さてどうしたものか。

もったいぶらないでさっさと答えを言うと、まず、lsの結果をファイルに出力すると速くなります。端末に表示する方は、別に表示に手間取っているわけではありません。それにしては時間がかかり過ぎです。

ueda@remote:~/tmp$ time ls > ~/output
   
   real    0m6.474s
   user    0m5.976s
   sys 0m0.496s

出力先が端末とファイルの場合で挙動が変わるなんて最低です。

さらに速くしたいときは、ls -fかls -Uです。これでソートが切れます。ls -fだと「.」と「..」も出力されます。 ls -Uだと「.」と「..」は出力されません。

ueda@remote:~/tmp$ time ls -f > ~/output
   
   real    0m0.620s
   user    0m0.264s
   sys 0m0.344s
   ueda@remote:~/tmp$ head ~/output 
   .
   ..
   90682
   691133
   935660
   814634
   45905
   682037
   89898
   51703
   ueda@remote:~/tmp$ time ls -U > ~/output
   
   real    0m0.605s
   user    0m0.248s
   sys 0m0.352s
   ueda@remote:~/tmp$ head ~/output
   90682
   691133
   935660
   814634
   45905
   682037
   89898
   51703
   275023
   594034

ソートしたけりゃsortすればいいんです。

ueda@remote:~/tmp$ time ls -U | LANG=C sort > ~/output
   
   real    0m1.331s
   user    0m1.068s
   sys 0m0.380s

なんだかls -fよりls -Uの方が使い勝手がよさそうですが、ところがどっこい、端末上ではls -Uは遅いので注意してください

ueda@remote:~/tmp$ time ls -U
   ...
   766920 230084 666666 934457 725634 803393 94237 773567 592212 504359
   362385 42211 614482 679702 127511 10382 897892 247139 228008 763314
   
   real    1m25.614s
   user    0m3.112s
   sys 0m12.073s
   ueda@remote:~/tmp$ time ls -f
   ...
   766920 42211 224326 380819 90130 876036 702813 845513 559273
   
   real    0m16.343s
   user    0m1.300s
   sys 0m1.016s

こういう挙動不審のコマンドはあまりよろしくありません。

寝る。

ノート   このエントリーをはてなブックマークに追加 
 

prev:東雲橋から next:完全に俳句な件。

やり散らかし一覧

記事いろいろ