GithubHelp home page GithubHelp logo

mikemcquaid / dotfiles Goto Github PK

View Code? Open in Web Editor NEW
254.0 254.0 148.0 731 KB

๐Ÿ’ป My dot files shared between machines.

License: GNU General Public License v3.0

Shell 74.69% Ruby 23.62% Vim Script 1.69%
dotfiles macos shell zsh

dotfiles's Introduction

Some things you should know about life:

dotfiles's People

Contributors

mikemcquaid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dotfiles's Issues

bash_profile, bashrc issue

tldr

On macOS: shells are interactive, login which causes ONLY bash_profile to get run. This causes bashrc (and shrc) to never get run on macOS. This problem does not occur for zsh or bash on other *nix. (update: this is an issue for zsh as well on macOS)


In your current setup, the bashrc (and thus shrc) files never get run when on macOS (fresh install).

Define behavior of macOS for bash

macOS runs each shell as a login shell.

Here are some additional details: http://unix.stackexchange.com/questions/119627/why-are-interactive-shells-on-osx-login-shells-by-default

Define behavior of login shells in bash (only bash_profile is run)

Since macOS runs each shell as a login shell, it only runs the bash_profile and ignores the bashrc file.

From the SO:

Now, a kind of a silly peculiarity of bash, not shared by most other shells, is that it will not automatically run .bashrc if it's started as a login shell.

From man bash:

shows that bash_profile gets executed for login shells

When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if
that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that
exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.

shows that bashrc is NOT executed for login shells

When an interactive shell that is not a login shell is started, bash reads and executes commands from ~/.bashrc, if that file exists.

thus, bash_profile is the only thing executed for login shells

Potential Solutions

Solution 1: Source things differently on macOS

One solution is to source the bashrc from the bash_profile only on macOS AND source the other way around only on NOT macOS.

# .bash_profile
[ $(uname -s) = "Darwin" ] && source ~/.bashrc
.bashrc
[ $(uname -s) != "Darwin" ] && source ~/.bash_profile

Issue with this solution: running bash in a subshell will now only execute bashrc and not bash_profile. You need to execute bash --login instead and it will also run it in the opposite order (profile first, bashrc second) so that's something to keep in mind.

Solution 2: Change the command used to start the shell

Document that you need to start bash in interactive, non-login mode (the standard linux way).

  • The command would be: bash or to be explicit bash --noprofile -i
  • In iTerm2, you can do this like so and everything works great:
    screen shot 2017-03-22 at 3 09 17 pm
  • Unfortunately this doesn't work for Terminal.app out of the box.
    • You can either set the global login shell
      screen shot 2017-03-22 at 3 42 29 pm
    • OR specify the shell/command to be used in Terminal profiles.
      screen shot 2017-03-22 at 3 42 39 pm
    • Unless you use "Run inside shell", all other options will prepend a "-" before the command causing your bash to run in login mode which means bash_profile gets run and bashrc does not.

Would love your thoughts on a portable solution. Thanks!


Addendum

Some additional details to verify everything I said above.

Checking that the shell is Interactive

You can test that the shell is interactive by running echo $-. If "i" exists within the output, the shell is interactive.

From man bash:

PS1 is set and $- includes i if bash is interactive, allowing a shell script or a startup file to test this state.

echo $- | grep "i"

Checking that the shell is login

You can test this by running echo $0 after starting the shell. If it returns "-bash" then it has started as a login shell.

From man bash:

A login shell is one whose first character of argument zero is a -, or one started with the --login option.

Last login: Wed Mar 22 15:27:20 on ttys001
loaded bash_profile
Als-MacBook-Air ~ # echo $0
-bash
Als-MacBook-Air ~ # bash
loaded bashrc
loaded bash_profile
Als-MacBook-Air ~ # echo $0
bash
Als-MacBook-Air ~ # 

You can see in the example above, it only loads the profile and not bashrc as it has started as a login shell. After running bash as a subprocess, it loads both the bashrc and the profile and it is a non-login shell.

Your assumption right now is the opposite (which I believe applies in the Linux world), that each shell is interactive and non-login so bashrc will run first and you source the bash_profile from within that script.

rbenv folder overwritten?

Hi @MikeMcQuaid, it seems like the condition below:

    if [ -L "$HOMEFILE" ] && ! [ -d $DOTFILE ]
    then
      ln -sfv "$DIRFILE" "$HOMEFILE"
    else
      rm -rv "$HOMEFILE"
      ln -sv "$DIRFILE" "$HOMEFILE"
    fi

will attempt to rm -rv the ~/.rbenv folder if the script is run a second time.

Not sure if you were going for idempotency in this script, but apart from this, I've been able to run the setup script multiple times to update dependencies and symlinks.

Feel free to close if you don't care about idempotency for this project.

don't change PATH in sh.rc

hi, i've been working with some issues in pyenv and pipenv (python's new bundler) and I realized that the way my (and I believe your) shell is set up, is not entirely amenable to subshells / child processes

it seems as though putting changes to the PATH in shrc causes the subshell to rexecute the shrc thus re-adding things to the PATH. this issue is important when the parent process tries to run a subshell with a modified PATH, like a python virtualenv. unfortunately, the shrc ends up overriding those PATH changes via add_to_path_start. so my subshell's path will end up with /usr/local/bin/:my_virtualenv_path:... instead of my_virtualenv_path being at the beginning

seems like the better approach is to move any code that modifies the path like add_to_path_start, rbenv init, pyenv init, etc. into the profile. The profile should get run for login shells only and thus will not be rexecuted for subshells.

I'm making some changes in my own dotfiles to reflect this. just thought I'd drop you a note as well :) feel free to close

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.