From 161055c4087cb3dba487661d003089cb2aa19871 Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Thu, 13 Jun 2024 16:58:18 +0900 Subject: [PATCH 01/23] =?UTF-8?q?add:=20optparse=E3=82=92=E5=AE=9A?= =?UTF-8?q?=E7=BE=A9=E3=80=81l=E3=82=AA=E3=83=97=E3=82=B7=E3=83=A7?= =?UTF-8?q?=E3=83=B3=E3=82=92=E8=AA=AD=E3=81=BF=E8=BE=BC=E3=82=81=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 04.ls/ls.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index 6b1cfd48e4..083690e5f2 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -1,10 +1,15 @@ #!/usr/bin/env ruby # frozen_string_literal: true +require 'optparse' + MAX_CHUNK = 3 TAB_SPACE = 8 -file_paths = Dir.entries('.') +file_paths = Dir.entries('.').sort + +opt = OptionParser.new +params = opt.getopts(ARGV, 'l') def except_hidden_file(file_paths) file_paths.reject { |element| element[0] == '.' } @@ -21,7 +26,6 @@ def transpose_chunks(sliced_paths, num_rows) padded_slices.transpose.map(&:compact) end -file_paths = file_paths.sort file_paths = except_hidden_file(file_paths) num_rows = (file_paths.size.to_f / MAX_CHUNK).ceil From aac37f66b256f11531113d059b0be29667095c94 Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Mon, 17 Jun 2024 10:52:56 +0900 Subject: [PATCH 02/23] change: params -> options --- 04.ls/ls.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index 083690e5f2..03b03691ce 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -9,7 +9,7 @@ file_paths = Dir.entries('.').sort opt = OptionParser.new -params = opt.getopts(ARGV, 'l') +options = opt.getopts(ARGV, 'l') def except_hidden_file(file_paths) file_paths.reject { |element| element[0] == '.' } From e2dc4f70b062959902ac9ed76239fe89f69bc82c Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Mon, 17 Jun 2024 10:53:56 +0900 Subject: [PATCH 03/23] =?UTF-8?q?add:=20l=E3=82=AA=E3=83=97=E3=82=B7?= =?UTF-8?q?=E3=83=A7=E3=83=B3=E3=81=8C=E6=8C=87=E5=AE=9A=E3=81=95=E3=82=8C?= =?UTF-8?q?=E3=81=9F=E6=99=82=E3=81=AE=E5=88=86=E5=B2=90=E3=81=A8=E3=81=AA?= =?UTF-8?q?=E3=82=8Bif=E6=96=87=E3=82=92=E3=81=B2=E3=81=A8=E3=81=BE?= =?UTF-8?q?=E3=81=9A=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 04.ls/ls.rb | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index 03b03691ce..9cf0ef54a2 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -28,17 +28,21 @@ def transpose_chunks(sliced_paths, num_rows) file_paths = except_hidden_file(file_paths) -num_rows = (file_paths.size.to_f / MAX_CHUNK).ceil -sliced_paths = chunk_file_paths(file_paths, num_rows) -shaped_file_paths_array = transpose_chunks(sliced_paths, num_rows) - -max_string_length = file_paths.map(&:length).max - -shaped_file_paths_array.each do |array_element| - array_element.each do |element| - tab_count = ((max_string_length - element.length) / TAB_SPACE.to_f).ceil + 1 # タブの挿入する回数を計算 - print element - print "\t" * tab_count +if options['l'] + p 'l' +else + num_rows = (file_paths.size.to_f / MAX_CHUNK).ceil + sliced_paths = chunk_file_paths(file_paths, num_rows) + shaped_file_paths_array = transpose_chunks(sliced_paths, num_rows) + + max_string_length = file_paths.map(&:length).max + + shaped_file_paths_array.each do |array_element| + array_element.each do |element| + tab_count = ((max_string_length - element.length) / TAB_SPACE.to_f).ceil + 1 # タブの挿入する回数を計算 + print element + print "\t" * tab_count + end + puts end - puts end From ff05df0dd2e623ce3767bd8c5d349afa011a12cb Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Mon, 17 Jun 2024 11:00:00 +0900 Subject: [PATCH 04/23] =?UTF-8?q?change:=209~12=E8=A1=8C=E7=9B=AE=E3=82=92?= =?UTF-8?q?=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E3=81=AE=E4=B8=8B=E3=81=AB?= =?UTF-8?q?=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 04.ls/ls.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index 9cf0ef54a2..cddc5bb4ac 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -6,11 +6,6 @@ MAX_CHUNK = 3 TAB_SPACE = 8 -file_paths = Dir.entries('.').sort - -opt = OptionParser.new -options = opt.getopts(ARGV, 'l') - def except_hidden_file(file_paths) file_paths.reject { |element| element[0] == '.' } end @@ -26,6 +21,11 @@ def transpose_chunks(sliced_paths, num_rows) padded_slices.transpose.map(&:compact) end +file_paths = Dir.entries('.').sort + +opt = OptionParser.new +options = opt.getopts(ARGV, 'l') + file_paths = except_hidden_file(file_paths) if options['l'] From dfa39575ef76251ad4b6f49d69696d9fde89e011 Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Mon, 17 Jun 2024 12:14:35 +0900 Subject: [PATCH 05/23] =?UTF-8?q?define:=20FILE=5FTYPE,=20FILE=5FMODE?= =?UTF-8?q?=E3=82=92=E5=AE=9A=E7=BE=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 04.ls/ls.rb | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index cddc5bb4ac..37f3c352d0 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -6,6 +6,27 @@ MAX_CHUNK = 3 TAB_SPACE = 8 +FILE_TYPE = { + 'fifo' => 'p', + 'characterSpecial' => 'c', + 'directory' => 'd', + 'blockSpecial' => 'b', + 'file' => 'f', + 'link' => 'l', + 'socket' => 's' +}.freeze + +FILE_MODE = { + '0' => '---', + '1' => '--x', + '2' => '-w-', + '3' => '-wx', + '4' => 'r--', + '5' => 'r-x', + '6' => 'rw-', + '7' => 'rwx' +}.freeze + def except_hidden_file(file_paths) file_paths.reject { |element| element[0] == '.' } end From 867e38aca0e58d87286986014cff39ad296d12ad Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Mon, 17 Jun 2024 12:16:16 +0900 Subject: [PATCH 06/23] define: require 'etc' --- 04.ls/ls.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index 37f3c352d0..d1916fcc8c 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -2,6 +2,7 @@ # frozen_string_literal: true require 'optparse' +require 'etc' MAX_CHUNK = 3 TAB_SPACE = 8 From 38942f2647f48a18b4c9c7a50dfcc17869a85e48 Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Mon, 17 Jun 2024 12:17:16 +0900 Subject: [PATCH 07/23] =?UTF-8?q?add:=208=E9=80=B2=E6=95=B0=E3=81=AE?= =?UTF-8?q?=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E3=83=A2=E3=83=BC=E3=83=89?= =?UTF-8?q?=E3=82=92=E6=A0=BC=E7=B4=8D=E3=81=99=E3=82=8B=E5=A4=89=E6=95=B0?= =?UTF-8?q?file=5Fmode=5Factal=E3=82=92=E5=AE=9A=E7=BE=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 04.ls/ls.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index d1916fcc8c..d9096fc55e 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -51,7 +51,10 @@ def transpose_chunks(sliced_paths, num_rows) file_paths = except_hidden_file(file_paths) if options['l'] - p 'l' + file_paths.each do |file_path| + file_stat = File.lstat(file_path) + file_mode_octal = file_stat.mode.to_s(8).rjust(6, '0') + end else num_rows = (file_paths.size.to_f / MAX_CHUNK).ceil sliced_paths = chunk_file_paths(file_paths, num_rows) From 5ae357c09f9fd535ce85f0c7f934f438e95f08a3 Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Mon, 17 Jun 2024 12:35:04 +0900 Subject: [PATCH 08/23] =?UTF-8?q?add:=20nlink,=20uid,=20gid,=20size,=20mti?= =?UTF-8?q?me=E3=82=92=E5=8F=96=E5=BE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 04.ls/ls.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index d9096fc55e..b6dd29a1f0 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -54,6 +54,13 @@ def transpose_chunks(sliced_paths, num_rows) file_paths.each do |file_path| file_stat = File.lstat(file_path) file_mode_octal = file_stat.mode.to_s(8).rjust(6, '0') + nlink = file_stat.nlink + uid = Etc.getpwuid(file_stat.uid).name + gid = Etc.getgrgid(file_stat.gid).name + size = file_stat.size + mtime = file_stat.mtime.strftime('%-m %d %H:%M') + + puts "#{file_mode}\t#{nlink}\t#{uid}\t#{gid}\t#{size}\t#{mtime}\t#{file_path}" end else num_rows = (file_paths.size.to_f / MAX_CHUNK).ceil From e3af6bfef0b39470e8cd6b5cefd9ce3005fb5355 Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Mon, 17 Jun 2024 12:59:48 +0900 Subject: [PATCH 09/23] =?UTF-8?q?add:=20=E8=A1=A8=E7=A4=BA=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E3=83=A2=E3=83=BC?= =?UTF-8?q?=E3=83=89=E3=81=AE=E6=96=87=E5=AD=97=E5=88=97=E3=82=92=E4=BD=9C?= =?UTF-8?q?=E6=88=90=E3=81=99=E3=82=8B=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89?= =?UTF-8?q?convert=5Ffile=5Fmode=E3=82=92=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 8進数に変換したファイルモードの数値列から、lsコマンドで表示する文字列形式に変換するメソッド - ファイルの種類はfile_mode.ftypeから取得し、予め作成しているFILE_TYPEのhashから対応する文字をとってくる - ファイルの読み書き権限などは8進数数値列の4~6番目が対応しているため、その部分を取り出してFILE_MODEのhashから対応する文字列を取得した --- 04.ls/ls.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index b6dd29a1f0..69c4d32964 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -43,6 +43,13 @@ def transpose_chunks(sliced_paths, num_rows) padded_slices.transpose.map(&:compact) end +def convert_file_mode(file_stat) + file_mode_octal = file_stat.mode.to_s(8).rjust(6, '0') + file_mode = FILE_TYPE[file_stat.ftype].to_s + file_permissions = file_mode_octal.slice(3..-1).chars.map { |char| FILE_MODE[char] }.join + file_mode + file_permissions +end + file_paths = Dir.entries('.').sort opt = OptionParser.new @@ -53,7 +60,7 @@ def transpose_chunks(sliced_paths, num_rows) if options['l'] file_paths.each do |file_path| file_stat = File.lstat(file_path) - file_mode_octal = file_stat.mode.to_s(8).rjust(6, '0') + file_mode = convert_file_mode(file_stat) nlink = file_stat.nlink uid = Etc.getpwuid(file_stat.uid).name gid = Etc.getgrgid(file_stat.gid).name From 4bde95912848e54544e268803f1aca658df977e9 Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Mon, 17 Jun 2024 13:08:05 +0900 Subject: [PATCH 10/23] =?UTF-8?q?add:=20=E3=83=95=E3=82=A1=E3=82=A4?= =?UTF-8?q?=E3=83=AB=E3=81=AE=E7=B7=8F=E3=82=B5=E3=82=A4=E3=82=BA=E3=81=AE?= =?UTF-8?q?=E8=A1=A8=E7=A4=BA=E9=83=A8=E5=88=86total=E3=81=AE=E4=BD=9C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 04.ls/ls.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index 69c4d32964..c4cc037a10 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -58,6 +58,9 @@ def convert_file_mode(file_stat) file_paths = except_hidden_file(file_paths) if options['l'] + total_blocks = file_paths.sum { |file_path| File.lstat(file_path).blocks } + puts "total #{total_blocks}" + file_paths.each do |file_path| file_stat = File.lstat(file_path) file_mode = convert_file_mode(file_stat) From 08fcb9ad5f0ef96aca75b87a067f134139288faa Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Mon, 17 Jun 2024 13:46:08 +0900 Subject: [PATCH 11/23] =?UTF-8?q?add:=20=E3=83=95=E3=82=A1=E3=82=A4?= =?UTF-8?q?=E3=83=AB=E3=81=AE=E7=89=B9=E6=AE=8A=E6=A8=A9=E9=99=90=E3=82=92?= =?UTF-8?q?=E7=A2=BA=E8=AA=8D=E3=81=99=E3=82=8B=E3=83=A1=E3=82=BD=E3=83=83?= =?UTF-8?q?=E3=83=89apply=5Fspecial=5Fmode=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ファイルモードの書き換えを実行するために、SPECIAL_MODEを作成、置き換える文字を定義 置き換えが発生するかどうかは8進数変換した場合の3文字目に存在するため、そこが'0'であればこの処理は実行されない --- 04.ls/ls.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index c4cc037a10..0b1d8bbc70 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -28,6 +28,12 @@ '7' => 'rwx' }.freeze +SPECIAL_MODE = [ + { bit: '4', index: 2, exec: 's', no_exec: 'S' }, + { bit: '2', index: 5, exec: 's', no_exec: 'S' }, + { bit: '1', index: 8, exec: 't', no_exec: 'T' } +].freeze + def except_hidden_file(file_paths) file_paths.reject { |element| element[0] == '.' } end @@ -47,9 +53,20 @@ def convert_file_mode(file_stat) file_mode_octal = file_stat.mode.to_s(8).rjust(6, '0') file_mode = FILE_TYPE[file_stat.ftype].to_s file_permissions = file_mode_octal.slice(3..-1).chars.map { |char| FILE_MODE[char] }.join + # 特殊権限の確認 + file_permissions = apply_special_modes(file_mode_octal[2], file_permissions) if file_mode_octal[2] != '0' file_mode + file_permissions end +def apply_special_modes(special_modes, permissions) + SPECIAL_MODE.each do |mode| + if special_modes == mode[:bit] + permissions[mode[:index]] == 'x' ? mode[:exec] : mode[:no_exec] + end + end + permissions +end + file_paths = Dir.entries('.').sort opt = OptionParser.new From fdfadeccf36894d2b436693a1d5f3de6bf81bc90 Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Mon, 17 Jun 2024 13:59:20 +0900 Subject: [PATCH 12/23] =?UTF-8?q?add:=20=E4=BA=88=E3=82=81=E8=A1=A8?= =?UTF-8?q?=E7=A4=BA=E3=81=99=E3=82=8B=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB?= =?UTF-8?q?=E3=83=A2=E3=83=BC=E3=83=89=E3=82=92hash=E3=81=AB=E6=A0=BC?= =?UTF-8?q?=E7=B4=8D=E3=81=99=E3=82=8B=E3=81=9F=E3=82=81=E3=81=AB=E3=83=A1?= =?UTF-8?q?=E3=82=BD=E3=83=83=E3=83=89format=5Ffile=5Fmode=E3=82=92?= =?UTF-8?q?=E5=AE=9A=E7=BE=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit map関数でfile_pathひとつを送り、返り血としてファイルモードの情報を得る --- 04.ls/ls.rb | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index 0b1d8bbc70..31bb06cb8c 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -67,6 +67,19 @@ def apply_special_modes(special_modes, permissions) permissions end +def format_file_mode(file_path) + file_stat = File.lstat(file_path) + { + file_mode: convert_file_mode(file_stat), + nlink: file_stat.nlink, + uid: Etc.getpwuid(file_stat.uid).name, + gid: Etc.getgrgid(file_stat.gid).name, + size: file_stat.size, + mtime: file_stat.mtime.strftime('%-m %d %H:%M'), + blocks: file_stat.blocks + } +end + file_paths = Dir.entries('.').sort opt = OptionParser.new @@ -75,7 +88,9 @@ def apply_special_modes(special_modes, permissions) file_paths = except_hidden_file(file_paths) if options['l'] - total_blocks = file_paths.sum { |file_path| File.lstat(file_path).blocks } + file_modes = file_paths.map { |file_path| format_file_mode(file_path) } + total_blocks = file_modes.map { |file_mode| file_mode[:blocks] }.sum + puts "total #{total_blocks}" file_paths.each do |file_path| From 241960a5ff2315380b8cf398423193bf2d1e3708 Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Mon, 17 Jun 2024 14:25:39 +0900 Subject: [PATCH 13/23] =?UTF-8?q?fix:=20format=5Ffile=5Fmode=E3=81=A7?= =?UTF-8?q?=E6=A0=BC=E7=B4=8D=E3=81=99=E3=82=8B=E6=96=87=E5=AD=97=E5=88=97?= =?UTF-8?q?=E3=81=AE=E7=B4=B0=E3=81=8B=E3=81=AA=E5=9E=8B=E3=81=AE=E5=A4=89?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 04.ls/ls.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index 31bb06cb8c..7548e42679 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -71,11 +71,12 @@ def format_file_mode(file_path) file_stat = File.lstat(file_path) { file_mode: convert_file_mode(file_stat), - nlink: file_stat.nlink, + nlink: file_stat.nlink.to_s, uid: Etc.getpwuid(file_stat.uid).name, gid: Etc.getgrgid(file_stat.gid).name, - size: file_stat.size, + size: file_stat.size.to_s, mtime: file_stat.mtime.strftime('%-m %d %H:%M'), + file_path: file_path, blocks: file_stat.blocks } end From 6757bafb33c4af05e235f077a434e0970fde093c Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Mon, 17 Jun 2024 14:27:02 +0900 Subject: [PATCH 14/23] =?UTF-8?q?define:=20=E3=83=95=E3=82=A1=E3=82=A4?= =?UTF-8?q?=E3=83=AB=E6=83=85=E5=A0=B1=E3=81=AE=E6=9C=80=E5=A4=A7=E3=81=AE?= =?UTF-8?q?=E6=96=87=E5=AD=97=E6=95=B0=E3=82=92=E5=8F=96=E5=BE=97=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89calculate=5Fmax=5F?= =?UTF-8?q?string=5Fmodes=E3=82=92=E5=AE=9A=E7=BE=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 04.ls/ls.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index 7548e42679..bcffecc56a 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -81,6 +81,16 @@ def format_file_mode(file_path) } end +def calclate_max_string_modes(file_modes) + { + nlink: file_modes.map { |file_mode| file_mode[:nlink].size }.max, + uid: file_modes.map { |file_mode| file_mode[:uid].size }.max, + gid: file_modes.map { |file_mode| file_mode[:gid].size }.max, + size: file_modes.map { |file_mode| file_mode[:size].size }.max, + mtime: file_modes.map { |file_mode| file_mode[:mtime].size }.max + } +end + file_paths = Dir.entries('.').sort opt = OptionParser.new @@ -104,6 +114,7 @@ def format_file_mode(file_path) mtime = file_stat.mtime.strftime('%-m %d %H:%M') puts "#{file_mode}\t#{nlink}\t#{uid}\t#{gid}\t#{size}\t#{mtime}\t#{file_path}" + max_string_modes = calclate_max_string_modes(file_modes) end else num_rows = (file_paths.size.to_f / MAX_CHUNK).ceil From 8cc5450f8f2550f919203fc2aff8ebc27f0c8957 Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Mon, 17 Jun 2024 14:27:57 +0900 Subject: [PATCH 15/23] =?UTF-8?q?change:=20format=5Ffile=5Fmode=E3=81=A7?= =?UTF-8?q?=E6=B1=82=E3=82=81=E3=81=9F=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB?= =?UTF-8?q?=E6=83=85=E5=A0=B1=E3=82=92=E4=BD=BF=E7=94=A8=E3=81=97=E3=81=A6?= =?UTF-8?q?=E6=96=87=E5=AD=97=E3=81=AE=E5=87=BA=E5=8A=9B=E3=82=92=E5=AE=9F?= =?UTF-8?q?=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 04.ls/ls.rb | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index bcffecc56a..d2c56bb226 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -104,17 +104,19 @@ def calclate_max_string_modes(file_modes) puts "total #{total_blocks}" - file_paths.each do |file_path| - file_stat = File.lstat(file_path) - file_mode = convert_file_mode(file_stat) - nlink = file_stat.nlink - uid = Etc.getpwuid(file_stat.uid).name - gid = Etc.getgrgid(file_stat.gid).name - size = file_stat.size - mtime = file_stat.mtime.strftime('%-m %d %H:%M') - - puts "#{file_mode}\t#{nlink}\t#{uid}\t#{gid}\t#{size}\t#{mtime}\t#{file_path}" max_string_modes = calclate_max_string_modes(file_modes) + file_modes.each do |file_mode| + file_mode_print = [ + file_mode[:file_mode], + file_mode[:nlink].rjust(max_string_modes[:nlink]), + file_mode[:uid].ljust(max_string_modes[:uid]), + '', + file_mode[:gid].ljust(max_string_modes[:gid]), + file_mode[:size].rjust(max_string_modes[:size]), + file_mode[:mtime].ljust(max_string_modes[:mtime]), + file_mode[:file_path] + ].join(' ') + puts file_mode_print end else num_rows = (file_paths.size.to_f / MAX_CHUNK).ceil From f6df87eca96d7bf9ab8cdde65b13bfa6ff867c66 Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Mon, 17 Jun 2024 14:39:08 +0900 Subject: [PATCH 16/23] =?UTF-8?q?fix:=20=E5=90=8C=E4=B8=80=E5=90=8D?= =?UTF-8?q?=E3=81=AEhash=E3=82=92=E7=9C=81=E7=95=A5=E8=A8=98=E6=B3=95?= =?UTF-8?q?=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 04.ls/ls.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index d2c56bb226..bd93b5dcc3 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -76,7 +76,7 @@ def format_file_mode(file_path) gid: Etc.getgrgid(file_stat.gid).name, size: file_stat.size.to_s, mtime: file_stat.mtime.strftime('%-m %d %H:%M'), - file_path: file_path, + file_path:, blocks: file_stat.blocks } end From 44cdd4b2bf4e63ae14b8be6c9149f79f8411c8da Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Mon, 17 Jun 2024 14:46:35 +0900 Subject: [PATCH 17/23] =?UTF-8?q?change:=20=E7=A9=BA=E7=99=BD=E5=9F=8B?= =?UTF-8?q?=E3=82=81=E3=81=AE=E8=AA=BF=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 04.ls/ls.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index bd93b5dcc3..a7ac3fe0a6 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -110,10 +110,9 @@ def calclate_max_string_modes(file_modes) file_mode[:file_mode], file_mode[:nlink].rjust(max_string_modes[:nlink]), file_mode[:uid].ljust(max_string_modes[:uid]), - '', - file_mode[:gid].ljust(max_string_modes[:gid]), - file_mode[:size].rjust(max_string_modes[:size]), - file_mode[:mtime].ljust(max_string_modes[:mtime]), + file_mode[:gid].rjust(max_string_modes[:gid] + 1), + file_mode[:size].rjust(max_string_modes[:size] + 1), + file_mode[:mtime].rjust(max_string_modes[:mtime] + 1), file_mode[:file_path] ].join(' ') puts file_mode_print From 69c4b5369e5af9885680b6932999627ef53fca67 Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Tue, 18 Jun 2024 11:26:17 +0900 Subject: [PATCH 18/23] =?UTF-8?q?fix:=20=E3=83=95=E3=82=A1=E3=82=A4?= =?UTF-8?q?=E3=83=AB=E3=82=92=E7=A4=BA=E3=81=99=E6=96=87=E5=AD=97=E3=81=8C?= =?UTF-8?q?=E9=96=93=E9=81=95=E3=81=A3=E3=81=A6=E3=81=84=E3=81=9F=E3=81=AE?= =?UTF-8?q?=E3=81=A7=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit f -> - --- 04.ls/ls.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index a7ac3fe0a6..65f6c50d15 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -12,7 +12,7 @@ 'characterSpecial' => 'c', 'directory' => 'd', 'blockSpecial' => 'b', - 'file' => 'f', + 'file' => '-', 'link' => 'l', 'socket' => 's' }.freeze From 4d3313cf9be8da8b6da3d3f425b2bf9077173a0d Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Tue, 18 Jun 2024 11:58:54 +0900 Subject: [PATCH 19/23] =?UTF-8?q?fix:=20=E3=82=B9=E3=83=86=E3=82=A3?= =?UTF-8?q?=E3=83=83=E3=82=AD=E3=83=BC=E3=83=93=E3=83=BC=E3=83=88=E3=81=AA?= =?UTF-8?q?=E3=81=A9=E3=81=AE=E6=A8=A9=E9=99=90=E3=81=AE=E7=A2=BA=E8=AA=8D?= =?UTF-8?q?=E5=BE=8C=E3=80=81=E6=96=87=E5=AD=97=E5=88=97=E3=81=AB=E5=8F=8D?= =?UTF-8?q?=E6=98=A0=E3=81=95=E3=81=9B=E3=82=8B=E5=87=A6=E7=90=86=E3=81=8C?= =?UTF-8?q?=E3=81=86=E3=81=BE=E3=81=8F=E3=81=84=E3=81=A3=E3=81=A6=E3=81=84?= =?UTF-8?q?=E3=81=AA=E3=81=8B=E3=81=A3=E3=81=9F=E3=81=AE=E3=81=A7=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 04.ls/ls.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index 65f6c50d15..dc4ef18716 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -60,9 +60,13 @@ def convert_file_mode(file_stat) def apply_special_modes(special_modes, permissions) SPECIAL_MODE.each do |mode| - if special_modes == mode[:bit] - permissions[mode[:index]] == 'x' ? mode[:exec] : mode[:no_exec] - end + next unless special_modes == mode[:bit] + + permissions[mode[:index]] = if permissions[mode[:index]] == 'x' + mode[:exec] + else + mode[:no_exec] + end end permissions end From 1b9593fb6d8876cf9f6a1f1c126c6482fa7540f9 Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Wed, 19 Jun 2024 10:18:42 +0900 Subject: [PATCH 20/23] =?UTF-8?q?add:=20apply=5Fspecial=5Fmodes=E3=81=AB?= =?UTF-8?q?=E9=96=A2=E3=81=99=E3=82=8B=E8=AA=AC=E6=98=8E=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 04.ls/ls.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index dc4ef18716..b46d8e7e2a 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -53,7 +53,8 @@ def convert_file_mode(file_stat) file_mode_octal = file_stat.mode.to_s(8).rjust(6, '0') file_mode = FILE_TYPE[file_stat.ftype].to_s file_permissions = file_mode_octal.slice(3..-1).chars.map { |char| FILE_MODE[char] }.join - # 特殊権限の確認 + # 特殊権限の確認 特殊権限は8進数に変換されたファイルモードの3文字目に記載されている そのためfile_mode_octal[2]を参照する + # 0は特殊権限なし、なので最初に弾く(apply_special_modesは1か2か4であるかを判別し、当てはめるため) file_permissions = apply_special_modes(file_mode_octal[2], file_permissions) if file_mode_octal[2] != '0' file_mode + file_permissions end From 1ba92aae5040339e395954ee7c7ced7b9ec3cb35 Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Wed, 19 Jun 2024 10:30:51 +0900 Subject: [PATCH 21/23] =?UTF-8?q?change:=200=E3=81=A7=E3=81=82=E3=82=8B?= =?UTF-8?q?=E3=81=8B=E3=81=A9=E3=81=86=E3=81=8B=E7=A2=BA=E8=AA=8D=E3=81=99?= =?UTF-8?q?=E3=82=8Bif=E6=96=87=E3=82=92apply=5Fspecial=5Fmodes=E5=86=85?= =?UTF-8?q?=E3=81=AB=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 0, 1, 2, 4の判定はapply_special_modes内で行った方が処理としてわかりやすいと考えたから --- 04.ls/ls.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index b46d8e7e2a..5b6bb31bb1 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -54,12 +54,14 @@ def convert_file_mode(file_stat) file_mode = FILE_TYPE[file_stat.ftype].to_s file_permissions = file_mode_octal.slice(3..-1).chars.map { |char| FILE_MODE[char] }.join # 特殊権限の確認 特殊権限は8進数に変換されたファイルモードの3文字目に記載されている そのためfile_mode_octal[2]を参照する - # 0は特殊権限なし、なので最初に弾く(apply_special_modesは1か2か4であるかを判別し、当てはめるため) - file_permissions = apply_special_modes(file_mode_octal[2], file_permissions) if file_mode_octal[2] != '0' + file_permissions = apply_special_modes(file_mode_octal[2], file_permissions) file_mode + file_permissions end def apply_special_modes(special_modes, permissions) + # 0は特殊権限なし、なので最初に弾く(特殊権限は1か2か4であるため) + return permissions if special_modes == '0' + SPECIAL_MODE.each do |mode| next unless special_modes == mode[:bit] From d4d5ce3ecc7daae812f193923497888c390bc20e Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Thu, 20 Jun 2024 10:13:25 +0900 Subject: [PATCH 22/23] =?UTF-8?q?fix:=20=E7=89=B9=E6=AE=8A=E6=A8=A9?= =?UTF-8?q?=E9=99=90=E3=81=AE=E4=BB=98=E4=B8=8E=E3=83=AD=E3=82=B8=E3=83=83?= =?UTF-8?q?=E3=82=AF=E3=81=8C=E9=96=93=E9=81=95=E3=81=A3=E3=81=A6=E3=81=84?= =?UTF-8?q?=E3=81=9F=E3=81=AE=E3=81=A7=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 特殊権限は1つしか付与できないと勘違いしていたため、それぞれの権限の確認を1回ずつしかしてこなかった 今回は特殊権限をSUID(4), GUID(2), Sticky Bit(1)の順で確認し、存在していた場合は数値を減算するロジックを組んだ このような計算であれば2進数の方が適しているが、今回はわかりやすさのために8進数変換された状態(コードは10進数)で計算するようにした --- 04.ls/ls.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index 5b6bb31bb1..532268a86a 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -29,9 +29,9 @@ }.freeze SPECIAL_MODE = [ - { bit: '4', index: 2, exec: 's', no_exec: 'S' }, - { bit: '2', index: 5, exec: 's', no_exec: 'S' }, - { bit: '1', index: 8, exec: 't', no_exec: 'T' } + { bit: 4, index: 2, exec: 's', no_exec: 'S' }, + { bit: 2, index: 5, exec: 's', no_exec: 'S' }, + { bit: 1, index: 8, exec: 't', no_exec: 'T' } ].freeze def except_hidden_file(file_paths) @@ -54,17 +54,18 @@ def convert_file_mode(file_stat) file_mode = FILE_TYPE[file_stat.ftype].to_s file_permissions = file_mode_octal.slice(3..-1).chars.map { |char| FILE_MODE[char] }.join # 特殊権限の確認 特殊権限は8進数に変換されたファイルモードの3文字目に記載されている そのためfile_mode_octal[2]を参照する - file_permissions = apply_special_modes(file_mode_octal[2], file_permissions) + file_permissions = apply_special_modes(file_mode_octal[2].to_i, file_permissions) file_mode + file_permissions end def apply_special_modes(special_modes, permissions) # 0は特殊権限なし、なので最初に弾く(特殊権限は1か2か4であるため) - return permissions if special_modes == '0' + return permissions if special_modes.zero? SPECIAL_MODE.each do |mode| - next unless special_modes == mode[:bit] + next unless special_modes >= mode[:bit] + special_modes -= mode[:bit] permissions[mode[:index]] = if permissions[mode[:index]] == 'x' mode[:exec] else From 74c2e8cd548a014bd189666a10fa3ddb2415f774 Mon Sep 17 00:00:00 2001 From: "yuichi.imori" Date: Fri, 21 Jun 2024 10:28:11 +0900 Subject: [PATCH 23/23] =?UTF-8?q?change:=20=E7=89=B9=E6=AE=8A=E6=A8=A9?= =?UTF-8?q?=E9=99=90=E3=81=AE=E5=88=A4=E5=AE=9A=E3=82=92=E3=83=93=E3=83=83?= =?UTF-8?q?=E3=83=88=E6=BC=94=E7=AE=97=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit &を用い、ビット演算の論理積で2進数ごとの桁の判定を行った --- 04.ls/ls.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/04.ls/ls.rb b/04.ls/ls.rb index 532268a86a..83dd69aa4b 100755 --- a/04.ls/ls.rb +++ b/04.ls/ls.rb @@ -63,9 +63,8 @@ def apply_special_modes(special_modes, permissions) return permissions if special_modes.zero? SPECIAL_MODE.each do |mode| - next unless special_modes >= mode[:bit] + next unless (special_modes & mode[:bit]).positive? - special_modes -= mode[:bit] permissions[mode[:index]] = if permissions[mode[:index]] == 'x' mode[:exec] else