1. 31

Including a guide to setting up your shell configuration so things consistently work no matter how you login or from where.

  1.  

  2. 7

    What is that table of check marks trying to tell me?

    1. 1

      Looks like a horrible expansion of the “login / interactive” matrix, but it’s pretty bad.

        1. 1

          Why does that page redirect me to some win an iPhone scam?

          1. 1

            Does the page actually redirect you or have you simply clicked on one of the “ads” there?

            I’m not responsible for the content of the page (it isn’t mine), nor had I ever visited it without an ad blocker (I use uBlock Origin) but it’s the most concise explanation of the matter raised in this thread that I had found thus far.

        2. 2

          My first draft was a written-out list much like the one in the “Creating different kinds of shell” section, but I figured that the table format was much more concise, and made it more clear that most of the time, shells don’t care if they’re interactive or not.

          How could I have made it better?

      1. 3

        A technique I use when setting the PATH goes:

        PATH="${HOME}/bin${PATH:+:${PATH#${HOME}/bin:}}"
        

        This command prepends ~/bin to PATH. If ~/bin is already at the front of the PATH is doesn’t append it again. If PATH is not defined it avoids appending the path separator, ‘:’, to ~/bin.

        # If PATH is defined, prepend ":" to it (the +):
        ${PATH:+:${PATH}}
        
        # If PATH begins with ~/bin:, remove it (the #):
        ${PATH#${HOME}/bin:}
        

        This makes setting PATH generally idempotent, though it has a bug where ~/bin will be added to PATH twice if PATH is empty or unset. It’s also not idempotent if another directory is added to PATH between two invocations adding ~/bin to PATH. It works well enough in practice.

        1. 9

          Obnoxious zsh user chiming in here: in zsh you can typeset -U path to annotate the variable as being a unique array and then use array operators, like path+=(~/bin) for append or path[1,0]=~/foo for prepend or path=(foo $path bar) if you like cleaner syntax.

          Another zsh note unrelated to parent comment: in zsh there’s ~/.zshenv if you are looking for the Right place to modify the path variable. Most of the zsh package managers / configuration frameworks should gently guide you toward that filepath.

          1. 3

            Second zsh user, here’s my over-engineered method of setting PATH, along with MANPATH and fpath too: https://library.evaryont.me/evaryont/dotfiles/blob/master/zshenv

            The file automatically finds itself (assuming that ~/.zshenv is a symlink to the git clone of my dotfiles repository) and has a large list of directories that I want in my path, sorts, expands and make makes each array full of unique values. Super quick, too!

            1. 2

              That’s not over-engineered. Mine has arrays of common prefices where installation trees can be found, common patterns which might exist therein, functions for manipulation and so forth. You might want to use the (N/) qualifier on entries: only match directories, and remove from the list if no match.

              1. 1

                Interesting. Can you share your config?

            2. 1

              This small script from my dotfiles appends paths to $PATH only if they are existing. I think this solution is quite readable but it does not prevent a path from being added twice.

            3. 1

              I use this in zsh:

              # setpath [FRONT] [-- BACK] - set $PATH, optionally put FRONT first, BACK last
              setpath() {
                path=(
                  ~/bin
                  ~/prj/mblaze{,/contrib}
              #   ~/src/vis
                  ~/.gem/ruby/*/bin(Nn[-1])
                  ~/.opam/current/bin
                  ~/.cabal/bin
                  ~/.go/bin
                  /usr/local/sbin
                  /usr/local/bin
                  /usr/sbin
                  /usr/bin
                  /sbin
                  /bin
                  /usr/games
                  /usr/games/bin
                )
                path=( "$@[1,$@[(i)--]-1]" ${(u)path:A}(N-/) "$@[$@[(i)--]+1,-1]" )
              }
              setpath