2

I'm running into an issue where running common bash commands (e.g. ls, mv, rsync, vi) on an Ubuntu 14.04.5 LTS results in something like this: bash: rsync: command not found.

When I ssh in I get this error (before running any commands in the shell):

awk: cmd. line:1: //home/myuser/.pythonbrew/ {next} {print} awk: cmd. line:1: ^ syntax error

I was able to patch the issue by commenting out these lines in the ~/.bash_profile and ~/.bashrc files related to setup of python & pythonbrew:

export PATH=~/opt/python-2.7.3/bin:${PATH} export PYTHONPATH=~/opt/python-2.7.3/lib alias pb='pythonbrew' export PYTHONPATH=~/.pythonbrew/pythons/Python-2.7.3/lib [[ -s /home/myuser/.pythonbrew/etc/bashrc ]] && source /home/myuser/.pythonbrew/etc/bashrc

However, those lines seem unlikely to be the root cause, since those files hadn't been modified for years (and the bash commands only stopped working in the last few days).

Thoughts?


Contents of ~/.pythonbrew/etc/bashrc

# settings
PATH_ROOT="$PYTHONBREW_ROOT"
if [ -z "${PATH_ROOT}" ] ; then
    PATH_ROOT="$HOME/.pythonbrew"
fi
PATH_ETC="$PATH_ROOT/etc"

PATH_HOME="$PYTHONBREW_HOME"
if [ -z "${PATH_HOME}" ] ; then
    PATH_HOME="$HOME/.pythonbrew"
fi
PATH_HOME_ETC="$PATH_HOME/etc"

# py file
PY_PYTHONBREW="$PATH_ROOT/bin/pythonbrew"

# functions
__pythonbrew_set_default()
{
    PATH_PYTHONBREW="$PATH_ROOT/bin"
    PATH_PYTHONBREW_LIB="$PATH_ROOT/lib"
}

__pythonbrew_set_path()
{
    PATH_WITHOUT_PYTHONBREW=$(printf "$PATH" | awk -v RS=: -v ORS=: "/${PATH_ROOT//\//\/}/ {next} {print}" | sed -e 's#:$##')
    export PATH=$PATH_PYTHONBREW:$PATH_WITHOUT_PYTHONBREW
    export PYTHONPATH=$PATH_PYTHONBREW_LIB
}

__pythonbrew_set_temp_path()
{
    if [[ -s "$PATH_HOME_ETC/temp" ]] ; then
        source "$PATH_HOME_ETC/temp"
        PATH_PYTHONBREW="$PATH_ROOT/bin:$PATH_PYTHONBREW_TEMP"
        PATH_PYTHONBREW_LIB="$PATH_PYTHONBREW_TEMP_LIB"
    else
        __pythonbrew_set_default
    fi
    __pythonbrew_set_path
}

__pythonbrew_set_current_path()
{
    if [[ -s "$PATH_HOME_ETC/current" ]] ; then
        source "$PATH_HOME_ETC/current"
        PATH_PYTHONBREW="$PATH_ROOT/bin:$PATH_PYTHONBREW_CURRENT"
        PATH_PYTHONBREW_LIB="$PATH_PYTHONBREW_CURRENT_LIB"
    else
        __pythonbrew_set_default
    fi
    __pythonbrew_set_path
}

__pythonbrew_reload()
{
    [[ -s "$PATH_ETC/bashrc" ]] && source "$PATH_ETC/bashrc"
}

__pythonbrew_use()
{
    [[ $? == 0 ]] && __pythonbrew_set_temp_path
}

__pythonbrew_switch()
{
    [[ $? == 0 ]] && __pythonbrew_set_current_path
}

__pythonbrew_off()
{
    [[ $? == 0 ]] && __pythonbrew_set_current_path
}

__pythonbrew_update()
{
    [[ $? == 0 ]] && __pythonbrew_reload
}

__pythonbrew_venv()
{
    if [[ $? == 0 ]] ; then
        if [[ -s "$PATH_HOME_ETC/venv.run" ]] ; then
            source "$PATH_HOME_ETC/venv.run"
            cat /dev/null > "$PATH_HOME_ETC/venv.run"
        fi
    fi
}

__pythonbrew_find_command()
{
    command_name=""
    for arg in "$@" ; do
        case $arg in
            --*) continue;;
            -*) continue;;
            *)
            command_name=$arg
            break
            ;;
        esac
    done
}

__pythonbrew_run()
{
    __pythonbrew_find_command "$@"
    "$pythonbrew" "$@"
    case $command_name in
        use) __pythonbrew_use "$@";;
        switch) __pythonbrew_switch "$@" ;;
        off) __pythonbrew_off "$@" ;;
        update) __pythonbrew_update "$@" ;;
        venv) __pythonbrew_venv "$@" ;;
    esac
    builtin hash -r
}

pythonbrew()
{
    pythonbrew=$PY_PYTHONBREW
    __pythonbrew_run "$@"
}

pybrew()
{
    pythonbrew "$@"
}

sudopybrew()
{
    pythonbrew="sudo PYTHONBREW_ROOT=$PATH_ROOT PATH=$PATH_PYTHONBREW:$PATH_WITHOUT_PYTHONBREW $PY_PYTHONBREW"
    __pythonbrew_run "$@"
}

# main
__pythonbrew_set_current_path
6
  • What does echo $PATH say now?
    – DerfK
    Jan 25, 2018 at 20:28
  • @DerfK /home/myuser/.gems/bin:/usr/lib/ruby/gems/1.8/bin/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
    – bjnsn
    Jan 25, 2018 at 21:36
  • awk only appears once. What are you trying to do there? Jan 25, 2018 at 22:08
  • @MichaelHampton Are you talking about the ~/.pythonbrew/etc/bashrc file? I presume that was auto-generated by pythonbrew install, although its possible another developer wrote it.
    – bjnsn
    Jan 25, 2018 at 22:13
  • If that's generated code, you should seek help from the developer(s) of pythonbrew. Jan 25, 2018 at 22:15

3 Answers 3

2

Well, I can tell you what's happening, but I'm not sure why it's happening. Did you just install a new version of bash? As far as I can see, the cause has to be a small change in how bash parses certain substitutions. BTW, I'll also make some guesses about how to fix it, but without understanding the root cause they're just guesses.

The problem is occurring in the __pythonbrew_set_path function in ~/.pythonbrew/etc/bashrc:

__pythonbrew_set_path()
{
    PATH_WITHOUT_PYTHONBREW=$(printf "$PATH" | awk -v RS=: -v ORS=: "/${PATH_ROOT//\//\/}/ {next} {print}" | sed -e 's#:$##')
    export PATH=$PATH_PYTHONBREW:$PATH_WITHOUT_PYTHONBREW
    export PYTHONPATH=$PATH_PYTHONBREW_LIB
}

What it's supposed to do is take your current PATH (printf "$PATH"), remove all references to the python brew directory (the awk command), remove a stray ":" that got added to the end (the sed command, store that in PATH_WITHOUT_PYTHONBREW, then set a new PATH containing PATH_PYTHONBREW plus the cleaned old PATH.

What's actually happening is that there's a syntax error in the awk command, so it's not outputting anything, so PATH_WITHOUT_PYTHONBREW ends up completely blank, so effectively everything except PATH_PYTHONBREW is removed from your PATH.

The reason the awk command fails is that ${PATH_ROOT//\//\/} isn't doing what it's supposed to. It's supposed to take PATH_ROOT (the path to your python brew directory, "/home/myuser/.pythonbrew/") and add escapes before each /. Here's an example of how it should operate:

$ PATH_ROOT="/home/myuser/.pythonbrew/"
$ printf "%s\n" "${PATH_ROOT//\//\/}"
\/home\/myuser\/.pythonbrew\/

If you try that in your shell, I think it'll print "/home/myuser/.pythonbrew/" (no escapes) instead. You can see this string (the unescaped version) in the awk error message you got. The reason this causes an awk error is that awk uses / to mark the beginning and end of a search pattern; when they occur at the beginning and end and middle (without escapes), it gets confused.

So why isn't ${PATH_ROOT//\//\/} adding escapes? This is where I'm stumped. My best guess is that it's due to a change in exactly how bash parses the substitution here. Here's how bash is supposed to read it: take the variable's value (PATH_ROOT), and replace all (//) occurrences of a slash character (\/ -- note that it's escaped so it's not mistaken for the end of the pattern) with (/ -- this one's not escaped because it is the end of the pattern) the string \/ (\/).

My first guess would be that for some reason bash is removing escapes before "/" in the replacement string just like it does in the pattern to be replaced. If that's the case, adding an extra escape to the replacement string should fix it. Try this in your shell:

$ PATH_ROOT="/home/myuser/.pythonbrew/"
$ printf "%s\n" "${PATH_ROOT//\//\\/}"
\/home\/myuser\/.pythonbrew\/

In mine it does the same thing as the first; if it works (adds escapes) in yours, add the corresponding backslash to the awk command in ~/.pythonbrew/etc/bashrc and you should be good to go. If not, try these commands and let me know what your shell does with them (I've included my shell's output for comparison):

$ PATH_ROOT="/home/myuser/.pythonbrew/"
$ printf "%s\n" "${PATH_ROOT//\//A}" "${PATH_ROOT////A}" "${PATH_ROOT//o/\/}" "${PATH_ROOT//o/\\/}"
AhomeAmyuserA.pythonbrewA
AhomeAmyuserA.pythonbrewA
/h\/me/myuser/.pyth\/nbrew/
/h\/me/myuser/.pyth\/nbrew/
0

Looks like you have created the script on windows with Windows new line.

Please save the script as Unix file or make a

dos2unix < script_dos.sh > script_unix.sh

0

Sounds like your path is getting clobbered by your python export command. Try putting the python stuff at the end.

CHANGE THIS:

export PATH=~/opt/python-2.7.3/bin:${PATH}

TO THIS:

export PATH=$PATH:~/opt/python-2.7.3/bin

You must log in to answer this question.

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