Unix shell scripting interview questions focus on core concepts
A shell script often feels simple until it has to remember what happened five lines ago.
A shell script often feels simple until it has to remember what happened five lines ago. That is the first idea behind this lesson: how a Unix script can catch an exit code, use it later, and still finish with the right result.
Interview questions on shell scripting often circle the same ground. They ask how to handle failure, how to read fixed-width text, and how to back up a file without breaking the process that still needs it. Those are basic habits, and they matter more than fancy syntax.
Catching exit codes without losing the script
Every command in a Unix shell leaves behind a status. A zero means success. A nonzero value means something went wrong, and the number can tell you what kind of wrong it was.
The plain problem is this. A script may have several places where it can stop. If you want to record the final status before the script ends, you need to save that value somewhere first.
One common pattern in Korn shell is to put the status into a variable inside a function. The function acts like a small memory box. Each time a command finishes, the script captures $? and stores it.
Here is the idea in plain form:
- Run a command.
- Immediately save
$?. - Pass that value to a function.
- Let the function keep the last status it saw.
- At the end, check whether a status was saved.
- If one was, do the follow-up task, such as logging or mail.
The key point is timing. $? only holds the status of the most recent command. If another command runs first, that value is lost. Shell scripting often punishes slow hands. It does not wait kindly.
A small example makes this clear:
EXIT_CODE=""
assembleExitCode() {
EXIT_CODE=$1
}
some_command
assembleExitCode $?
another_command
assembleExitCode $?
if [[ x"$EXIT_CODE" != x ]]; then
echo "Mail status"
fi
This is simple, but it teaches a useful habit. The script does not guess. It stores the code, then acts on it. That is cleaner than trying to recover the number after the shell has moved on with its life.
Reading fixed-width text with the right tool
Another common interview question asks how to work with a file that has fields of fixed size instead of neat separators. There may be no comma, no tab, and no whitespace you can trust. The record is really just a long line with pieces carved out by position.
This is where awk earns its keep. awk can pull out parts of a line by character position. It can also split fixed-width data using field widths, which is often easier to read than counting columns by hand.
The basic idea is to treat the line like a strip of paper. You cut the first 20 characters for one field, the next 10 for another, and so on. Then you build XML or another format from those pieces.
A simple example helps:
awk '{
print "<row>"
print " <name>" substr($0,1,20) "</name>"
print " <date>" substr($0,21,10) "</date>"
print " <code>" substr($0,31,10) "</code>"
print " <id>" substr($0,41,7) "</id>"
print "</row>"
}' data.txt > data.xml
This works because substr() takes a starting point and a length. The script is not trying to understand names or dates. It is just cutting the line where the file layout says to cut.
If the text has padding spaces, a trim step helps. That means removing blanks from the left and right sides before printing the value. It is a small cleanup, but it keeps XML tags from being filled with ugly space junk. Files rarely come with manners.
For fixed-width input, awk is usually the right interview answer because it matches the problem shape. The data has positions, so the solution uses positions too.
Backing up a log file without breaking the running service
The third idea is about log files. A log may grow large, but renaming it with mv can cause trouble if another process still has the file open. The process may keep writing to the old inode, or it may lose its target entirely. That is a nice way to create a mystery nobody needs before lunch.
The safer pattern is to copy the log, compress the copy, and then clear the original file in place. That keeps the file name the same, which matters when a service expects that path to stay put.
The sequence is straightforward:
- Make a name for the archive copy.
- Copy the current log to that new name.
- Empty the original log file without renaming it.
- Compress the saved copy.
In shell terms, that often looks like this:
suffix=`date +%Y%m%d%H%M%S`.bak
newFileName=${YourLogName.log}.${suffix}
cp -p YourLogName.log "$newFileName"
cp /dev/null YourLogName.log
compress "$newFileName"
The important part is the emptying step. cp /dev/null leaves the original file in place but clears its contents. New log messages can keep coming in. That is why this method is used when uptime matters and a rename would be rude.
There is still a small risk of missing a few lines during the handoff. That is a fact of life, not a bug in the human race. Because of that, the cleanest time to do this is during a quiet period.
What these interview questions are really testing
These questions are not really about memorizing commands. They test whether someone understands three core habits.
First, status codes matter. A shell script must save the result before it disappears.
Second, file layout matters. If the data has fixed positions, use fixed positions.
Third, live files matter. A running process may depend on a name staying in place, even if the contents need to be refreshed.
That is the core of practical shell work. It is less about clever one-liners and more about not breaking the thing that is already working.
With these patterns, a reader can now explain how to catch exit codes, how to slice fixed-width records for XML work, and how to rotate a log without renaming it out from under a live process.
The Migration Brief keeps that same shape in mind: one practical fix, one file format explained, and one safer way to move your mail.