Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I used to do this, but unary kind of sucks after 3; So maybe others might like this better before their fingers get trained:

    ..() { # Usage: .. [N=1] -> cd up N levels
      local d="" i
      for ((i = 0; i < ${1:-"1"}; i++))
        d="$d/.."  # Build up a string & do 1 cd to preserve dirstack
      [[ -z $d ]] || cd ./$d
    }
Of course, what I actually have been doing since the early 90s is realize that a single "." with no-args is normally illegal and people "cd" soooo much more often than sourcing script definitions. So, I hijack that to save one "." in the first 3 cases and then take a number for the general case.

    # dash allows non-AlphaNumeric alias but not function names; POSIX is silent.
    cd1 () { if [ $# -eq 0 ]; then cd ..; else command . "$@"; fi; } # nice "cd .."
    alias .=cd1
    cdu() {           # Usage: cdu [N=2] -> cd up N levels
      local i=0 d=""  # "." already does 1 level
      while [ $i -lt ${1:-"2"} ]; do d=$d/..; i=$((i+1)); done
      [ -z "$d" ] || cd ./$d; }
    alias ..=cdu
    alias ...='cd ../../..' # so, "."=1up, ".."=2up, "..."=3up, ".. N"=Nup
and as per the comment this even works in lowly dash, but needs a slight workaround. bash can just do a .() and ..() shell function as with the zsh.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: