1

While following instructions at a forum post to install something over ssh at an external machine, I executed the following command without thinking:

. .bashrc

I have never seen the command before but am guessing (from having had a similar problem previously) that it recursively sources ~/.bashrc because now I can't execute any commands. When I login, I can't do anything. I immediately get:

-bash: /usr/bin/whoami: Argument list too long
-bash: /usr/bin/cut: Argument list too long
-bash: /usr/bin/logger: Argument list too long 

Unfortunately, I can't do what solved the problem when I had a similar problem in the past (login without using the bash shell by doing ssh -t user@host /bin/sh and then modify ~/.bashrc) because there does not seem to be any problem with ~/.bashrc. It looks exactly the same as it did before I messed up.

Whatever I did, modifying ~/.bashrc does not appear to be a fix. Can anyone please suggest an alternative solution?


Here is ~/.bashrc:

# .bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
       . /etc/bashrc
fi

export PATH=$PATH:$HOME/.local/bin:$HOME/bin
export PATH=$PATH:$HOME/.local/bin:$HOME/bin/prog1:$PATH
export PATH=$PATH:$HOME/.local/bin:$HOME/bin/prog2:$PATH
export PATH=$PATH:$HOME/.local/bin:$HOME/prog2:$PATH
export PATH=$PATH:$HOME/.local/bin:$HOME/prog2/bin:$PATH
export PATH=$PATH:$HOME/.local/bin:$HOME/bin/prog3/tools/newtool:$PATH

export PYTHONPATH=$PATH:$HOME/.local/bin:$HOME/prog2:$PYTHONPATH
4
  • For starters, please add your complete $HOME/.bashrc to your question. Commented May 5, 2021 at 22:03
  • @ajgringo619, thank you. I edited the question.
    – Ant
    Commented May 5, 2021 at 22:14
  • 2
    The problem does not come from your .bashrc, it comes from some other configuration file. This could be /etc/bashrc or something else. What is the output of the following command? set -x; ulimit -a; echo foo; /bin/echo bar Commented May 5, 2021 at 22:25
  • @Gilles'SO-stopbeingevil', I pasted the command you suggested and the output as an edit to the question. To do this, I had to login without using the bash shell by using the method I mentioned in my question.
    – Ant
    Commented May 5, 2021 at 22:28

2 Answers 2

7

. .bashrc would run the contents of .bashrc in the current shell. Usually, you don't need to do that, since .bashrc is read by the shell when it starts, but if you make modifications to it and want to reload them, you might do that.

But doing that in one interactive shell shouldn't affect other shells you start on later logins.


What you have there in .bashrc, is somewhat odd, though:

export PATH=$PATH:$HOME/.local/bin:$HOME/bin/prog1:$PATH
            ^^^^^                                  ^^^^^

Note how you're putting the old $PATH to the start and end of the new PATH, five different times. By my count, that would put the original $PATH there 32 times. That's not too bad, but if that has been done when the shell starts, your $PATH would now be some thousands of characters, and if you then do the same thing again, it might end up being far longer than 100 kB. Starting with my $PATH of 74 chars, running those assignments twice gives a string of 172 kB.

And that might be a problem: Linux has limit of 128 kB for the length of a single command line argument (in addition to a limit for the whole lot). Environment variables and command line arguments are passed similarly on execve(), so presumably the same limit applies to both, and hence PATH.

1
  • thank you for explaining that. I just tried removing the line (in the non-bash shell) and then logged in in bash. Unfortunately, I still have the same problem. The line did exist before today.
    – Ant
    Commented May 5, 2021 at 22:35
5

Replace the first set of export lines with this

export PATH="$PATH:$HOME/.local/bin:$HOME/bin"
[[ -d "$HOME/bin/prog1" ]] && PATH="$PATH:$HOME/bin/prog1"
[[ -d "$HOME/bin/prog2" ]] && PATH="$PATH:$HOME/bin/prog2"
[[ -d "$HOME/prog2" ]] && PATH="$PATH:$HOME/prog2"
[[ -d "$HOME/prog2/bin" ]] && PATH="$PATH:$HOME/prog2/bin"
[[ -d "$HOME/bin/prog3/tools/newtool" ]] && PATH="$PATH:$HOME/bin/prog3/tools/newtool"

What was happening was that you were doubling up $PATH on every line ($PATH + new item + $PATH). Very strange.

In this replacement code each [[ ... ]] section ensures the corresponding directory exists before adding it to your $PATH. Not essential but certainly cleaner

11
  • Thank you!! I am going to have to get some sleep and read your solution with a fresh brain to figure out what I was doing wrong, but it seems to have worked. I can login on bash. One thing that still doesn't work is that I still can't access "prog3" that I just installed. I'm getting "No such file or directory" so still have an issue somewhere. However, I'm happy to be able to login!! Thank you very much.
    – Ant
    Commented May 5, 2021 at 22:44
  • yes, I accepted the answer. Thanks again.
    – Ant
    Commented May 5, 2021 at 22:46
  • It's not necessary to export the variable everywhere: it's already exported. Commented May 6, 2021 at 1:28
  • @glennjackman ah yes. Thank you, code amended Commented May 6, 2021 at 6:08
  • you can also use && [[ ! "$PATH" =~ "$HOME/bin/prog1" ]] to prevent a directory from being added to $PATH if it's already in it. e.g. something like for d in dir1 dir2 dir3 ; do [[ -d "$d" ]] && [[ ! "$PATH" =~ "\<$d\>" ]] && PATH="$PATH:$d" ; done (\< and \> are the ERE equivalents to PCRE's \b).
    – cas
    Commented May 6, 2021 at 7:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .