🕵️ SicherheitslückenWhat continuous operational resilience looks like under DORA(09.09.2026 um 17:53 Uhr)
🔧 AI Nachrichten OpenAI seeks tougher AI rules. CIOs may feel the ripple effects(10.09.2026 um 12:11 Uhr)
🔧 AI Nachrichten Mistral valued at €21bn after €3bn Series D funding round(08.09.2026 um 10:19 Uhr)
🪟 Windows TippsWindows XP's Cursor Indicator Is Getting a Windows 11 Refresh(25.08.2026 um 13:00 Uhr)
🕵️ SicherheitslückenWhat continuous operational resilience looks like under DORA(09.09.2026 um 17:53 Uhr)
🔧 AI Nachrichten OpenAI seeks tougher AI rules. CIOs may feel the ripple effects(10.09.2026 um 12:11 Uhr)
🔧 AI Nachrichten Mistral valued at €21bn after €3bn Series D funding round(08.09.2026 um 10:19 Uhr)
🪟 Windows TippsWindows XP's Cursor Indicator Is Getting a Windows 11 Refresh(25.08.2026 um 13:00 Uhr)

🔧 Programmierung 🕛 vor 1 Jahr 5 Min Lesezeit
0

Day 10: ls -l *

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht




Overview



The market is tough. I wish I had an easier time interviewing. But, it gets easier every time I write an article, do a leetcode problem, or finish a day-job task. They passed on me in my most recent SRE interview, but that's OK. It just tells me that, for whatever reason, I wasn't the best candidate. Or it meant that they weren't the right employer for me. Either way, I'm still going to practice, study, and persevere.






Listing in Bash on Linux



One of the questions that they asked me was, what does this command do on Linux?




CODE
$ ls -l *









The Output



Here's an example of the output:




CODE
➜  pwd $ ls -l *
-rw-r--r--@ 1 user group 0 Month 01 14:05 LICENSE
-rw-r--r--@ 1 user group 202 Month 01 14:05 go.mod
-rw-r--r--@ 1 user group 896 Month 01 14:05 go.sum
-rw-r--r--@ 1 user group 138 Month 01 14:05 main.go

cmd:
total 8
-rw-r--r--@ 1 user group 1444 Month 01 14:05 root.go

internal:
total 16
-rw-r--r--@ 1 user group 37 Month 01 16:05 main.go
-rw-r--r--@ 1 user group 225 Month 01 14:10 main_test.go






Here are some things we see so far:




  1. It shows the current working directory and all its non-hidden contents.

  2. It shows permissions of the files in symbolic notation (as opposed to file mode notation like 0755). These permissions include owner, group, and other permissions (in that order) along with @ indicating extended attributes like for SELinux.

  3. It shows the total number of child elements below each directory child below the current working directory (pwd).

  4. This listing shows the user and group indicated on the child (file or dir)

  5. The last mod date/time for the file.






How does ls get this information?





  • stat - for getting file and directory info for each item listed, even with symbolic links and not using the -l (long-listing) option.


  • lstat - for getting metadata information for when using -l (long-listing) on symbolic link file types.






Code Sample



In an attempt to implement ls with -l support in go, here is a code sample.



Here's the stat_t parsing section:




CODE
func New(n string, stat *syscall.Stat_t) Stat {
var m Stat
m.BaseName = path.Base(n)
m.AbsolutePath, _ = filepath.Abs(n)
if stat.Mode&syscall.S_IFDIR == syscall.S_IFDIR {
m.Type = "directory"
} else if stat.Mode&syscall.S_IFREG == syscall.S_IFREG {
m.Type = "file"
} else if stat.Mode&syscall.S_IFLNK == syscall.S_IFLNK {
m.Type = "symlink"
} else if stat.Mode&syscall.S_IFIFO == syscall.S_IFIFO {
m.Type = "fifo"
} else if stat.Mode&syscall.S_IFSOCK == syscall.S_IFSOCK {
m.Type = "socket"
} else if stat.Mode&syscall.S_IFCHR == syscall.S_IFCHR {
m.Type = "character_device"
} else if stat.Mode&syscall.S_IFBLK == syscall.S_IFBLK {
m.Type = "block_device"
} else {
m.Type = "unknown"
}
m.SizeBytes = stat.Size
m.Mode = stat.Mode
m.UserID = stat.Uid
m.GroupID = stat.Gid
m.LastAccessedTime = time.Unix(stat.Atimespec.Sec, stat.Atimespec.Nsec)
m.LastModifiedTime = time.Unix(stat.Mtimespec.Sec, stat.Mtimespec.Nsec)
m.CreateTime = time.Unix(stat.Ctimespec.Sec, stat.Ctimespec.Nsec)
m.BirthTime = time.Unix(stat.Birthtimespec.Sec, stat.Birthtimespec.Nsec)
m.BlockSize = uint32(stat.Blksize)
m.NumBlocks = uint64(stat.Blocks)

var err error
u, err := user.LookupId(fmt.Sprintf("%d", stat.Uid))
if err == nil {
m.Owner = u.Username
m.UserName = u.Username
} else {
m.Owner = "unknown"
m.UserName = "unknown"
}

u, err = user.LookupId(fmt.Sprintf("%d", stat.Gid))
if err == nil {
m.GroupName = u.Username
} else {
m.GroupName = "unknown"
}

m.HardLinkReferenceCount = uint16(stat.Nlink)

octalPerm := os.FileMode(stat.Mode) & os.ModePerm
m.Permissions.Octal = fmt.Sprintf("%o", octalPerm)

const (
ownerStatTOffset = 6
groupStatTOffset = 3
otherStatTOffset = 1
)

// https://man7.org/linux/man-pages/man7/inode.7.html
// who-has-what-perms section starts at offset 6 and ends at offset 10.

// The >> operator in Go shifts the bits of a number to the right.
// Think of the number as a row of lights (1 = on, 0 = off).
// - >> 1 moves all the lights 1 step to the right, filling empty spaces on the left:
// - Positive numbers fill with 0 (e.g., 8 >> 1: 00001000 -> 00000100 = 4).
// - Negative numbers fill with 1 to keep the number negative.
// - Bits that fall off the right edge disappear.
var (
ownerPerms = uint8(octalPerm >> ownerStatTOffset)
groupPerms = uint8(octalPerm >> groupStatTOffset)
otherPerms = uint8(octalPerm >> otherStatTOffset)
)
m.Permissions.Symbolic.Owner = perm.New(ownerPerms)
m.Permissions.Symbolic.Group = perm.New(groupPerms)
m.Permissions.Symbolic.Other = perm.New(otherPerms)
return m
}






And here is the permissions parsing code:




CODE

func New(mode uint8) SymbolicPermission {
var (
read bool
write bool
execute bool
)
const (
readOffset = 4
writeOffset = 2
executeOffset = 1
)

// bitIsSet determines whether a specific bit is set in an unsigned int.
// Example:
// mode := uint8(5) // Binary: 101
// bitIsSet(mode, 4) // Returns true (read bit is set)
// 0b101 & 0b100 = 0b100 (comparison: 0b100 == 0b100 → true)
// bitIsSet(mode, 2) // Returns false (write bit is not set)
// 0b101 & 0b010 = 0b000 (comparison: 0b000 == 0b010 → false)
// bitIsSet(mode, 1) // Returns true (execute bit is set)
// 0b101 & 0b001 = 0b001 (comparison: 0b001 == 0b001 → true)
bitIsSet := func(mode, offset uint8) bool {
return mode&offset == offset
}
read = bitIsSet(mode, readOffset)
write = bitIsSet(mode, writeOffset)
execute = bitIsSet(mode, executeOffset)

return SymbolicPermission{
Read: read,
Write: write,
Execute: execute,
}
}


Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Sam Altman calls GPT-6 Astra rollout ‘messy’ as enterprise users wait for access
1 Quelle
Swiss government explores replacing Microsoft 365 with open-source software
1 Quelle
What continuous operational resilience looks like under DORA