ls -fやls -Uをもっと布教したい。
Tue Nov 12 00:15:44 JST 2013 (modified: Sun Oct 1 10:50:27 JST 2017)
views: 3684, 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
こういう挙動不審のコマンドはあまりよろしくありません。
寝る。