Many of those utilities, if you inspect the source code, are recognizably the same programs as their original versions written 30+ years ago. They’ve been maintained and changed over the years, sure, but they’ve rarely needed big changes. After all, they’re simple programs that do basically the same job today as they did then, using basically the same API surface.
The main issue with this is that the programs are usually still single-threaded. For some key utilities like find and grep, this has allowed more modern alternatives to leapfrog them in performance. (To be fair, it’s hard to add parallelism without breaking compatibility somewhat.)
But in most other respects, there’s nothing wrong with being a little old-fashioned. Using global variables is an example of that. It’s a problem in larger programs but at this scale it’s fine.
The main issue with this is that the programs are usually still single-threaded. For some key utilities like find and grep, this has allowed more modern alternatives to leapfrog them in performance. (To be fair, it’s hard to add parallelism without breaking compatibility somewhat.)
But in most other respects, there’s nothing wrong with being a little old-fashioned. Using global variables is an example of that. It’s a problem in larger programs but at this scale it’s fine.