"Syntaxfehler in der Nähe eines unerwarteten Tokens" nach dem Bearbeiten von .bashrc

11

Ich versuche, auf die Zwischenablage zuzugreifen, aber wenn ich source ~/.bashrc in das Terminal eingebe, wird folgende Fehlermeldung angezeigt:

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

Ich habe versucht, das Tutorial in Gary Woodfines Antwort auf Command Line Clipboard Access zu erstellen .

Die Ausgabe von cat ~/.bashrcist:

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

Dies ist auf Ubuntu 19.04. Kann mir jemand helfen, herauszufinden, wie ich das beheben kann?

Taran
quelle

Antworten:

16

Die Einschränkung ist in der zweiten Zeile:

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

Das sollte sein:

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

Es sieht so aus, als hätten Sie vergessen, Enternach Eingabe des zweiten Alias zu treffen, was dazu führte, dass Sie # ~/.bash...Ihrer aliasDefinition in derselben Zeile direkt folgten . Ohne ein vorangestelltes Leerzeichen # ~/.bash...könnte dies nicht als Kommentar der Shell interpretiert werden, sondern als Teil des Argumentes des aliasBefehls.

Ich würde auch empfehlen, Aliase in die Datei ~/.bash_aliaseseinzufügen, die bei der ~/.bashrcAusführung bezogen werden, damit Sie sie nicht bearbeiten ~/.bashrcund eventuell durcheinander bringen müssen.

Wenn Sie darauf bestehen, Aliase einzufügen ~/.bashrc, fügen Sie sie am Ende der Datei hinzu.

Weitere Informationen zu diesem Thema finden Sie in Eliahs hervorragender Antwort auf Ihre Frage.

mook765
quelle
6
Diese Antwort wäre viel besser, wenn Sie erklären würden, warum das Update funktioniert
Andy
Vielen Dank! Übrigens, selbst wenn man meinen Rat nicht befolgt, die Aliase irgendwo nach der Interaktivitätsprüfung zu platzieren, empfehle # ~/.bashrc: executed by bash(1) for non-login shells.ich, als erste Zeile beizubehalten. Es gibt keinen technischen Grund, warum es zuerst (oder überhaupt) erscheinen muss. Aber es ist ein Kommentar, der die gesamte Datei dokumentiert. Daher ist es für menschliche Leser ziemlich verwirrend, dass es nach anderem Code erscheint. Ich verstehe, wenn Sie das nicht ändern wollen, zumal das OP diese Antwort so akzeptierte, wie sie war. (Ich denke, dass es unter den gegebenen Umständen sinnvoll ist , dafür zu arbeiten oder es einfach zu verlassen.)
Eliah Kagan
'preseed' - meintest du 'vor'?
Michael Harvey
20

mook765 ist in Bezug auf die Ursache des Problems völlig korrekt , und die in dieser Antwort vorgeschlagene Lösung behebt den Syntaxfehler. Ich empfehle jedoch, ihn auf eine andere Weise zu lösen.

Es ist in Ordnung, Alias-Definitionen einzufügen .bashrc, aber es ist am besten, sie - oder irgendetwas - nicht ganz oben in diese Datei zu setzen.

Wir neigen dazu, uns vorzustellen, dass .bashrcsie nur von interaktiven Shells bezogen werden, aber dies ist tatsächlich nicht der Fall. Nicht interaktive Remote-Shells ( wenn Bash sie als solche identifiziert ) sind ebenfalls Quellen .bashrc. Aus diesem Grund enthält Ubuntus Standard .bashrc1 diesen Code: 2

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

Grundsätzlich sollte alles, was Sie eingeben .bashrc, einschließlich, aber nicht beschränkt auf Alias-Definitionen, irgendwo darunter liegen. Sie sollten Ihren eigenen Code immer nur über diesen Code setzen, wenn Sie einen eindeutigen Grund dafür haben, was selten vorkommt.

Sie können Ihre Alias-Definitionen an einer beliebigen Stelle unterhalb dieses Codes einfügen . Ich empfehle jedoch, sie ganz am Ende der Datei einzufügen. Oder Sie möchten sie lieber in der Nähe einiger der vorhandenen Aliasdefinitionen in der Datei platzieren. Oder Sie möchten sie lieber in einer separaten Datei ablegen ~/.bash_aliases, die Sie erstellen können, wenn sie nicht vorhanden ist. 3 Jede dieser Optionen ist in Ordnung.

Hier ist eines der häufigsten Beispiele für die bizarren und unerwarteten Effekte, die das Setzen des eigenen Codes über die Interaktivitätsprüfung haben kann. Dieses spezielle Problem tritt auf, wenn der Code eine Ausgabe erzeugt, die nicht von einer Aliasdefinition ausgehen sollte. (Wenn der Alias ​​verwendet wird, kann er natürlich zu einem Befehl erweitert werden, der eine Ausgabe erzeugt, aber eine syntaktisch korrekte Aliasdefinition sollte keine Ausgabe erzeugen, es sei denn, die -pOption wird übergeben alias.) Ich erwarte nicht, dass Aliasdefinitionen normalerweise Probleme verursachen, selbst wenn sie auftreten in nicht interaktiven Shells laufen. Nicht interaktive Shells führen ohnehin standardmäßig keine Alias-Erweiterung durch (obwohl dies lediglich eine Standardeinstellung ist). Wenn sie jedoch unerwartete Effekte hervorrufen, wird wahrscheinlich niemand daran denken, dies zu überprüfen.

