2

So I've got a .bash_aliases file with many exported bash functions inside; a good deal of which are incompatible with sh...

The problem is that sh is used all over my laptop (OS X) and linux machines that I ssh into. In addition it always tries to import my bash functions and spams errors.

The functions in question are:

  • all of my functions that have a '-' in their name (NOTE: these only spam errors on OS X, not linux)
  • and a log() function (below) with syntax that is only legal in bash

    log() {
        # braces allow for piping of same output to multiple files
        { $@ 2> >(tee .err.log); } &> >(tee .out.log);
        echo; echo logged output to .err.log \& .out.log respectively;
    }
    export -f log
    

So how can I solve this problem? I'd prefer it if I didn't have to rename the functions or put them in separate scripts inside a */bin directory...

Thanks for the help!

P.S. screenshot:

enter image description here

EDIT: I see I didn't include enough info. So yes .bash_profile does source .bashrc which in turn sources .bash_aliases (I have no .profile). In addition I have already tried to create an exit clause in .bash_aliases when $SHELL='sh' but it didn't work which is because they are being imported directly from my environment (as @Bodo and the import errors in screen cap indicate).

EDIT2 IMPORTANT: Also strangely I just found out that in the linux machine that I ssh into /bin/sh is a symbolic link to bash. Which means that bash although throwing no errors when sourcing log() actually does throw errors when importing it from the environment??

  • .bash_aliases isn't a standard file. Where are you sourcing it from? Ubuntu sources it in .bashrc, are you doing that? And does your .profile also source .bashrc? – terdon Jun 14 at 15:47
  • I don't know what you mean about it not being 'standard' because many auto-generated .bashrc files I've seen source it. Also yes, both my .bash_profile and my .bashrc do that. – profPlum Jun 14 at 15:49
  • Just find where it's sourced and comment it out. grep -R .bash_aliases ~/ – deimos Jun 14 at 15:55
  • @profPlum "not standard" means that it isn't part of the bash setup. Some systems modify their default bashrc files to source it, but that's up to each individual distribution. I haven't seen it outside Ubuntu, but it might be a Debian thing too. But it certainly isn't a bash thing, so it's easy to avoid. – terdon Jun 14 at 15:57
  • Wait, does your ~/.profile do it too or only your ~/.bash_profile? And what operating systems are you using? Is their /bin/sh actually sh or is it a symlink to /bin/bash or /bin/dash or something else? – terdon Jun 14 at 16:06
2

You should not export the functions. Instead I suggest to source .bash_aliases for all bash instances that need it. (I guess you need the functions in interactive bash shells only.)

A similar problem is mentioned here: /bin/sh: error importing function definition for `some-function', where the accepted answer proposes to rename the functions.

You see the errors even if /bin/sh is linked to bash on your system, because when bash is called as sh, it tries to behave like sh and to comply with POSIX, see https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html#Invoked-with-name-sh

  • correct me if I'm wrong but won't just sourcing the file not bring the functions into the env of the bash shell that sourced it? Your right I only need it for interactive bash (and possibly some of my scripts) but I was under the impression that they needed to be exported to be used interactively? – profPlum Jun 14 at 16:19
  • @profPlum no, not at all. You only need to export them if you will need them in child shells launched by your main one. Does not exporting solve it? Kudos to Bodo, if so, but that's really surprising since exported functions won't be carried over to the remote shell you ssh into. – terdon Jun 14 at 16:38
  • @terdon: I have the roughly the same setup on both machines (similar .bashrc and same .bash_aliases). So that is why they 'carry'. Also that is good to know, I will try that now and see what happens. – profPlum Jun 14 at 16:57
  • @profPlum to assuage my curiosity, could you give an example of when this was happening? I can't reproduce through ssh. Did you only see these messages on your local machine or when running a script? – terdon Jun 14 at 17:05
  • Bodo: thanks that worked! didn't know I didn't need to export :) @terdon: also thanks for your help & extra effort, I would upvote you but I don't have the reputation to do it. If I get that rep soon I will. Both of you have a good day! :) – profPlum Jun 14 at 17:06
2

The simple solution is to not source them. Since ~/.bash_aliases isn't a standard file, you must be explicitly sourcing it in one of your config files. So an easy solution would be to find the line that source it (most likely in your ~/.bashrc) and change it from this (or whatever your system has, this one is from Ubuntu):

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

To this:

if [ -f ~/.bash_aliases ] && [ -n "$BASH_VERSION" ]; then
    . ~/.bash_aliases
fi

That way, the .bash_aliases file will only be sourced when running bash.


To clarify, what I am assuming is happening here based on the information in your question and comments, is the following:

  1. You are sshing into a machine.

  2. Because you are sshing into it, this launches the default /bin/sh as a login shell.

  3. Since this is a login shell, it will source ~/.profile.

  4. Because your .profile is set up to source ~/.bashrc (again, not standard, but common), you now read .bashrc although you might not be running bash.

  5. Since your .bashrc is set up to source ~/.bash_aliases, you read that file too and that produces the errors.

Yet another reason why I personally am not a fan of the decision some systems have made to make the default ~/.bashrc source ~/.profile.

  • Probably /bin/sh does not source .bash_aliases, but the exported function is passed to sh, see unix.stackexchange.com/q/157547/330217 – Bodo Jun 14 at 15:58
  • @Bodo I don't see the relevance. sh is sourcing .bash_aliases because the OP is logging into a remote machine, so starting a login shell. Login shells read .profile and the OP's .profile is set to source .bashrc which, in turn, sources .bash_aliases :) – terdon Jun 14 at 16:01
  • @Bodo see updated answer, I explained it a bit more. – terdon Jun 14 at 16:05
  • The OP wrote explicitly about "exported functions". I may have overlooked it, but where did you find the information that .profile sources .bashrc? – Bodo Jun 14 at 16:06
  • @Bodo yeah, I am sort of assuming that the functions aren't actually exported since the question doesn't show any export -f. I took that to be a misunderstanding of the OP's. The rest I got because we know the OP is running a login shell and yet stuff defined in bashrc is being called and from this comment. – terdon Jun 14 at 16:07

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.