语法错误后未找到 Bash 命令

语法错误后未找到 Bash 命令

我遇到一个问题,在 Ubuntu 14.04.5 LTS 上运行常见的 bash 命令(例如 ls、mv、rsync、vi)会导致如下结果: bash: rsync: command not found

当我通过 ssh 登录时出现此错误(在 shell 中运行任何命令之前):

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

我可以通过在与 python 和 pythonbrew 设置相关的文件~/.bash_profile中注释掉这些行来修补该问题:~/.bashrc

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

但是,这些行似乎不太可能是根本原因,因为这些文件多年来都没有被修改过(并且 bash 命令只是在最近几天才停止工作)。

有什么想法吗?


内容~/.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

答案1

好吧,我可以告诉你发生了什么,但我不确定为什么确实发生了。您刚刚安装了新版本的 bash 吗?据我所知,原因一定是 bash 解析某些替换的方式发生了微小变化。顺便说一句,我也会猜测如何修复它,但如果不了解根本原因,它们就只是猜测。

问题发生__pythonbrew_set_path在〜/ .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
}

它是什么应该要做的就是采取当前的PATHprintf "$PATH"),删除对 python brew 目录的所有引用(命令awk),删除添加到末尾的杂散“:”(命令sed,将其存储在中PATH_WITHOUT_PYTHONBREW,然后设置一个新的PATH包含PATH_PYTHONBREW加上清理过的旧的PATH

实际发生的情况是命令中存在语法错误awk,因此它没有输出任何内容,PATH_WITHOUT_PYTHONBREW最终完全是空白,因此实际上除了 之外的所有内容PATH_PYTHONBREW都会从 中删除PATH

命令失败的原因awk${PATH_ROOT//\//\/}没有按预期执行。它应该采用PATH_ROOT(python brew 目录的路径,“/home/myuser/.pythonbrew/”)并在每个之前添加转义符/。以下是它如何执行的示例应该操作:

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

如果您在 shell 中尝试这样做,我认为它会打印“/home/myuser/.pythonbrew/”(无转义)。您可以在awk收到的错误消息中看到此字符串(未转义的版本)。这导致awk错误的原因是awk用于/标记搜索模式的开始和结束;当它们出现在开始和结束处时和中间(没有转义),它会感到困惑。

那么为什么不${PATH_ROOT//\//\/}添加转义符呢?这就是我困惑的地方。我最好的猜测是,这是由于 bash 解析替换的方式发生了变化。bash 应该这样读取它:获取变量的值 ( PATH_ROOT),并将所有 ( //) 出现的斜杠字符 ( \/-- 请注意,它已转义,因此不会被误认为是模式的结尾) 替换为 ( /-- 这个没有转义,因为它模式的末尾)字符串\/\/)。

我的第一个猜测是,出于某种原因,bash 删除了替换字符串中“/”之前的转义符,就像在要替换的模式中一样。如果是这样,在替换字符串中添加一个额外的转义符应该可以解决这个问题。在你的 shell 中尝试一下:

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

在我的系统中,它的作用与第一个相同;如果它在您的系统中有效(添加转义符),请awk在 ~/.pythonbrew/etc/bashrc 中的命令中添加相应的反斜杠,然后就可以了。如果不行,请尝试这些命令,并让我知道您的 shell 如何处理它们(我已包含我的 shell 的输出以供比较):

$ 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/

答案2

看起来您已经在 Windows 上使用 Windows 新行创建了脚本。

请将脚本保存为 Unix 文件或制作

dos2unix < script_dos.sh > script_unix.sh

答案3

听起来你的路径被 python 导出命令破坏了。尝试将 python 内容放在最后。

改变这一点:

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

对此:

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

相关内容