![语法错误后未找到 Bash 命令](https://linux22.com/image/716721/%E8%AF%AD%E6%B3%95%E9%94%99%E8%AF%AF%E5%90%8E%E6%9C%AA%E6%89%BE%E5%88%B0%20Bash%20%E5%91%BD%E4%BB%A4.png)
我遇到一个问题,在 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
}
它是什么应该要做的就是采取当前的PATH
(printf "$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