オプションは、rauth1に対応で。
ファイルのパーミションは、PHPマニュアルをそのままコピペしたんだけど、手元だとシンボリックリンクがうまく出ない・・・・。
うーん、意外と面倒・・・・。つかコード長いし。
Ref:
最小限のls -laを書いてみた - Islands in the byte stream
404 Blog Not Found:perl - 勝手に添削 - 最小限のls -laを書いてみた
<?php require_once 'Console/Getopt.php'; $shortoptions = "l|a|t|r|u|h|1"; $longoptions = array(''); $options = Console_Getopt::getopt($_SERVER['argv'], $shortoptions, $longoptions); if (is_a($opts, 'PEAR_Error')){ error_log(sprintf("invalid option. %s", $opts->getMessage())); exit(); } $opts = array(); foreach ($options[0] as $o){ $opts[$o[0]] = $o[1]; } $glob_exp = '*'; if ($options[1]){ $target = $options[1][0]; if (!file_exists($target)){ error_log(sprintf("ls: %s: No such file or directory", $target)); exit(); } if (is_dir($target)){ chdir($target); } else if (is_file($target)){ $glob_exp = $target; if (in_array('a', array_keys($opts))){ unset($opts['a']); } } } $files = array(); $padding = array( 'nlink' => 0, 'user' => 0, 'group' => 0, 'size' => 0, ); $glob = glob($glob_exp); if (in_array('a', array_keys($opts))){ $glob = array_merge($glob, glob('.*')); } foreach ($glob as $file){ $key = $file; $stat = lstat($file); if (in_array('u', array_keys($opts))){ $key = $stat['atime']; } else if (in_array('t', array_keys($opts))){ $key = $stat['mtime']; } $stat['user'] = posix_getpwuid($stat['uid']); $stat['group'] = posix_getgrgid($stat['gid']); $stat['fmode'] = fmode($file); $stat['filename'] = $file . (is_dir($file) ? '/' : ''); if (in_array('h', array_keys($opts))){ $stat['size'] = fsize($stat['size']); } $files[$key] = $stat; if ($padding['user'] < strlen($stat['user']['name'])){ $padding['user'] = strlen($stat['user']['name']); } if ($padding['group'] < strlen($stat['group']['name'])){ $padding['group'] = strlen($stat['group']['name']); } if ($padding['size'] < strlen(strval($stat['size']))){ $padding['size'] = strlen(strval($stat['size'])); } if ($padding['nlink'] < strlen(strval($stat['nlink']))){ $padding['nlink'] = strlen(strval($stat['nlink'])); } } $sort_method = in_array('r', array_keys($opts)) ? 'ksort' : 'krsort'; $sort_method($files); $formats = array( 'short' => "%s\t", 'short1' => "%s\n", 'long' => "%s %{$padding['nlink']}s %-{$padding['user']}s %-{$padding['group']}s %{$padding['size']}s %s %5s %s\n" ); $now = time(); foreach ($files as $f) { if (in_array('l', array_keys($opts))){ $params = array($formats['long'], $f['fmode'], $f['nlink'], $f['user']['name'], $f['group']['name'], $f['size'], date('m-d', $f['mtime']), date( ($f['mtime'] > $now -86400*365 ? 'H:i' : 'Y'), $f['mtime']), $f['filename'], ); } else if (in_array('1', array_keys($opts))){ $params = array( $formats['short1'], $f['filename'] ); } else { $params = array( $formats['short'], $f['filename'] ); } call_user_func_array('printf', $params); } if (!in_array('l', array_keys($opts)) && !in_array('1', array_keys($opts))){ echo "\n"; } /** * @brief filemode * @param int filesize * @retval string filesize */ function fmode($file) { $info = ''; $perms = fileperms($file); if (($perms & 0xC000) == 0xC000) { // ソケット $info = 's'; } elseif (($perms & 0xA000) == 0xA000) { // シンボリックリンク $info = 'l'; } elseif (($perms & 0x8000) == 0x8000) { // 通常のファイル $info = '-'; } elseif (($perms & 0x6000) == 0x6000) { // ブロックスペシャルファイル $info = 'b'; } elseif (($perms & 0x4000) == 0x4000) { // ディレクトリ $info = 'd'; } elseif (($perms & 0x2000) == 0x2000) { // キャラクタスペシャルファイル $info = 'c'; } elseif (($perms & 0x1000) == 0x1000) { // FIFO パイプ $info = 'p'; } else { // 不明 $info = 'u'; } // 所有者 $info .= (($perms & 0x0100) ? 'r' : '-'); $info .= (($perms & 0x0080) ? 'w' : '-'); $info .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x' ) : (($perms & 0x0800) ? 'S' : '-')); // グループ $info .= (($perms & 0x0020) ? 'r' : '-'); $info .= (($perms & 0x0010) ? 'w' : '-'); $info .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x' ) : (($perms & 0x0400) ? 'S' : '-')); // 全体 $info .= (($perms & 0x0004) ? 'r' : '-'); $info .= (($perms & 0x0002) ? 'w' : '-'); $info .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x' ) : (($perms & 0x0200) ? 'T' : '-')); return $info; } /** * @brief filesizeを見やすく * @param int filesize * @retval string filesize */ function fsize($string) { $size = intval($string); $unit = ""; $units = array( 1 => "", 1000 => "K", 1000000 => "M", 1000000000 => "G", 1000000000000 => "T", ); foreach ($units as $key=>$value){ if ($size/$key<1000){ $s = sprintf("%f", $size/$key); return trim(substr($s, 0, 3),".") . $value; break; } } return $string; }
[itoh@testserver test]$ php ~/work/ls.php -alth drwxr-xr-x 32 smbuser smbuser 4.0K 05-17 12:08 ../ drwxr-xr-x 6 smbuser smbuser 4.0K 03-24 13:59 ./ drwxrwxr-x 2 smbuser smbuser 4.0K 03-24 12:43 ab/ -rw-r--r-- 1 smbuser smbuser 59 03-08 17:56 index.php -rw-rw-r-- 1 smbuser smbuser 11K 01-10 12:57 40745_.jpg -rw-r--r-- 1 smbuser smbuser 671 01-10 12:56 jpeg_progressve_checker.php -rw-r--r-- 1 smbuser smbuser 10K 01-10 12:03 40745.jpg -rw-rw-r-- 1 smbuser smbuser 10K 01-05 20:51 44165.jpg -rw-rw-r-- 1 smbuser smbuser 58 12-01 22:01 createdb.sql drwxrwxr-x 2 smbuser smbuser 4.0K 10-28 12:32 tmp/ -rw-r--r-- 1 smbuser smbuser 80 10-28 12:32 smarty_test.tpl -rw-r--r-- 1 smbuser smbuser 494 10-28 12:32 smarty.php -rw-rw-r-- 1 smbuser smbuser 35 10-28 12:21 dump -rw-r--r-- 1 smbuser smbuser 1.1K 10-22 2009 test.php -rw-r--r-- 1 smbuser smbuser 677 10-21 2009 create_serial_num.sql -rw-r--r-- 1 smbuser smbuser 263 10-21 2009 create_serial_num.table.sql -rw-r--r-- 1 smbuser smbuser 351 10-21 2009 create_serial_num.php -rw-r--r-- 1 smbuser smbuser 135 07-21 2009 at_include.php -rw-r--r-- 1 smbuser smbuser 612 07-21 2009 vars.inc.php -rw-r--r-- 1 smbuser smbuser 6.1K 03-31 2009 .DS_Store -rwx------ 1 smbuser smbuser 599 11-05 2008 get.sh [itoh@testserver test]$ ls -alth 合計 124K drwxr-xr-x 32 smbuser smbuser 4.0K 5月 17 12:08 .. drwxr-xr-x 6 smbuser smbuser 4.0K 3月 24 13:59 . drwxrwxr-x 2 smbuser smbuser 4.0K 3月 24 12:43 ab -rw-r--r-- 1 smbuser smbuser 59 3月 8 17:56 index.php -rw-rw-r-- 1 smbuser smbuser 12K 1月 10 12:57 40745_.jpg -rw-r--r-- 1 smbuser smbuser 671 1月 10 12:56 jpeg_progressve_checker.php -rw-r--r-- 1 smbuser smbuser 11K 1月 10 12:03 40745.jpg -rw-rw-r-- 1 smbuser smbuser 11K 1月 5 20:51 44165.jpg -rw-rw-r-- 1 smbuser smbuser 58 12月 1 22:01 createdb.sql drwxrwxr-x 2 smbuser smbuser 4.0K 10月 28 2010 tmp -rw-r--r-- 1 smbuser smbuser 80 10月 28 2010 smarty_test.tpl -rw-r--r-- 1 smbuser smbuser 494 10月 28 2010 smarty.php -rw-rw-r-- 1 smbuser smbuser 35 10月 28 2010 dump -rw-r--r-- 1 smbuser smbuser 1.1K 10月 22 2009 test.php -rw-r--r-- 1 smbuser smbuser 677 10月 21 2009 create_serial_num.sql -rw-r--r-- 1 smbuser smbuser 263 10月 21 2009 create_serial_num.table.sql -rw-r--r-- 1 smbuser smbuser 351 10月 21 2009 create_serial_num.php -rw-r--r-- 1 smbuser smbuser 135 7月 21 2009 at_include.php -rw-r--r-- 1 smbuser smbuser 612 7月 21 2009 vars.inc.php -rw-r--r-- 1 smbuser smbuser 6.1K 3月 31 2009 .DS_Store -rwx------ 1 smbuser smbuser 599 11月 5 2008 get.sh
うーん、こんなもんかな。