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

Pocket
LINEで送る

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

この前のシェル芸勉強会で扱った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

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

寝る。

Pocket
LINEで送る