Learn › Linux Foundations › Manipulation
basename - a hands-on Linux lab on a real virtual machine.
Strip a path down to its last name with basename. Keep just the file name, drop a suffix with a second argument or with -s, handle a trailing slash, and shorten a whole list of names with -s or -a. Pure text surgery, so it never touches the disk and answers the same on every machine.
Here is a path a script just handed you: /home/student/report.txt. It tells you where a file lives, folder by folder, all the way down. But sometimes you do not care about the journey. You only want the destination: the file's own name, report.txt, with the whole /home/student/ road stripped away.
Doing that by hand, counting slashes and copying the tail, is fiddly and easy to get wrong. There is a command built for exactly this one job. It is called basename, and it takes a full path and hands you back only the last piece.
The black boxes below are a practice terminal: a safe sandbox that checks the one command each step teaches, so you cannot break anything. basename does pure text work on the path you type, so it never reads a real disk. That means its answers are the same on every machine, and the outputs shown here are exactly what you will see.
A path is the full address of a file, written as a list of folders separated by slashes, ending in the file itself. In /home/student/report.txt, the folders are home and student, and report.txt is the file at the end.
basename reads that address and returns only the final part, the base name, which is where the command gets its name. Everything before the last slash is the directory portion, and basename throws it away. It does not open the file or check that it exists. It just does careful surgery on the text of the path.
The simplest form is basename followed by one path. Hand it the full address and it gives you back the file's own name:
basename /home/student/report.txt
prompt: student@linuxcamp:~$ answer: basename /home/student/report.txt output: report.txt hint: Type basename, a space, then the full path: basename /home/student/report.txt
The whole /home/student/ part is gone, and you are left with just report.txt. basename scanned the path for the last slash and kept only what came after it. Notice it did not remove the .txt on the end: to basename, the extension is simply part of the file's name, so it stays. Stripping the extension too is a separate move, and it is the next thing you will learn.
Often the name alone is still more than you want. You have report.txt but you really want just report, so you can build a new name like report.bak or report.log. basename can strip a trailing piece for you if you tell it what to remove.
Add a second argument after the path: the suffix you want gone. Whatever text you name, if the file ends with it, basename chops it off the result. Ask it to drop the .txt:
basename /home/student/report.txt .txt
prompt: student@linuxcamp:~$ answer: basename /home/student/report.txt .txt output: report hint: Add the suffix as a second word after the path: basename /home/student/report.txt .txt
Now you have the bare report, both the directory and the .txt gone. The suffix is just text basename looks for at the very end of the name and removes if it finds it. One honest caution: the suffix is a plain match, not a rule about extensions. If you ask it to strip .txt from a name that does not end in .txt, nothing is removed and you get the name back unchanged. It only cuts what is actually there.
Paths do not always end in a file. Sometimes you are handed a directory path with a slash on the end, like /home/student/, and you want the name of that last folder. You might expect the trailing slash to confuse a text tool. It does not.
basename quietly ignores a slash on the very end before it does its work, so it reaches past the slash to the real last piece. Point it at a folder path and see:
basename /home/student/
prompt: student@linuxcamp:~$ answer: basename /home/student/ output: student hint: Type basename and a directory path that ends in a slash: basename /home/student/
It returned student, the last folder, not an empty line. basename stripped the trailing slash first, then took the final piece that was left. This is why it works the same whether you hand it a file path or a folder path. It always gives you the last real name in the address, and a stray slash on the end is not counted.
So far you have fed basename one path at a time. When you have a whole list of files and want the same suffix stripped from every one, doing them one by one is slow. The -s flag, short for suffix, fixes that. It names the suffix to remove AND tells basename that every remaining argument is a separate name to process.
Give it -s .txt followed by two names, and it strips .txt from each and prints one result per line:
basename -s .txt a.txt b.txt
prompt: student@linuxcamp:~$ answer: basename -s .txt a.txt b.txt output: a b hint: Put -s and the suffix first, then list the names: basename -s .txt a.txt b.txt
Two names in, two clean names out, a and b, each on its own line with the .txt removed. That is the difference -s makes. In the plain two-argument form, the second word IS the path, but with -s the suffix comes right after the flag, which frees every later word to be its own name. There is also a bare -a flag, short for all, for when you have many names but no suffix to strip: -a means treat every argument as a name to shorten. Using -s turns -a on for you automatically, which is why the list above just worked.
This command shines inside scripts. Imagine a script that is handed the full path to a log file and needs to print a friendly message using just the file's name. Without basename, you would be slicing the string by hand. With it, one call does the job, and the script reads clearly.
Run the everyday form one more time so the core move is muscle memory, pulling the file name out of a deep path:
basename /var/log/syslog
prompt: student@linuxcamp:~$ answer: basename /var/log/syslog output: syslog hint: Type basename and the full path to the file: basename /var/log/syslog
You got syslog, the file's own name, with /var/log/ stripped off. This is the single most common way basename is used: a script has a long path and needs the short name for a message, a new filename, or a comparison. It is one small, sharp tool, and this is the cut it makes.
Scaffolding off. No command is printed this time. You have every piece you need.
A script hands you the path /home/student/notes.md. You want just the plain word notes, with the /home/student/ directory stripped away AND the .md extension removed, so nothing is left but the bare name.
prompt: student@linuxcamp:~$ answer: basename /home/student/notes.md .md output: notes hint: Recall the two-argument form: basename, then the path, then the suffix to remove. The suffix here is .md.
That is the full move. You handed basename the path to strip the directory, then named .md as the suffix to cut, and it returned the bare notes. This two-argument form, path then suffix, is the one you will reach for most: it collapses a full address down to a clean name you can build on. You recalled it from memory, which is exactly what the real machine will ask of you.
basename needs at least one path to work on, and in its plain form it accepts only so many arguments. Here are the two messages you are most likely to meet, with what each means and what to check first:
Run basename with nothing after it and you get basename: missing operand. An operand is just the input a command expects, here the path. The message means you gave it no path at all. Check that you actually typed a path after the command.
Run the plain form with too many words, like basename a b c, and you get basename: extra operand 'c'. In the plain form basename expects one path and, at most, one suffix, so a third word confuses it. It even names the offending word. Check whether you meant to use -s or -a, which are the flags that let you pass a whole list of names on purpose.
Both error messages print and then basename stops without giving you a name. They are not disasters; they are basename telling you the plain form got the wrong number of arguments. The fix is almost always either adding the path you forgot, or switching to -s or -a when you truly do have many names to process.
You earned this cheat sheet. Every row is a form of basename you just ran:
The one idea under all of it: basename takes a path in and hands the last name back, and it can trim a suffix off that name if you ask. It is pure text surgery, so it never touches the disk and always answers the same way.
basename is one half of a pair. It keeps the last name and throws away the directory. Its partner, dirname, does the exact opposite: it keeps the directory and throws away the last name. Point both at /home/student/report.txt and basename gives report.txt while dirname gives /home/student. That is the very next lesson.
The practice terminal has shown you the whole of basename. It strips a path down to its last name, drops a suffix when you name one, ignores a trailing slash, and handles a whole list of names with -s or -a. Every one of those you typed yourself.
The Manipulation module ends with one real Linux machine, the module capstone mission, and that is where you put these pieces to work for real. A VM boots just for you, with a live shell. It hands you objectives that use exactly what you practiced across this module. One difference from here: the mission shows no commands. You read the objective, you recall the command, you type it. That recall is what makes it stick.
Finish the other Manipulation lessons, then go strip a real path down to its name.
Practice basename in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.