“ ข้อผิดพลาดทางไวยากรณ์ใกล้โทเค็นที่ไม่คาดคิด” หลังจากแก้ไข. bashrc


11

ฉันพยายามเข้าถึงคลิปบอร์ด แต่เมื่อฉันป้อนข้อมูล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

ผมพยายามที่จะทำกวดวิชาในคำตอบแกรี่ Woodfine ของการบรรทัดคำสั่งคลิปบอร์ดเข้าถึง

ผลลัพธ์ของ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 ใครสามารถช่วยฉันหาวิธีแก้ไขปัญหานี้ได้บ้าง

คำตอบ:


16

ข้อแม้อยู่ในบรรทัดที่สอง:

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.

ดูเหมือนว่าคุณจะกดEnterหลังจากป้อนนามแฝงที่สองซึ่งส่งผล# ~/.bash...โดยตรงต่อaliasคำจำกัดความของคุณในบรรทัดเดียวกัน หากไม่มีช่องว่างก่อนหน้านี้# ~/.bash...ไม่สามารถตีความได้ว่าเป็นความคิดเห็นโดยเชลล์ แต่เป็นส่วนหนึ่งของอาร์กิวเมนต์ของaliasคำสั่ง

ฉันยังแนะนำให้วางนามแฝงในไฟล์~/.bash_aliasesซึ่งจะมีที่มาเมื่อ~/.bashrcมีการดำเนินการดังนั้นคุณไม่จำเป็นต้องแก้ไข~/.bashrcและทำให้ยุ่งเหยิงในที่สุด

หากคุณยืนยันในการวางนามแฝงใน~/.bashrcเพิ่มพวกเขาในตอนท้ายของไฟล์

สำหรับข้อมูลเชิงลึกเกี่ยวกับหัวข้อนี้โปรดอ้างอิงคำตอบที่ดีเลิศของ Eliah สำหรับคำถามของคุณ


6
คำตอบนี้จะดีขึ้นมากถ้าคุณอธิบายว่าทำไมการแก้ไข
Andy

ขอบคุณ! Btw แม้ว่าใครเลือกที่จะไม่ทำตามคำแนะนำของฉันในการวางนามแฝงที่ไหนสักแห่งหลังจากการตรวจสอบการโต้ตอบฉันแนะนำให้# ~/.bashrc: executed by bash(1) for non-login shells.เก็บไว้เป็นบรรทัดแรก ไม่มีเหตุผลทางเทคนิคบังคับให้ปรากฏก่อน (หรือเลย) แต่มันเป็นความคิดเห็นที่บันทึกไฟล์ทั้งหมด ดังนั้นมันค่อนข้างสับสนกับผู้อ่านของมนุษย์ที่จะให้มันปรากฏขึ้นหลังจากรหัสอื่น ๆ ฉันเข้าใจว่าคุณไม่ต้องการเปลี่ยนโดยเฉพาะอย่างยิ่งเมื่อ OP ยอมรับคำตอบนี้เหมือนเดิม (ฉันคิดว่าการแก้ไขสำหรับสิ่งนั้นหรือเพียงปล่อยให้มันทั้งสองมีเหตุผลภายใต้สถานการณ์)
Eliah Kagan

'preseed' - คุณหมายถึง 'ก่อนหน้า' หรือไม่
Michael Harvey

20

mook765 นั้นถูกต้องทั้งหมดเกี่ยวกับสาเหตุของปัญหาและทางออกที่เสนอในคำตอบนั้นช่วยแก้ไขข้อผิดพลาดทางไวยากรณ์ แต่ฉันขอแนะนำให้คุณแก้ปัญหาด้วยวิธีอื่น

มันเป็นการดีที่จะใส่คำจำกัดความของนามแฝงเข้าไป.bashrcแต่จะเป็นการดีที่สุดที่จะไม่ใส่พวกเขา - หรืออะไรก็ตาม - ที่ด้านบนสุดของไฟล์นั้น

เรามักจะคิดว่า.bashrcเป็นแหล่งเปลือกหอยแบบโต้ตอบเท่านั้น แต่นี่ไม่ใช่กรณี ไม่โต้ตอบหอยระยะไกล ( ถ้าระบุทุบตีพวกเขาเป็นเช่นนี้ ) .bashrcนอกจากนี้ยังแหล่งที่มา นั่นคือสาเหตุที่.bashrc1ค่าเริ่มต้นของ Ubuntu มีรหัสนี้: 2

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

โดยทั่วไปทุกสิ่งที่คุณใส่.bashrcรวมถึง แต่ไม่ จำกัด เพียงนิยามของนามแฝงควรไปที่ด้านล่างนั้น คุณควรใส่รหัสของคุณเองเหนือรหัสนั้นหากคุณมีเหตุผลที่ชัดเจนในการทำเช่นนั้นซึ่งหายาก

คุณสามารถใส่คำจำกัดความของนามแฝงได้ทุกที่ด้านล่างรหัสนั้นแม้ว่าฉันจะแนะนำให้วางไว้ที่ท้ายสุดของไฟล์ หรือคุณอาจต้องการวางใกล้กับนิยามนามแฝงที่มีอยู่ในไฟล์ หรือคุณอาจต้องการวางไว้ในไฟล์แยกต่างหาก~/.bash_aliasesซึ่งคุณสามารถสร้างได้หากไม่มีอยู่ 3ตัวเลือกใด ๆ เหล่านี้ใช้ได้

นี่คือหนึ่งในตัวอย่างที่พบได้ทั่วไปของเอฟเฟ็กต์ที่แปลกประหลาดและที่ไม่คาดคิดซึ่งวางโค้ดของตัวเองเหนือการตรวจสอบการโต้ตอบ ปัญหาเฉพาะนั้นเกิดขึ้นเมื่อโค้ดสร้างเอาต์พุตซึ่งไม่ควรเกิดขึ้นจากนิยาม alias (นามแฝงเมื่อมีการใช้งานอาจขยายไปยังคำสั่งที่สร้างเอาต์พุต แต่นิยามของนามแฝงที่ถูกต้องทางไวยากรณ์ไม่ควรสร้างเอาท์พุทเว้นแต่-pตัวเลือกจะถูกส่งผ่านไปalias) ฉันไม่คาดหวังว่าคำจำกัดความของนามแฝงจะทำให้เกิดปัญหา ทำงานในเชลล์แบบไม่โต้ตอบ เชลล์ที่ไม่มีการโต้ตอบจะไม่ทำการขยายนามแฝงตามค่าเริ่มต้น (แม้ว่านี่จะเป็นเพียงค่าเริ่มต้น) อย่างไรก็ตามหากพวกเขาทำเอฟเฟกต์ที่ไม่คาดคิดก็ไม่มีใครคิดว่าจะตรวจสอบ

.bashrcนี้เป็นที่ยอมรับเพียงเหตุผลที่อ่อนแอเพื่อหลีกเลี่ยงการวางคำจำกัดความนามแฝงดังกล่าวข้างต้นการตรวจสอบการติดต่อสื่อสารใน อย่างไรก็ตามเนื่องจากไม่มีประโยชน์ในการทำเช่นนั้นเมื่อเทียบกับการวางไว้ที่อื่นในไฟล์ฉันขอแนะนำให้ทำตามวิธีการทั่วไปของการวางโค้ดด้านบนเท่านั้นเพื่อตรวจสอบว่าคุณตั้งใจจะทำงานในเชลล์ระยะไกลแบบไม่โต้ตอบ


สิ่งที่น่าสนใจอื่น ๆ ของสิ่งนี้คือสาเหตุที่นี่เป็นข้อผิดพลาดทางไวยากรณ์:

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

#เริ่มความคิดเห็นซึ่งได้รับอนุญาตให้ทำตามคำสั่ง อย่างไรก็ตาม#ตัวละครไม่มีผลในการเริ่มต้นความคิดเห็นเมื่อมันปรากฏในคำที่มีขนาดใหญ่ยกเว้นเป็นตัวอักษรตัวแรกของคำนั้น (ในแง่นี้ "คำว่า" รวมถึงสิ่งที่ชอบpbpaste='xclip -selection clipboard -o'#, เนื่องจาก quoting .) ข้อความต่อไปนี้ซึ่งตั้งใจเป็นความคิดเห็นจะถูกนำมาเป็นข้อโต้แย้งเพิ่มเติมเพื่อaliasbuiltin แต่มีข้อผิดพลาดเกิดขึ้นขณะแยกวิเคราะห์พวกเขาเนื่องจากการปรากฏตัวที่ไม่คาดคิด(ซึ่งมีความหมายพิเศษต่อเชลล์ แต่ไม่สมเหตุสมผลในบริบทนั้น ผลที่ได้คือaliasbuiltin จะไม่ทำงานและคุณจะได้รับข้อผิดพลาดทางไวยากรณ์แทน

ดังนั้นจึงเป็นไปได้ที่จะแก้ไขข้อผิดพลาดทางไวยากรณ์ด้วยการแก้ไขหนึ่งอักขระโดยใส่ช่องว่างระหว่าง'และ#อักขระบนบรรทัดนั้น แต่ตามรายละเอียดข้างต้นฉันขอแนะนำให้ดำเนินการต่อไปและย้ายคำจำกัดความของนามแฝงในไฟล์ให้ต่ำลงมาก


