I am trying to write a Bash script that takes the name of a file or directory as an argument and reports if the file is a directory, regular file or other. The script should also report if the user has read, write and execute permission on the file or directory.

Obviously something like this will get the raw information:

read -p "Enter a filename: " fname
file $fname
ls -la $fname

however, I am wondering if we could just drop the file command completely, pass the filename variable to an ls that we then write some kind of if, then, else statement based on the results. the ls command gives a file type and full break down of the permissions the user running it has on the file, so can I make custom output based on the results of an ls command?

Instead the shell test is recommended. The answer below shows a great example of how to format this.

  • Should it take the filename as an argument or should it prompt the user for it? – jesse_b Jul 5 '18 at 19:56
  • to take the filename as an argument we would have to wrap this all in a function right? My preference is the prompt but either way works. – DanMan3395 Jul 5 '18 at 19:57
  • Before trying to do this with ls, I suggest you familiarize yourself with your system's stat command - it may be possible for you to get the output you want much more simply – steeldriver Jul 5 '18 at 20:00
  • yep stat also provides the info i need, the question is, can that info be parsed and used to determine the outcome of if, then, else language? – DanMan3395 Jul 5 '18 at 20:01

You can use the shell test to check for file type and permissions:


read -rp 'Enter a filename: ' fname
if [ -f "$fname" ]; then
    echo 'File is a regular file'
elif [ -d "$fname" ]; then
    echo 'File is a directory'
    echo 'File is not a regular file or a directory'
[ -r "$fname" ] && read=read
[ -w "$fname" ] && write=write
[ -x "$fname" ] && execute=execute

echo "User has ${read} ${write} ${execute} permissions" | tr -s ' '

The shell test

The if construct will report on the file type by checking if it is a regular file (-f) or a directory (-d) else it will report that it is neither.

Then we check the various permissions: read (-r), write (-w), and execute (-x). Setting a variable for each. If the user does not have one of these permissions the corresponding variable will remain unset, so in the final echo line if the user doesn't have that permission the variable will expand to nothing. This is wrapped up with a call to tr -s ' ' to remove any extra spaces that may be there from permissions not existing.

  • This works quite well but i am afraid I do not understand it. you aren't pulling the information from the output of any command I can see. – DanMan3395 Jul 5 '18 at 20:09
  • @DanMan3395: I've updated the question to include a link to some documentation on the shell test – jesse_b Jul 5 '18 at 20:11
  • Thank you, this is exactly what i was looking for. I could not find a man page for this on my system. – DanMan3395 Jul 5 '18 at 20:16
  • The way i was trying to do this seems stupid in contrast now that i understand this. thanks again! – DanMan3395 Jul 5 '18 at 20:44
  • @DanMan3395: No problem, glad I could help. Also don't look at it that way. When I go through and read scripts I wrote even a few months ago I find things that make me facepalm, but you can't start as an expert. I don't know about you but I learn best from mistakes. – jesse_b Jul 5 '18 at 20:52

Not the answer you're looking for? Browse other questions tagged or ask your own question.