6

I have the following in my ~/.bashrc to hide the listing of test from the output of ls:

alias ls='ls -I test'

But I want it to only hide test if my current working directory is the root (/) folder, not if I am in some other folder.

How may I achieve this?

  • 5
    If the working directory is the root, or if the directory to be listed is the root? Whilst the former is what you asked, I'm not sure that's what you really want! – Toby Speight Mar 2 '17 at 11:06
  • 1
    Looks like someone is working on a user-level rootkit? :P – Navin Mar 3 '17 at 12:47
  • This is a bad idea. Better make a different alias and use that. – reinierpost Mar 3 '17 at 15:02
10

Something like this i thought it would work:

alias ls='[[ "$PWD" = "/" ]] && ls -I test ||ls'

$PWD is the current working directory
&& has the action to perform if pwd is / (condition check =true)
|| has the action to perform if pwd is not / (condition check=false)

But after carefull testing above solution IS NOT WORKING correctly.

On the other hand this will work ok as alternative to functions:

alias ls='{ [[ "$PWD" == "/" ]] && a="-I tmp2" ||a=""; };ls $a '

Or even better, similar to other answers but without the need of function:

alias lstest='{ [[ "$PWD" == "/" ]] && set -- "-I" "tmp2" || set --; }; ls "$@"'

Possible extra flags and/or full paths given in command line when invoking this alias are preserved and sent to ls.

  • 7
    A problem with this is that using ls from / will always result in a listing of the current directory (/), no matter what the command line says. – Kusalananda Mar 2 '17 at 9:30
  • @Kusalananda You are right , my solution was not correct. I would like you to have a look in my alternative. I tested it and seems to work fine in Debian Bash. Definetely my answer should not have been marked as accepted before , but with the troll presence things got mixed up. I don't know if there is a way to transfer the "solution" mark to your answer as it was in the very beginning (before troll attacks) – George Vasiliou Mar 2 '17 at 11:58
  • 1
    Ah! alias 'ls={ [[ "$PWD" == "/" ]] && set -- "-I" "tmp2"; }; ls "$@" ', but that modifies the positional parameters instead... – Kusalananda Mar 2 '17 at 12:05
  • 1
    aliases are nasty because they are some forms of macro expansion. Those particular alias can't stand for a real ls command. For instance, ! ls or foo || ls won't do what you think. This really calls for a function. Note that the first example would run ls twice if the first one exits with a non-zero exit status. – Stéphane Chazelas Mar 2 '17 at 23:05
  • 3
    "without the need of function" isn't really a plus. Both of the "corrected" functions unnecessarily overwrite global variables that might be in use. – chepner Mar 3 '17 at 3:29
34
ls () {
  case "$PWD" in
    /) command ls -I test "$@" ;;
    *) command ls "$@" ;;
  esac
}

The above shell function will test the current directory against / and executes the GNU ls command differently according to the outcome of the test.

"$@" will be replaced by the command line options and operands on the original command line.

We need to use command ls rather than just ls in the function to bypass the shell function lookup for ls (which would otherwise give us a nice infinite recursion).

Note that this will not use the ignore pattern if doing ls / from somewhere else, and that it will use the ignore pattern if doing, e.g., ls /home/dvoo from /.

To make it easier to remember what this actually does (six months down the line when you wonder what it's doing), use the long options:

ls () {
  case "$PWD" in
    /) command ls --ignore='test' "$@" ;;
    *) command ls "$@" ;;
  esac
}

Alternative implementation of the above function that will only call ls from one place (and which is shorter):

ls () {
  [ "$PWD" = "/" ] && set -- --ignore='test' "$@"
  command ls "$@"
}
22

Use a function that tests if you're in / for ls:

ls () {
    if [[ "$PWD" == / ]]
    then
        command ls -I test "$@"
    else
        command ls "$@"
    fi
}

This way, any arguments you pass to ls will still be used.

Or:

ls () {
    if [ "$PWD" == / ]
    then
        set -- -I test "$@"
    fi
    command ls "$@"
}
  • 3
    That was a nice way of sorting out only having one call to ls in the function! – Kusalananda Mar 2 '17 at 10:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy