re-use '~/.profile` for Fish?

31,802

Solution 1

You can use bash to parse /etc/profile and ~/.profile, and then start fish.

  1. Create /usr/local/bin/fishlogin with contents

     #!/bin/bash -l
     exec -l fish "$@"
    
  2. Make it executable

     sudo chmod a+rx /usr/local/bin/fishlogin
    
  3. Check that it works by running fishlogin and checking that you end up in a Fish shell. Press Control+D to exit the Fish shell.

  4. Add it to /etc/shells

     echo /usr/local/bin/fishlogin | sudo tee -a /etc/shells
    
  5. Set it as your default shell.

    Under Linux:

     sudo usermod -s /usr/local/bin/fishlogin $USER
    

    Under macOS:

     chsh -s /usr/local/fishlogin $USER
    

Solution 2

For a much cleaner solution, you can use the foreign env plugin:

fenv source ~/.profile

Solution 3

My current solution (see here for a maybe more recent version):

egrep "^export " ~/.profile | while read e
    set var (echo $e | sed -E "s/^export ([A-Z_]+)=(.*)\$/\1/")
    set value (echo $e | sed -E "s/^export ([A-Z_]+)=(.*)\$/\2/")

    # remove surrounding quotes if existing
    set value (echo $value | sed -E "s/^\"(.*)\"\$/\1/")

    if test $var = "PATH"
        # replace ":" by spaces. this is how PATH looks for Fish
        set value (echo $value | sed -E "s/:/ /g")

        # use eval because we need to expand the value
        eval set -xg $var $value

        continue
    end

    # evaluate variables. we can use eval because we most likely just used "$var"
    set value (eval echo $value)

    set -xg $var $value
end

Solution 4

I tried sourcing .profile on fish startup and it worked like a charm for me.

just do :

echo 'source ~/.profile;clear;' >  ~/.config/fish/config.fish

Restart terminal or iterm2, test an alias from .profile to test.

Note : Won't work with more complex .profile files that use syntax not available in fish - credit @erb

Solution 5

You can use bass, a plugin to execute bash commands in fish.

  1. Install bass.

    $ git clone https://github.com/edc/bass.git
    $ cd bass
    $ make install
    
  2. And then, just put this in your config.fish:

    bass source ~/.profile
    
Share:
31,802

Related videos on Youtube

Albert
Author by

Albert

I am postgraduate of RWTH Aachen, Germany and received a M.S. Math and a M.S. CompSci. My main interests are Machine Learning, Neural Networks, Artificial Intelligence, Logic, Automata Theory and Programming Languages. And I'm an enthusiastic hobby programmer with a wide range of side projects, mostly in C++ and Python. Homepage GitHub SourceForge HackerNewsers profile page MetaOptimize Q+A

Updated on September 18, 2022

