Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Is there any command to list the contents if passed a directory, but output the contents if it's a file?

For example, often when I am navigating the directory structure I will start typing into the terminal something like

ll /etc/path/  # I see a file in tab-completion that interests me, called myfile.txt
ll /etc/path/myfile.txt  # I do the auto-completion to get it into the command line
less /etc/path/myfile.txt  # Now I have to go back and change 'll' to 'less'

Alternatively, if I'm looking for a file, I start with

less /etc/path  # I see in tab-completion several files that might interest me, so I need to know more
ll /etc/path  # See more info about file sizes, etc, so I can choose the file I want. Have to change 'less' to 'll'
less /etc/path/myfile.txt  # Now that I know which file I want, I have to go back and change 'll' to 'less'

This is something I end up doing dozens of times a day, and starts to slow me down. Is there a command or script that does the likeliest scenario for you? For example

some-program /etc/path/to/file/or/directory

If the target is a text file or symlink to a text file, 'less /etc/path/to/.....' would be executed. But if it were anything else, e.g. directory, binary file, block device, it would do 'll /etc/path/to/......'

Of course if it does something you don't want, like 'less' on a file symlink but you want to see the symlink itself with 'll', then you just run 'll' manually.

Anything like this exist (I bet it's out there, it seems like such a common task)? Or am I just using Linux command line in an inefficient way and there are better ways to navigate through it...how do you do it? Or I am really the only one going back and forth in the command line all the time switching 'less' to 'll' and back again?

I tried writing something but I'm a bash beginner so it's definitely not working, and quite clunky even if it were. Surely there's a better way out there, some magic command I've just not heard about?

some-program() {
  if [[ $# > 1 ]]; then
    echo "Only one argument supported at this time"
  exit 1
  fi
  if [[ $# == 0 ]]; then
    ELEMENT="."
  else
    ELEMENT="$1"
  fi
  if [[ -d $ELEMENT ]]; then
    ls --color=auto -alF "$ELEMENT"
  else
    less "$ELEMENT"
  fi
}
share|improve this question

migrated from serverfault.com Mar 18 '13 at 16:39

This question came from our site for professional system and network administrators.

    
Your script seems OK. It will use less to show the file content if applied to a file, and it will list the directory if applied to a directory. I have one point only which is you defined a function and you did not invoke it. You just need to remove the first line and last one. –  Khaled Mar 17 '13 at 12:20
    
Or put this inside your .profile or .bashrc –  fboaventura Mar 17 '13 at 15:41
    
Have you considered actually using your command history? Try the arrow keys on your keyboard... –  Michael Hampton Mar 18 '13 at 11:36

1 Answer 1

less has a really neat built-in feature that lets you do things like this. See the lesspipe man page.

To use that feature to automatically show a directory listing of directories, do the following:

  1. Set up lesspipe following the man page: eval "$(lesspipe)"

  2. Create ~/.lessfilter with the following contents and make it executable:

    #!/bin/sh
    if [ -d "$1" ]; then
        ls -alF "$1"
    else
        # We don't handle this format.
        exit 1
    fi
    exit 0
    

This sets up a filter script run by lesspipe to handle file types. It checks to see if what you're trying to view is a directory and, if so, runs ls instead.

Your original request included color. That's unfortunately a bit harder, since less doesn't show color by default and the output from the filter script is still piped through less. You'd need to use -R as a default option (which is probably not a good idea if you ever view a binary file) to do that. I don't think there's a way to have the lessfilter script tell less to add a new option.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.