«Синтаксическая ошибка рядом с неожиданным токеном» после редактирования .bashrc

Я пытаюсь получить доступ к буферу обмена, но когда я ввожу source ~/.bashrc в терминал, я получаю эту ошибку:

bash: /home/taran/.bashrc: line 2: syntax error near unexpected token ('
bash: /home/taran/.bashrc: line 2:alias pbpaste='xclip -selection 
clipboard -o'# ~/.bashrc: executed by bash(1) for non-login shells

Я пытался сделать урок в ответе Гэри Вудфайна до Доступ к буферу обмена из командной строки .

Выходные данные cat ~/.bashrc:

alias pbcopy='xclip -selection clipboard'
alias pbpaste='xclip -selection clipboard -o'# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth

# append to the history file, don't overwrite it
shopt -s histappend

# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000

# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize

# If set, the pattern "**" used in a pathname expansion context will
# match all files and zero or more directories and subdirectories.
#shopt -s globstar

# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"

# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi

# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
    xterm-color|*-256color) color_prompt=yes;;
esac

# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes

if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
    # We have color support; assume it's compliant with Ecma-48
    # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
    # a case would tend to support setf rather than setaf.)
    color_prompt=yes
    else
    color_prompt=
    fi
fi

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt

# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
    ;;
*)
    ;;
esac

# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    alias ls='ls --color=auto'
    #alias dir='dir --color=auto'
    #alias vdir='vdir --color=auto'

    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
fi

# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'

# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'

# Add an "alert" alias for long running commands.  Use like so:
#   sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

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

# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

Это на Ubuntu 19.04. Может кто-нибудь помочь мне понять, как это исправить?

11
задан 5 September 2019 в 05:27

2 ответа

Протест находится во второй строке:

alias pbcopy='xclip -selection clipboard'
alias pbpaste='xclip -selection clipboard -o'# ~/.bashrc: executed by bash(1) for non-login shells.

Это должно быть:

alias pbcopy='xclip -selection clipboard'
alias pbpaste='xclip -selection clipboard -o'
# ~/.bashrc: executed by bash(1) for non-login shells.

Похоже, что Вы забыли совершать нападки, Входят после ввода второго псевдонима, который привел к # ~/.bash... непосредственно после Вашего alias определение в той же строке. Без предыдущего пространства # ~/.bash... не мог быть интерпретирован как комментарий оболочки, но как часть аргумента alias команда.

Я также рекомендовал бы поместить псевдонимы в файл ~/.bash_aliases который будет получен когда ~/.bashrc выполняется, таким образом, Вы не должны редактировать ~/.bashrc и в конечном счете испортите его.

Если Вы настаиваете на том, чтобы помещать псевдонимы в ~/.bashrc, добавьте их в конце файла.

Для более глубокого понимания этой темы обратитесь к превосходному ответу Eliah на свой вопрос.

16
ответ дан 23 November 2019 в 03:51

mook765 совершенно корректен о причине проблемы, и решение, предложенное в том ответе, фиксирует синтаксическую ошибку, но я рекомендую решить его по-другому.

Хорошо вставлять определения псевдонима .bashrc, но лучше не поместить их - или что-либо - в самом верху того файла.

Мы склонны думать .bashrc как получаемый только интерактивными оболочками, но это - на самом деле не случай. Неинтерактивные удаленные оболочки (если удар определяет их как таковой), также источник .bashrc. Именно поэтому значение по умолчанию Ubuntu .bashrc1 содержит этот code:2

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

В основном все Вы вставляете .bashrc, включая, но не ограничиваясь, определениями псевдонима, должен пойти куда-нибудь ниже этого. Необходимо только когда-либо помещать собственный код выше того кода, если у Вас есть ясная причина сделать так, который редок.

Можно поместить определения псевдонима где угодно ниже того кода, хотя я предлагаю поместить их в самый конец файла. Или Вы могли бы предпочесть помещать их около некоторых существующих определений псевдонима в файле. Или Вы могли бы предпочесть помещать их в отдельный файл ~/.bash_aliases, который можно создать, если это не существует 3, Любой этот выбор прекрасен.

