Bash: An Easier Way to Check File Permissions (Octal Mode & Stat)

File permissions on Linux can be a pain. You can either understand them in symbolic mode (basically, alphabet soup--i.e., drwxrwxrwx), or you can master them in octal mode (i.e., 777--which roughly translates to "Open the gates of Mordor!"). While symbolic mode might acutually be the more human-readable format; octal mode feels a bit more intuitive, and in my experience is what I see referenced more often on the interwebz (i.e., StackOverflow). The problem?--Linux generally defaults to symbolic mode on the command line--such as when you run ls -l. Here's a short script that helps cope with this. Run it, and it'll give you the permissions for a file, directory, or contents of a directory in octal mode.

Lost in Translation

First off: I'll assume this isn't your first time dancing the permissions tango--i.e., you have a basic understanding of symbolic and octal permissions. So, I won't go into the nitty gritty, here, of what each and every number combination means--let alone the existential implications of what your permissions should be for any given use-case. Instead, let's focus on how to resolve some of these existential crises: you're not sure what the permissions for a certain file should be; Google (or, much better, Duck-Duck-Go), says your permissions should be set to 664; you hit the command line, run ls -l to view your file's permissions and get the following output: -rwxr-xr-x. Congratulations: unless you're a power-Linux-user, you now get to spend the next five minutes translating the symbolic output of ls -l into an octal (number) value. Wouldn't it be cool if Linux could do the translation for you? Newsflash: it can--with the help of stat.

Here's a quick example. I want to know what both the octal and symbolic permissions are for a file called lso.sh. I can run the following: stat -c "%a %A %n" /pathto/lso.sh. %a prints the octal value; %A gets me the symbolic; and, %ngets me the file name. Have a look at the output:

using stat to verify file permissions on the command line
Very useful!--hopefully an "AHA!"-moment if you're new to stat

"Yeah--that's cool and all..." but who really wants to hit shift + 5 (i.e., '%') three times in the same command!? Isn't there an easier way? There is: lets drop this command in a Bash script and give it a few arguments; then we can run it much like we would ls

The Script: ls Powered by Octal (lso)

Here it is in action: I've put together my script so that I can run stat on an entire directory, an entire directory including hidden files, or just a single file. Once aliased, all I have to do is type lso

output from a script that checks octal mode permissions on linux
You'll soon find me going door to door: "Do you mind taking some time to talk about our lord and savior, Bash?"

Let's look at the actual script. The logic isn't anything special:

#! /bin/bash

if [ -z ${1} ]; then
  stat -c "%a %A %n" *
elif [ "$1" = h ]; then
  stat -c "%a %A %n" .* *
else
  stat -c "%a %A %n" "$1"
fi

The first if statement checks to see whether an argument has been passed to the script (i.e., a $1 variable). If the $1 variable hasn't been defined, then we run stat on the entire contents of whatever the current directory is--we do this with the * at the end of the command in place of a file-path. This statement allows you to run the script with just the alias and no arguments, i.e., $ lso (again, assuming you've aliased the script appropriately).

# if no argument, run stat on entire directory
if [ -z ${1} ]; then
  stat -c "%a %A %n" *

The else if statement says basically: if an argument has been passed (i.e., a $1 variable is defined) and the variable is defined as 'h', run stat on the current directory and output (h)idden files in addition to regular files. Here, I've given stat two file paths: .* covers any hidden files, and * covers any regular files. Hence, you can run the script like this, $ lso h and it will give you output for hidden files as well

# if argument equals 'h', include hidden files
elif [ "$1" = h ]; then 
  stat -c "%a %A %n" .* *

The final else statement gives an ultimatum: if neither of the first conditions (if, elif) checks out, take whatever argument comes with the call to the script and pass it to stat as a file-path. This allows you to run the script with a file-path as an argument: i.e., $lso /pathto/some/file. That path can be relative to your current directory, or can be an absolute path anywhere on your device.

# otherwise, take the argument and pass it to stat as a file-path
else 
  stat -c "%a %A %n" "$1" 
fi

That's about it. It's a simple script, but it can make life a whole lot easier if you're not used to translating between symbolic and octal permission modes. For my script, I've passed both the %a and %A output values to stat. This means, of course, that I get both octal and symbolic modes in my output. This is actually a great way of mastering translation, although it can be hard on the eyes. If you'd only like to see octal permissions in the output, just remove the %A output value from the script! Enjoy!