3 ms·
You’re still doing unnecessary work. You’re turning a list of files into a string, then parsing the string back into words. Your shell already provides a nice
by db48x 2y ago
You’re still doing unnecessary work. You’re turning a list of files into a string, then parsing the string back into words.
Your shell already provides a nice abstraction over calling readdir directly. A glob gives you a list, with no intermediate stage as a string that needs to be parsed. You can iterate directly over that list.
Every language provides either direct access to the C library, so that you can call readdir, or it provides some abstraction over it to make the process less annoying. In Common Lisp the function `directory` takes a pathname and returns a list of pathnames for the files in the named directory. In Rust there is the `std::fs::read_dir` that gives you an iterator that yields `io::Result<std::fs::DirEntry>`, allowing easy handling of io errors and also neatly avoiding an extra allocation. Raku has a function `dir` that returns a similar iterator, but with the added feature that it can match the names against a regex for you and only yield the matches. You can fill in more examples from your favorite languages if you want.
- kazinator 2y agoThere is a glob() function you can use in POSIX C also to get an array of strings. The getdents system call being used in the above program is the basis for implementing readdir. It doesn't return a string, but rather a buffer of multiple directory entries. The program isn't parsing a giant string; it is parsing out the directory entry structures, which are variable length and have a length field so the next one can be found. The program writes each name including the null terminator, so that the output is suitable for utilities which understand that.
- db48x 2y agoThe problem is the phrase “suitable for shell pipelines”. If you are in a shell, you should not be doing anything like this. You should use a glob directly in the shell. You should not be calling an external program, having that program print out something, and then parsing it. Just use a glob right there in your shell script. If you do anything else, you are doing it wrong. Do I really have to say this again?