Вот один из более типичных примеров причудливых и неожиданных эффектов, помещая собственный код выше проверки интерактивности, может иметь. Та конкретная проблема происходит, когда код производит вывод, которого не должно происходить из определения псевдонима. (Псевдоним при использовании может, конечно, расшириться до команды, которая производит вывод, но синтаксически корректное определение псевдонима не должно производить вывод если -p опция передается alias.) Я не ожидаю, что определения псевдонима обычно вызовут проблемы, даже если они будут работать в неинтерактивных оболочках. Неинтерактивные оболочки не выполняют расширение псевдонима по умолчанию так или иначе (хотя это - просто значение по умолчанию). Однако, если они действительно заканчивают тем, что произвели неожиданные эффекты, вероятно, что никто не будет думать для проверки этого.

Это - по общему признанию только слабая причина постараться не помещать определения псевдонима выше интерактивности, регистрируются .bashrc. Однако с тех пор нет абсолютно никакого преимущества выполнения так по сравнению с помещением их больше нигде в файле, я рекомендую после общего подхода только помещения кода выше той проверки, которую Вы сознательно намереваетесь осуществить в неинтерактивных удаленных оболочках.


Другой интересный аспект этого - то, почему это было синтаксической ошибкой:

alias pbpaste='xclip -selection clipboard -o'# ~/.bashrc: executed by bash(1) for non-login shells.

# запускает комментарии, которым разрешают следовать за командами. Однако # символ не имеет эффекта запуска комментария, когда это появляется в большем слове, за исключением первого символа того слова. (В этом смысле "слово" включает вещи как pbpaste='xclip -selection clipboard -o'#, из-за заключения в кавычки.) Следующий текст, который был предназначен как комментарий, взят в качестве дополнительных аргументов alias встроенный. Но ошибка происходит при парсинге их, из-за неожиданного присутствия (, который имеет особое значение к оболочке, но который не имеет смысла в том контексте. Эффект состоит в том что alias встроенный на самом деле никогда не работает, и Вы получаете синтаксическую ошибку вместо этого.

Поэтому на самом деле было бы возможно зафиксировать синтаксическую ошибку с редактированием с одним символом путем помещения пространства между ' и # символы на той строке. Но, как детализировано выше, я рекомендую идти далее и переместить определения псевдонима намного ниже в файл.


1The значение по умолчанию .bashrc в Ubuntu может быть просмотрен в /etc/skel/.bashrc, пока Вы не изменили тот файл. Это копируется в корневой каталог пользователя, когда пользователь создается. Как много файлов в Ubuntu, этот файл минимально изменяется от Debian, распределения, из которого получена Ubuntu. Совет в этом сообщении относится, избивают Debian, а также Ubuntu, но это не обязательно применяется без модификации для избиения всех систем GNU/Linux.

2It также возможно, хотя редкий, запуститься bash как неинтерактивная оболочка входа в систему. Как интерактивные оболочки входа в систему, такие источники оболочки ~/.profile автоматически, и значение по умолчанию ~./profile в Ubuntu явно источники ~/.bashrc. Помимо предотвращения неумышленного выполнения в неинтерактивных удаленных оболочках, помещая Ваши дополнения к ~/.bashrc ниже проверки интерактивности также препятствует тому, чтобы он был неумышленно выполнен в странном случае неинтерактивной оболочки входа в систему.

3Ubuntu's значение по умолчанию .bashrc проверки, если ~/.bash_aliases существует ([ -f ~/.bash_aliases ]) и источники это (. ~/.bash_aliases) если это делает. Код, который Вы отправили, проверяет что Ваш измененный .bashrc файл действительно выполняет те действия - похоже, что единственное изменение в нем было кодом, который Вы добавили наверху.

20
ответ дан 23 November 2019 в 03:51

Другие вопросы по тегам:

Похожие вопросы: