web-dev-qa-db-fra.com

"erreur de syntaxe près d'un jeton inattendu" après avoir modifié .bashrc

J'essaie d'accéder au presse-papiers mais quand je saisis source ~/.bashrc dans le terminal, j'obtiens cette erreur:

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

J'ai essayé de faire le tutoriel dans réponse de Gary Woodfine à accès au presse-papiers en ligne de commande .

La sortie de cat ~/.bashrc est:

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

C'est sur Ubuntu 19.04. Quelqu'un peut-il m'aider à comprendre comment résoudre ce problème?

11
taran

La mise en garde est dans la deuxième ligne:

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

Ça devrait être:

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

On dirait que tu as oublié de frapper Enter après avoir entré le deuxième alias qui a abouti à # ~/.bash... en suivant directement votre définition de alias sur la même ligne. Sans espace précédent # ~/.bash... ne pouvait pas être interprété comme un commentaire par le shell mais comme une partie de l'argument de la commande alias.

Je recommande également de placer des alias dans le fichier ~/.bash_aliases qui proviendra lorsque ~/.bashrc est exécuté, vous n'avez donc pas besoin de modifier ~/.bashrc et finalement gâcher.

Si vous insistez pour placer des alias dans ~/.bashrc, ajoutez-les à la fin du fichier.

Pour un aperçu plus approfondi de ce sujet, veuillez vous référer à l'excellente réponse d'Eliah à votre question.

16
mook765

mook765 est tout à fait correct sur la cause du problème, et la solution proposée dans cette réponse corrige l'erreur de syntaxe, mais je vous recommande de le résoudre d'une manière différente.

C'est bien de mettre des définitions d'alias dans .bashrc, mais il est préférable de ne pas les mettre - ou quoi que ce soit - tout en haut de ce fichier.

Nous avons tendance à penser à .bashrc comme provenant uniquement de shells interactifs, mais ce n'est en fait pas le cas. Shells distants non interactifs ( si bash les identifie comme tels ) source également .bashrc. C'est pourquoi par défaut d'Ubuntu .bashrc 1  contient ce code: 2

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

Fondamentalement, tout ce que vous mettez dans .bashrc, y compris, mais sans s'y limiter, les définitions d'alias, devrait aller quelque part en dessous. Vous ne devriez jamais mettre votre propre code au-dessus de ce code que si vous avez une raison claire de le faire, ce qui est rare.

Vous pouvez mettre vos définitions d'alias n'importe où en dessous de ce code , bien que je suggère de les mettre à la toute fin du fichier. Vous pouvez également préférer les placer près de certaines définitions d'alias existantes dans le fichier. Ou vous préférerez peut-être les mettre dans un fichier séparé ~/.bash_aliases, que vous pouvez créer s'il n'existe pas. 3  Chacun de ces choix est très bien.

Voici l'un des exemples les plus courants des effets bizarres et inattendus de mettre son propre code ci-dessus le contrôle d'interactivité peut avoir. Ce problème particulier se produit lorsque le code produit une sortie, ce qui ne devrait pas se produire à partir d'une définition d'alias. (L'alias, lorsqu'il est utilisé, peut bien sûr s'étendre à une commande qui produit une sortie, mais une définition d'alias syntaxiquement correcte ne devrait pas produire de sortie à moins que -p l'option est passée à alias.) Je ne m'attends pas à ce que les définitions d'alias généralement causent des problèmes même si elles s'exécutent dans des shells non interactifs. Les shells non interactifs n'effectuent pas l'expansion d'alias par défaut de toute façon (bien que ce soit simplement une valeur par défaut). Cependant, s'ils finissent par produire des effets inattendus, il est probable que personne ne pensera à vérifier cela.

Ce n'est certes qu'une faible raison pour éviter de placer des définitions d'alias au-dessus du contrôle d'interactivité dans .bashrc. Cependant, étant donné qu'il n'y a absolument aucun avantage à le faire par rapport à les placer n'importe où ailleurs dans le fichier, je recommande de suivre l'approche générale de ne mettre que du code au-dessus de cela pour vérifier délibérément que vous avez l'intention de s'exécuter coquilles distantes non interactives.


L'autre aspect intéressant de ceci est pourquoi c'était une erreur de syntaxe:

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

# démarre les commentaires, qui sont autorisés à suivre les commandes. Cependant, le # le caractère n'a pas pour effet de démarrer un commentaire lorsqu'il apparaît dans un mot plus grand, sauf en tant que premier caractère de ce mot. (En ce sens, "Word" inclut des choses comme pbpaste='xclip -selection clipboard -o'#, en raison de la citation .) Le texte suivant, qui était destiné à être un commentaire, est considéré comme des arguments supplémentaires à la fonction intégrée alias. Mais une erreur se produit lors de leur analyse, en raison de la présence inattendue de (, qui a une signification particulière pour le Shell, mais qui n'a pas de sens dans ce contexte. L'effet est que la fonction intégrée alias ne s'exécute jamais et vous obtenez une erreur de syntaxe à la place.

Par conséquent, il serait en fait possible de corriger l'erreur de syntaxe avec une modification à un caractère , en mettant un espace entre les ' et # caractères sur cette ligne. Mais comme détaillé ci-dessus, je recommande d'aller plus loin et de déplacer les définitions d'alias beaucoup plus bas dans le fichier.


1 Le défaut .bashrc dans Ubuntu peut être consulté sur /etc/skel/.bashrc, tant que vous n'avez pas modifié ce fichier. Il est copié dans le répertoire personnel d'un utilisateur lors de sa création. Comme de nombreux fichiers dans Ubuntu, ce fichier est légèrement modifié de Debian, la distribution dont Ubuntu est dérivé. Les conseils de ce post s'appliquent à Bash dans Debian ainsi qu'à Ubuntu, mais ils ne s'appliquent pas nécessairement sans modification à Bash dans tous les systèmes GNU/Linux.

2 Il est également possible , bien que rare, de démarrer bash en tant que shell de connexion non interactif. Comme les shells de connexion interactifs, un tel shell source ~/.profile automatiquement et la valeur par défaut ~./profile dans Ubuntu source explicitement ~/.bashrc. En plus d'empêcher l'exécution involontaire dans des shells distants non interactifs, placer vos ajouts dans ~/.bashrc sous le contrôle d'interactivité l'empêche également d'être exécuté involontairement dans le cas étrange d'un shell de connexion non interactif.

3 Par défaut d'Ubuntu .bashrc vérifie si ~/.bash_aliases existe ([ -f ~/.bash_aliases ]) et le source (. ~/.bash_aliases) si c'est le cas. Le code que vous avez publié vérifie que votre .bashrc le fichier effectue ces actions - il semble que la seule modification soit le code que vous avez ajouté en haut.

20
Eliah Kagan