LoginSignup
1
1

[Go] lsコマンドを一部実装してみる

Last updated at Posted at 2024-05-18

はじめに

Goを勉強したいので、手始めにlsコマンドを一部実装してみようかなと思います。今回は、lsでファイル名の一覧が表示されること、またオプションは、-lでファイルの詳細一覧が出力されることを目標として設定します。

実装

今回のリポジトリですmm

では最初に、lsを実装していきます。ポイントは、osライブラリが提供しているos.Getwd()でカレントディレクトリのパスを取得し、os.ReadDir()でディレクトリ内のファイルを全て返して、ファイル名を出力しているようにしている点です。

main.go
package main

import (
	"fmt"
	"os"
)

func main() {
	dir, err := os.Getwd()
	if err != nil {
		panic(err)
	}
	files, _ := os.ReadDir(dir)

	listFiles(files)
}

func listFiles(files []fs.DirEntry) {
	for _, f := range files {
		fmt.Printf("%s ", f.Name())
	}
}

では、スクリプトを実行してみます。

$ go run main.go
README.md go.mod main.go 

ここまでは、上手くいっていそうです。つづけて、オプションの-lを実装します。
ポイントは、flagライブラリが提供するflag.Bool()でコマンドライン引数を受け取るようにし、fsライブラリのfs.DirEntryといったインターフェースに属する関数を活用し、ファイルの各種情報を出力している点です。

main.go
package main

import (
	"flag"
	"fmt"
	"io/fs"
	"os"
	"time"
)

func main() {
+	isListed := flag.Bool("l", false, "List files")
+	flag.Parse()

	dir, err := os.Getwd()
	if err != nil {
		panic(err)
	}
	files, _ := os.ReadDir(dir)

+	if *isListed {
+		listFilesWithDetails(files)
+		return
+	}

	listFiles(files)
}

func listFiles(files []fs.DirEntry) {
	for _, f := range files {
		fmt.Printf("%s ", f.Name())
	}
}

+func listFilesWithDetails(files []fs.DirEntry) {
+	for _, f := range files {
+		info, err := f.Info()
+		if err != nil {
+			panic(err)
+		}
+		fmt.Printf("%s %s %d %s\n", info.Mode(), formatDate(info.ModTime()), info.Size(), f.Name())
+	}
+}

+func formatDate(t time.Time) string {
+	return t.Format("Jan 02 15:04")
+}

では、スクリプトを実行してみます。

$ go run main.go -l
-rw-r--r-- May 16 22:51 8 README.md
-rw-r--r-- May 16 18:18 30 go.mod
-rw-r--r-- May 18 15:42 719 main.go

こちらも、期待通りの結果が返ってきました。なお、今回は本来の-lにあるような、ハードリンクの数や所有者・所有グループまでは実装しませんでした。特に後者の理由は、Goの標準ライブラリのみではシンプルには書けないようだからです。Goの限界なのでしょう。

おわりに

こうして実装に取り組むと学びが色々とあると感じますし、やはり面白いです。
アドバイスや指摘があれば、頂けると幸いです。次は、grepコマンドの実装に挑戦してみようかな~

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1