Dies ist zugegebenermaßen nur ein schwacher Grund, um zu vermeiden, dass Aliasdefinitionen über dem Einchecken der Interaktivität stehen .bashrc. Da es jedoch mache ich durchaus kein Vorteil ist so im Vergleich zu ihnen irgendwo sonst in der Datei setzen, empfehlen folgende ich den allgemeinen Ansatz von nur über diesem Prüfcodes setzen , dass Sie bewusst die Absicht , in nicht-interaktiven Fernschalen zu laufen.


Der andere interessante Aspekt ist, warum dies ein Syntaxfehler war:

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

#Startet Kommentare, die Befehlen folgen dürfen. Das #Zeichen hat jedoch nicht den Effekt, einen Kommentar zu starten, wenn er in einem größeren Wort erscheint, außer als erstes Zeichen dieses Wortes. (In diesem Sinne „Wort“ gehören Dinge wie pbpaste='xclip -selection clipboard -o'#, aufgrund zitiert .) Der folgende Text, der als Kommentar gedacht war, wird als zusätzliche Argumente an die genommen aliasbuiltin. Beim Parsen tritt jedoch ein Fehler auf, der auf das unerwartete Vorhandensein von zurückzuführen ist (, das für die Shell eine besondere Bedeutung hat, in diesem Zusammenhang jedoch keinen Sinn ergibt. Der Effekt ist, dass das aliaseingebaute System tatsächlich nie ausgeführt wird und Sie stattdessen einen Syntaxfehler erhalten.

Daher wäre es tatsächlich möglich, den Syntaxfehler mit einer Bearbeitung mit einem Zeichen zu beheben , indem in diese Zeile ein Leerzeichen zwischen 'und #eingefügt wird. Wie oben beschrieben, empfehle ich jedoch, weiter zu gehen und die Aliasdefinitionen in der Datei viel tiefer zu verschieben.


1 Die Standardeinstellung.bashrcin Ubuntu kann unter angezeigt werden/etc/skel/.bashrc, sofern Sie diese Datei nicht geändert haben. Dies wird beim Erstellen des Benutzers in das Home-Verzeichnis eines Benutzers kopiert. Wie viele Dateien in Ubuntu wird diese Datei gegenüber Debian, der Distribution, von der Ubuntu abgeleitet ist, nur minimal geändert. Der Rat in diesem Beitrag gilt sowohl für Bash in Debian als auch für Ubuntu, gilt jedoch nicht unbedingt ohne Änderung für Bash in allen GNU / Linux-Systemen.

2 Es ist auch möglich , obwohl selten,bashals nicht interaktive Anmeldeshellzu starten. Wie interaktive Login-Shells werden solche Shell-Quellen~/.profileautomatisch und die Standardeinstellungen~./profilein Ubuntu explizit als Quellen verwendet~/.bashrc. Neben der Verhinderung einer unbeabsichtigten Ausführung in nicht interaktiven Remote-Shells wird durch das Unterstellen Ihrer Ergänzungen~/.bashrcunterhalb der Interaktivitätsprüfung auch verhindert, dass sie im seltsamen Fall einer nicht interaktiven Anmeldeshell unbeabsichtigt ausgeführt werden.

3 Ubuntus Standard.bashrcprüft, ob es~/.bash_aliasesexistiert ([ -f ~/.bash_aliases ]) und gibt es (. ~/.bash_aliases) an, wenn dies der Fall ist. Der von Ihnen veröffentlichte Code überprüft, ob Ihre geänderte.bashrcDatei diese Aktionen ausführt. Es sieht so aus, als ob die einzige Änderung daran der Code war, den Sie oben hinzugefügt haben.

Eliah Kagan
quelle
Diese Antwort deckte alle Fragen ab, die ich hatte, großartig (vielleicht sollte erwähnt werden, dass .bash_aliases voraussichtlich von .bashrc bezogen wird
eckes
@EliahKagan, eigentlich habe ich diesen Satz in der Mitte nicht bemerkt, whoops. Die Betonung, die diese Antwort auf die Position der Aliase legt, ließ sie so lesen, als wäre es ein größeres Problem als es wirklich ist. Wie es wäre, wenn z. B. die Aliase auch in nicht interaktiven Schalen angewendet würden ... Ich sehe Ihren Standpunkt darin, zuerst den Schutzzustand beizubehalten, aber wir scheinen uns nicht einig zu sein, in welcher Reihenfolge diese verschiedenen Themen priorisiert werden sollten. ;)
ilkkachu
@ilkkachu Ja, es ist möglich, dass wir uns darüber nicht einig sind. Andererseits habe ich angefangen, diese Antwort zu schreiben, nachdem mook765 bereits veröffentlicht wurde und das OP sie bereits als akzeptiert markiert hatte. Daher habe ich mich entschlossen, diese Antwort mit einem Verweis auf diese Antwort zu beginnen (" mook765 ist in Bezug auf die Ursache des Problems völlig korrekt , und die in dieser Antwort vorgeschlagene Lösung behebt den Syntaxfehler"), bevor ich den größten Teil meiner restlichen Antwort auf die Frage zum alternative Lösung, um sie an einem anderen Ort als ganz oben in der Datei zu platzieren.
Eliah Kagan
2
@eckes Vielen Dank für den Rat - ich habe ein paar Endnoten hinzugefügt, um das und einige verwandte Themen für die interessierten Leser zu behandeln. (Der Grund , warum ich nicht berücksichtigen ~/.bashrcSourcing ~/.bash_aliasesein zu besonders wichtiger Punkt in diesem Zusammenhang ist , dass Inspektion den der OP - ~/.bashrcDatei zeigt , dass der Code, der so tut , blieb intakt. Es ist jedoch sowohl relevant und interessant, und du bist Recht, vorzuschlagen, dass es erwähnt wird.)
Eliah Kagan