1.bashrcสามารถดูค่าเริ่มต้นใน Ubuntu ได้/etc/skel/.bashrcตราบใดที่คุณยังไม่ได้แก้ไขไฟล์นั้น สิ่งนี้จะถูกคัดลอกไปยังโฮมไดเรกทอรีของผู้ใช้เมื่อผู้ใช้ถูกสร้างขึ้น เช่นเดียวกับไฟล์จำนวนมากในอูบุนตูไฟล์นี้มีการเปลี่ยนแปลงเพียงเล็กน้อยจากเดเบียนการกระจายที่มาจากอูบุนตู คำแนะนำในโพสต์นี้ใช้กับ Bash ใน Debian รวมถึง Ubuntu แต่ไม่จำเป็นต้องปรับใช้กับ Bash ในระบบ GNU / Linux ทั้งหมด

2นอกจากนี้ยังเป็นไปได้ที่จะเริ่มต้นbashเป็นเชลล์ล็อกอินแบบไม่โต้ตอบ เช่นเดียวกับเปลือกหอยโต้ตอบการเข้าสู่ระบบแหล่งเปลือกดังกล่าว~/.profileโดยอัตโนมัติและเริ่มต้น~./profileใน Ubuntu ~/.bashrcอย่างชัดเจนแหล่งที่มา นอกเหนือจากการป้องกันการเรียกใช้งานโดยไม่ตั้งใจในเชลล์ระยะไกลแบบไม่โต้ตอบการเพิ่มส่วนเพิ่มเติมของคุณไป~/.bashrcด้านล่างการตรวจสอบการโต้ตอบยังป้องกันไม่ให้มีการดำเนินการโดยไม่ตั้งใจในกรณีแปลก ๆ ของเชลล์ล็อกอินแบบไม่โต้ตอบ

3ค่าเริ่มต้นของ Ubuntu.bashrcจะตรวจสอบว่า~/.bash_aliasesมีอยู่แล้วหรือไม่[ -f ~/.bash_aliases ]และตรวจสอบแหล่งที่มา (. ~/.bash_aliasesถ้ามี) รหัสที่คุณโพสต์ตรวจสอบว่า.bashrcไฟล์ที่แก้ไขของคุณทำการกระทำเหล่านั้น - ดูเหมือนว่าการเปลี่ยนแปลงเพียงอย่างเดียวคือรหัสที่คุณเพิ่มที่ด้านบน


คำตอบนั้นครอบคลุมคำถามทั้งหมดที่ฉันมียอดเยี่ยม (อาจจะพูดถึงว่า. bash_aliases คาดว่าจะได้มาจาก. bashrc
eckes

@EliahKagan ที่จริงฉันไม่ได้สังเกตประโยคนั้นอยู่ตรงกลางอ๊ะ การเน้นคำตอบนี้วางอยู่ที่ตำแหน่งของนามแฝงทำให้มันอ่านราวกับว่ามันจะเป็นปัญหาใหญ่กว่าที่เป็นจริง อย่างที่มันเป็นถ้าเช่นนามแฝงถูกใช้ในกระสุนที่ไม่มีปฏิกิริยาเช่นกัน ... ฉันเห็นจุดของคุณเกี่ยวกับการรักษาสภาพการป้องกันไว้ก่อน แต่ดูเหมือนว่าเราจะไม่เห็นด้วยกับคำสั่งที่แตกต่างกัน ;)
ilkkachu

@ilkkachu ใช่เป็นไปได้ว่าเราไม่เห็นด้วย ในทางกลับกันฉันเริ่มเขียนคำตอบนี้หลังจากที่mook765โพสต์ไปแล้วและ OP ได้ทำเครื่องหมายว่ายอมรับแล้ว ดังนั้นฉันจึงตัดสินใจที่จะเริ่มคำตอบนี้โดยอ้างถึงคำตอบนั้น (" mook765 นั้นถูกต้องทั้งหมดเกี่ยวกับสาเหตุของปัญหาและวิธีแก้ปัญหาที่เสนอในคำตอบนั้นแก้ไขข้อผิดพลาดทางไวยากรณ์") ก่อนส่วนที่เหลือของคำตอบของฉัน ทางเลือกอื่นของการวางไว้ที่อื่นนอกเหนือจากส่วนบนสุดของไฟล์
Eliah Kagan

2
@eckes ขอบคุณสำหรับคำแนะนำ - ฉันได้เพิ่มอ้างอิงท้ายเรื่องไม่กี่ฉบับเพื่อครอบคลุมเรื่องนั้นและปัญหาที่เกี่ยวข้องบางประการสำหรับผู้อ่านที่สนใจ (เหตุผลที่ฉันไม่พิจารณาว่าการ~/.bashrcจัดหา~/.bash_aliasesเป็นจุดสำคัญอย่างยิ่งในบริบทนี้คือการตรวจสอบ~/.bashrcไฟล์OP พบว่ารหัสที่ทำเช่นนั้นยังคงไม่เปลี่ยนแปลงอย่างไรก็ตามทั้งที่เกี่ยวข้องและน่าสนใจและคุณ สิทธิ์ในการแนะนำไว้ถูกกล่าวถึง)
Eliah Kagan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.