"Errore di sintassi vicino token imprevisto" dopo aver modificato .bashrc


11

Sto provando ad accedere agli appunti ma quando inserisco source ~/.bashrc nel terminale ottengo questo errore:

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

Ho provato a fare il tutorial nella risposta di Gary Woodfine all'accesso agli Appunti dalla riga di comando .

L'output di 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

Questo è su Ubuntu 19.04. Qualcuno può aiutarmi a capire come risolvere questo problema?

Risposte:


16

L'avvertenza è nella seconda riga:

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

Dovrebbe essere:

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

Sembra che ti sei dimenticato di colpire Enterdopo aver inserito il secondo alias che ha portato a # ~/.bash...seguire direttamente la tua aliasdefinizione nella stessa riga. Senza uno spazio precedente # ~/.bash...non potrebbe essere interpretato come un commento dalla shell ma come parte dell'argomento del aliascomando.

Consiglierei anche di inserire gli alias nel file ~/.bash_aliasesche verranno acquistati quando ~/.bashrcviene eseguito, quindi non è necessario modificarli ~/.bashrced eventualmente rovinarli.

Se insisti nel posizionare gli alias ~/.bashrc, aggiungili alla fine del file.

Per approfondimenti su questo argomento, si prega di fare riferimento all'eccellente risposta di Elia alla tua domanda.


6
Questa risposta sarebbe molto meglio se spiegassi perché la correzione funziona
Andy,

Grazie! A proposito, anche se si sceglie di non seguire il mio consiglio di mettere gli alias da qualche parte dopo il controllo dell'interattività, consiglio di # ~/.bashrc: executed by bash(1) for non-login shells.essere tenuto come prima riga. Non c'è motivo tecnico per costringerlo ad apparire per primo (o per niente). Ma è un commento che documenta l'intero file. Quindi è abbastanza confuso per i lettori umani che appaia dopo altri codici. Capisco se non vuoi cambiarlo, soprattutto perché l'OP ha accettato questa risposta com'era. (Penso che il montaggio per questo o semplicemente lasciarlo siano entrambi ragionevoli in base alle circostanze.)
Eliah Kagan,

"preseed" - intendevi "precedere"?
Michael Harvey,

20

mook765 è del tutto corretto sulla causa del problema e la soluzione proposta in quella risposta risolve l'errore di sintassi, ma ti consiglio di risolverlo in modo diverso.

Va bene inserire le definizioni degli alias .bashrc, ma è meglio non metterle - o niente - all'inizio del file.

Tendiamo a pensare .bashrcche provengano solo da shell interattive, ma in realtà non è così. Anche le shell remote non interattive ( se bash le identifica come tali ) sono di origine .bashrc. Ecco perché .bashrc1 predefinito di Ubuntu contiene questo codice: 2

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

Fondamentalmente tutto ciò che inserisci .bashrc, incluso ma non limitato alle definizioni di alias, dovrebbe andare da qualche parte al di sotto di questo. Dovresti sempre mettere il tuo codice sopra quel codice solo se hai un motivo chiaro per farlo, il che è raro.

Puoi mettere le tue definizioni alias ovunque al di sotto di quel codice , anche se suggerisco di metterle alla fine del file. Oppure potresti preferire metterli vicino ad alcune delle definizioni di alias esistenti nel file. Oppure potresti preferire metterli nel file separato ~/.bash_aliases, che puoi creare se non esiste. 3 Qualsiasi di queste scelte va bene.

Ecco uno degli esempi più comuni degli effetti bizzarri e imprevisti che mettono il proprio codice al di sopra del controllo dell'interattività. Questo particolare problema si verifica quando il codice produce output, il che non dovrebbe accadere da una definizione di alias. (L'alias, quando utilizzato, può ovviamente espandersi fino a un comando che produce output, ma una definizione di alias sintatticamente corretta non dovrebbe produrre output a meno che non -pvenga passata l' opzione alias.) Non mi aspetto che le definizioni di alias causino solitamente problemi anche se eseguito in shell non interattive. Le shell non interattive non eseguono comunque l'espansione dell'alias per impostazione predefinita (anche se questo è semplicemente un valore predefinito). Tuttavia, se finiscono per produrre effetti inaspettati, è probabile che nessuno penserà di verificarlo.

Questo è certamente solo un motivo debole per evitare di mettere le definizioni di alias al di sopra del controllo dell'interattività .bashrc. Tuttavia, poiché non vi è assolutamente alcun vantaggio nel farlo rispetto al metterli in qualsiasi altra parte del file, consiglio di seguire l'approccio generale di mettere solo il codice sopra quello che controlla che si intende deliberatamente eseguire in shell remote non interattive.


L'altro aspetto interessante di questo è il motivo per cui si è verificato un errore di sintassi:

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

#avvia commenti, ai quali è consentito seguire i comandi. Tuttavia, il #personaggio non ha l'effetto di iniziare un commento quando appare in una parola più grande, tranne come primo carattere di quella parola. (In questo senso, "parola" include cose come pbpaste='xclip -selection clipboard -o'#, a causa della citazione .) Il seguente testo, che è stato inteso come un commento, è preso come argomento aggiuntivo per l' aliasintegrato. Ma si verifica un errore durante l'analisi, a causa della presenza imprevista di (, che ha un significato speciale per la shell, ma che non ha senso in quel contesto. L'effetto è che il aliasbuiltin in realtà non viene mai eseguito e si ottiene invece un errore di sintassi.

Pertanto, sarebbe effettivamente possibile correggere l'errore di sintassi con una modifica di un carattere , inserendo uno spazio tra i caratteri 'e #su quella riga. Ma come spiegato sopra, ti consiglio di andare oltre e di spostare le definizioni degli alias molto più in basso nel file.


1 È.bashrcpossibile visualizzare l'impostazione predefinitain Ubuntu/etc/skel/.bashrc, purché non sia stato modificato quel file. Questo viene copiato nella home directory di un utente quando l'utente viene creato. Come molti file in Ubuntu, questo file viene minimamente modificato da Debian, la distribuzione da cui deriva Ubuntu. I consigli in questo post si applicano a Bash in Debian e Ubuntu, ma non si applicano necessariamente senza modifiche a Bash in tutti i sistemi GNU / Linux.

2 È anche possibile , sebbene raro, iniziarebashcome shell di login non interattiva. Come le shell di login interattive, tali shell si generano~/.profileautomaticamente e il valore predefinito~./profilein Ubuntu si genera esplicitamente~/.bashrc. Oltre a impedire l'esecuzione involontaria in shell remote non interattive, mettere le tue aggiunte~/.bashrcsotto il controllo di interattività impedisce anche che venga eseguito involontariamente nel caso strano di una shell di login non interattiva.

3 Il default di Ubuntu.bashrccontrolla se~/.bash_aliasesesiste ([ -f ~/.bash_aliases ]) e. ~/.bash_aliasesse lo fa() se lo fa. Il codice che hai pubblicato verifica che il tuo.bashrcfilemodificatoesegua tali azioni: sembra che l'unica modifica apportata sia stata il codice che hai aggiunto in alto.


Quella risposta ha coperto tutte le domande che avevo, grandiose (forse dovrei menzionare che .bash_aliases dovrebbe provenire da .bashrc
eckes,

@EliahKagan, in realtà, non ho notato quella frase nel mezzo, whoops. L'enfasi che questa risposta pone sulla posizione degli alias l'ha fatta leggere come se fosse un problema più grande di quello che è in realtà. Come sarebbe se , ad esempio, gli alias fossero applicati anche in gusci non interattivi ... Vedo il tuo punto su come mantenere prima la condizione di guardia, ma sembra che non siamo d'accordo sull'ordine di priorità di queste diverse questioni. ;)
ilkkachu,

@ilkkachu Sì, è possibile che non siamo d'accordo. D'altra parte, ho iniziato a scrivere questa risposta dopo che Mook765 era già stato pubblicato e l'OP lo aveva già contrassegnato come accettato. Quindi ho deciso di iniziare questa risposta facendo riferimento a quella risposta (" mook765 è del tutto corretto sulla causa del problema e la soluzione proposta in quella risposta corregge l'errore di sintassi") prima di poi sfruttare la maggior parte del resto della mia risposta sul soluzione alternativa di metterli altrove rispetto all'inizio del file.
Eliah Kagan,

2
@eckes Grazie per il consiglio - Ho aggiunto alcune note di chiusura per coprire questo e alcuni problemi correlati, per quei lettori che sono interessati. (Il motivo per cui non considero l' ~/.bashrcapprovvigionamento ~/.bash_aliasesun punto particolarmente importante in questo contesto è che l'ispezione del ~/.bashrcfile del PO rivela che il codice che lo ha fatto è rimasto intatto. È, tuttavia, pertinente e interessante, e tu sei giusto suggerire che sia menzionato.)
Eliah Kagan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.