When writing about digital technology, or any topic, is something you do, it takes time to accumulate credibility. Even if you put in the study time up front to know your stuff, building trust takes time.
I’ve been fortunate that, after years expanding my portfolio and the knowledge base under it, people come to me for advice on related subject matter. I’m still not totally comfortable in this position, but I roll with it.
As more professionals put stock in my technical background, I have been exposed to more specialized technical environments and use cases. Friends asking for consumer electronics troubleshooting is worlds apart from professionals looking to overcome a technical hurdle.
This new class of advice I’m prompted to provide has elucidated the challenges that professionals confront. Moreover, when I field the same question multiple times, it hints at a potential gap in computer science training. Naturally, I want to do my part to close it.
To be clear, I’m not putting anyone down. There are plenty of things I don’t know and probably should. I simply want to draw attention to concepts that I’m surprised that competent individuals struggle with. Specifically, what I regard as key Unix principles I’ve found notably missing.
I’m not totally surprised, as a lot of “tech sector” professionals work in levels of abstraction above the OS. But it pays to know these Unix basics considering there is often a Unix/Unix-like OS somewhere in the abstraction hierarchy. If that layer is unsound, the whole edifice risks collapse.
To that end, I want to highlight questions I’ve been asked about Unixy (my substitute for “Unix and Unix-like”) systems, and the fundamentals to grasp to become self-sufficient.
To Run Programs, It’s Best To Stay on the $PATH
While it’s easier than ever for software developers to escape the command line interface, sometimes it’s unavoidable.
If a program comes preinstalled on a Unixy system or can be installed from an official OS repository, it’s usually easy to invoke. But when the CLI program is some executable downloaded from the internet, this can trip people up.
Running it from within its directory is no big deal. Clicking on it in the file browser might even pop open a terminal emulator and run it. But once some (mainly neophyte) developers leave that directory, they’re not sure why the command is inaccessible without giving the absolute or relative path to it.
This has to do with the shell’s PATH environment variable. When you enter a command into a shell like Bash, the shell has to know where it is. In Unix, everything is a file, and every file is somewhere in the file tree (starting at /). But if the system had to search every file, that would take too long.
Instead, your shell only looks in the directories in the PATH variable. If there is no executable file with the name you entered in one of those directories, a Unixy system doesn’t know where that command is.
To see what directories are in your PATH, open a terminal and run echo $PATH. This outputs the value of the PATH variable as it is currently set in the shell.
If you want to add more places for your system to check for executables, just update PATH. Define the PATH variable explicitly in your shell’s configuration file (e.g. for Bash, ~/.bashrc, ~/.bash_profile or something similar). One common practice is to make a directory in the user’s home directory called “bin” and add $HOME/bin to your PATH (HOME being the current user’s home).
Remember, you don’t want to replace your PATH with just the desired directory. That would make it the only place your shell looks. You just want one more place to search. You could copy the output of echo $PATH as is and paste it into your shell config file. The more conventional method is to add this line:
Just as with many common programming languages, this assignment statement works because the right side of the “=” sign is evaluated first and then assigned to the left side. In other words, your current PATH is returned, your new directory is concatenated to the end, and then PATH is set to that.
Set It So Your Shell Won’t Forget It
There’s another property of environment variables I’ve seen developers overlook: how long they persist.
It’s not uncommon for devs to utilize CLI tools that expect certain environment variables. In Unixy systems, you’re free to define any arbitrary environment variable with any arbitrary value. When they need one, I typically see devs run the same environment variable definition every time they launch their terminal.
This is because every time most terminal emulators (and with them, a shell) start for the first time (from not running anywhere on the system), they start a new session. When the last of the shell processes associated with the terminal emulator terminates, so too does the session. Notably, environment variables set via export command only last for the session.
As you probably intuited, we can set our environment variable in our shell config file just as we did with PATH. Just refer to the PATH definition syntax above to see how. Now enjoy all the time you saved.
Always Know Who’s Listening
While I wouldn’t necessarily consider it a core Unix concept, this next trick is so handy that I’m surprised more devs don’t know it.
In the course of managing some Unixy system, eventually you may need to know what network ports are actively listening. Doing so by checking all running services can be cumbersome because, depending on the system’s available tooling, open ports may not appear in the summarized output. It’s easier to skip the service utility and analyze the ports directly.
My preferred approach is to use lsof. This useful command returns all open files. “Wait,” you might say, “I’m looking for ports, not files.” Ah, but remember, in Unix, everything is a file. That includes ports.
Even better, lsof is tailored for this use case (among many others), as its -i flag limits output to files used as part of Internet Protocol communication. By running lsof -i you can see every open port, including listening ones.
You may want to throw in other flags or pipe it through a regular expression filter via grep to narrow down your search, but the above command alone will get you most of the way there.
Just Your Friendly Neighborhood Penguin-Man
What drew me most to the idea for this article was its direct applicability to a whole class of people who need quick, reliable answers. As I invest more into professional dialog with developers, I hope to uncover more areas where I’m able to light the Unix way I’ve grown so fond of.
Suggest a Topic
Is there a Unix tutorial you’d like to see featured?
Please email your ideas to me and I’ll consider them for a future column.
And use the Reader Comments feature below to provide your input!