Comments

  • Albert
    Albert almost 2 years

    (I'm talking about the shell Fish, esp. Fish's Fish.)

    For Bash/ZSH, I had ~/.profile with some exports, aliases and other stuff.

    I don't want to have a separate config for environment variables for Fish, I want to re-use my ~/.profile. How?

    In The FAQ, it is stated that I can at least import those via /usr/local/share/fish/tools/import_bash_settings.py, however I don't really like running that for each Fish-instance.

  • Albert
    Albert almost 12 years
    I don't want to fully execute .profile. I just want to get all exports from there. One easy way would be to egrep "^export" which would be good enough already for me. Another, more correct solution would be this. Also, I e.g. could run this import_bash_settings.py script which probably does something similar. So, there are obviously many ways to do this. With my question here, I was wondering how others have solved this.
  • Alexar
    Alexar over 8 years
    Worked for me too! Running MacOSX.
  • erb
    erb over 7 years
    Won't work with more complex .profile files that use syntax not available in fish.
  • Eswar Rajesh Pinapala
    Eswar Rajesh Pinapala over 7 years
    @erb I agree with you, I added the caveat in the answer.
  • max pleaner
    max pleaner over 7 years
    can you explain what this does?
  • yonix
    yonix over 7 years
    So elegant! Should be the accepted answer IMO
  • gloriphobia
    gloriphobia about 7 years
    Just in case anyone is wondering, the mac equivalent of usermod -s /usr/local/bin/fishlogin $USER is chsh -s /usr/local/fishlogin $USER
  • electronix384128
    electronix384128 about 7 years
    If you get chsh: /usr/local/bin/fishlogin: non-standard shell need to add it to /etc/shells
  • jhrmnn
    jhrmnn over 6 years
    To fully imitate launching fish directly, fish "$@" should be replaced with exec -l fish "$@". exec replaces the bash process with fish, while -l causes that argv[0] for fish is -fish, which signals that this is a login shell.
  • Jules Sam. Randolph
    Jules Sam. Randolph about 6 years
    This should be the accepted solution. You could elaborate (install omf)
  • Sz.
    Sz. almost 6 years
    Usually no big deal, but this seems to have the drawback that whenever a subshell is implicitly created, an unnecessary bash instance will also always be launched first. (Note: ~/.profile is only relevant for login shells.) Still upvoted, though, for its good trade-off between simplicity and hackyness. (I'd personally still rather just tweak my shell config scripts a bit, as I've long given up having complicated ones, in favor of custom shell-independent methods.)
  • Noé Rubinstein
    Noé Rubinstein over 5 years
    @Sz. Well, nope. Fish does not support subshells in the first place. And even if it did, it would not do so by executing your login shell, so no Bash would be spawned then.
  • Jared Smith
    Jared Smith over 5 years
    @maxpleaner AFAICT it looks through .profile for export statements and executes them as fish sets. It's kinda hacky, but clever.
  • Albert
    Albert over 5 years
    Note that fish reorders and modifies the entries in $PATH, which you might find confusing. See here.
  • ggnoredo
    ggnoredo about 5 years
    this is awesome thank you
  • Wayne Werner
    Wayne Werner about 5 years
    Probably don't even need to install dash - just sh will do (which is probably dash)
  • mk12
    mk12 almost 5 years
    If you're going to use this method, make sure it isn't too slow. I personally started to notice that my shell startup delay was annoyingly long, and tracked it down to bass.
  • rsalmei
    rsalmei almost 5 years
    @mk12 probably it isn't bass' fault, it is your .profile that has too much going on.
  • mk12
    mk12 almost 5 years
    @rsalmei All I had in there was environment variable and alias definitions, with a few if statements. It causes no noticeable delay in bash. So I think it is bass's fault. On the other hand, I'm much happier with the fenv plugin. It's written in shell rather than Python and seems much faster for me.
  • rsalmei
    rsalmei almost 5 years
    Yeah @mk12, it seems to be nice, but also way more limited, as it only captures environment variables. bass on the other hand interprets any bash shell script, and make them run in fish. It certainly will have a bit more overhead, but totally negligible in my experience, but your mileage may vary.
  • Dominykas Mostauskis
    Dominykas Mostauskis over 4 years
    @JulesRandolph installation of Oh My Fish is not required. The foreign_env fish plugin can be installed alone, it doesn't have dependencies.
  • RomanKousta
    RomanKousta over 3 years
    This just broke my Iterm2 on Mac. Followed the exact steps, now I can't even open iTerms.
  • RomanKousta
    RomanKousta over 3 years
    If following this answer bricks anyone else's iTerm2, here's how to recover: in iTerm2, "Profile" -> "General", make sure the "Command" is set to "Command" and enter "/bin/sh" as the command (or /bin/bash). Cmd+N open a new shell, then chsh -s /usr/local/bin/fish. Then undo the beginning steps and change "Command" back to Login Shell.
  • RomanKousta
    RomanKousta over 3 years
    This doesn't handle aliases, which make up 80% of my .bash_profile, and is therefore useless to me.
  • Noé Rubinstein
    Noé Rubinstein over 3 years
    @AsyncMoksha I'm curious to know how it managed to break. Maybe you could try running fishlogin from your current shell and see if it prints any interesting error message?
  • Dominykas Mostauskis
    Dominykas Mostauskis over 3 years
    ~/.profile gets sourced twice, because --login (or -l) is used twice, once on bash and once on exec. Remove one of the -l flags.
  • Noé Rubinstein
    Noé Rubinstein over 3 years
    As far as I can tell, the exec builtin does not read .profile; all the option does is add a '-' to the start of the first element of argv.
  • Timo Kluck
    Timo Kluck about 3 years
    If anyone's interested, here's an addition that also gets the .bashrc's aliases: ` #!/bin/bash -i if [ -d "$XDG_RUNTIME_DIR" ]; then alias > "$XDG_RUNTIME_DIR"/.bash_aliases fi exec -l fish --init-command 'source $XDG_RUNTIME_DIR/.bash_aliases' "$@" `
  • Admin
    Admin about 2 years
    You can add @jgillich solution in your .config/fish/config.fish file ``` if status is-interactive fenv source ~/.profile end ``` That way .profile will always be synced with fish :)