Lỗi cú pháp gần mã thông báo bất ngờ. Sau khi chỉnh sửa .bashrc


11

Tôi đang cố gắng truy cập vào bảng tạm nhưng khi tôi nhập vào source ~/.bashrc thiết bị đầu cuối thì tôi gặp lỗi này:

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

Tôi đã cố gắng thực hiện hướng dẫn trong câu trả lời của Gary Woodfine cho Truy cập bảng lệnh dòng lệnh .

Đầu ra của cat ~/.bashrclà:

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

Đây là trên Ubuntu 19.04. Bất cứ ai có thể giúp tôi tìm ra cách khắc phục điều này?

Câu trả lời:


16

Thông báo trước nằm ở dòng thứ hai:

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

Đó phải là:

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

Có vẻ như bạn đã quên đánh Entersau khi nhập bí danh thứ hai dẫn đến kết quả # ~/.bash...trực tiếp theo aliasđịnh nghĩa của bạn trong cùng một dòng. Không có một không gian trước không # ~/.bash...thể được hiểu là một nhận xét bởi shell mà là một phần của đối số của aliaslệnh.

Tôi cũng khuyên bạn nên đặt bí danh trong tệp ~/.bash_aliasessẽ có nguồn gốc khi ~/.bashrcđược thực thi, vì vậy bạn không cần chỉnh sửa ~/.bashrcvà cuối cùng làm hỏng nó.

Nếu bạn khăng khăng đặt bí danh vào ~/.bashrc, hãy thêm chúng vào cuối tệp.

Để hiểu sâu hơn về chủ đề này, vui lòng tham khảo câu trả lời tuyệt vời của Eliah cho câu hỏi của bạn.


6
Câu trả lời này sẽ tốt hơn rất nhiều nếu bạn giải thích lý do tại sao bản sửa lỗi hoạt động
Andy

Cảm ơn! Btw ngay cả khi người ta chọn không làm theo lời khuyên của tôi về việc đặt bí danh ở đâu đó sau khi kiểm tra tương tác, tôi khuyên bạn nên # ~/.bashrc: executed by bash(1) for non-login shells.giữ dòng đầu tiên. Không có lý do kỹ thuật nào buộc nó phải xuất hiện đầu tiên (hoặc hoàn toàn). Nhưng đó là một bình luận ghi lại toàn bộ tập tin. Vì vậy, nó khá khó hiểu với người đọc để nó xuất hiện sau mã khác. Tôi hiểu nếu bạn không muốn thay đổi điều đó, đặc biệt là khi OP chấp nhận câu trả lời này. (Tôi nghĩ rằng chỉnh sửa cho điều đó hoặc chỉ để lại cả hai đều hợp lý trong các trường hợp.)
Eliah Kagan

'preseed' - ý bạn là 'trước'?
Michael Harvey

20

mook765 hoàn toàn chính xác về nguyên nhân của vấn đề và giải pháp được đề xuất trong câu trả lời đó đã sửa lỗi cú pháp, nhưng tôi khuyên bạn nên giải quyết nó theo một cách khác.

Sẽ tốt hơn nếu đặt các định nghĩa bí danh .bashrc, nhưng tốt nhất là không đặt chúng - hoặc bất cứ thứ gì - ở trên cùng của tệp đó.

Chúng ta có xu hướng nghĩ rằng .bashrcchỉ có nguồn gốc từ các vỏ tương tác, nhưng thực tế không phải vậy. Các shell từ xa không tương tác ( nếu bash xác định chúng là như vậy ) cũng là nguồn .bashrc. Đó là lý do tại sao Ubuntu mặc định .bashrc1 chứa mã này: 2

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

Về cơ bản mọi thứ bạn đưa vào .bashrc, bao gồm nhưng không giới hạn ở các định nghĩa bí danh, nên đi đâu đó bên dưới. Bạn chỉ nên đặt mã của riêng bạn lên trên mã đó nếu bạn có lý do rõ ràng để làm như vậy, điều này rất hiếm.

Bạn có thể đặt định nghĩa bí danh của mình ở bất cứ đâu bên dưới mã đó , mặc dù tôi khuyên bạn nên đặt chúng ở cuối tệp. Hoặc bạn có thể muốn đặt chúng gần một số định nghĩa bí danh hiện có trong tệp. Hoặc bạn có thể thích đặt chúng vào tệp riêng biệt ~/.bash_aliasesmà bạn có thể tạo nếu nó không tồn tại. 3 Bất kỳ lựa chọn nào cũng tốt.

Đây là một trong những ví dụ phổ biến hơn về các hiệu ứng kỳ lạ và bất ngờ đặt mã riêng của một người lên trên kiểm tra tương tác có thể có. Vấn đề cụ thể đó xảy ra khi mã tạo ra đầu ra, điều không nên xảy ra từ một định nghĩa bí danh. (Các bí danh, khi được sử dụng, có thể tất nhiên mở rộng ra một lệnh sản xuất đầu ra, nhưng một định nghĩa alias đúng cú pháp không nên sản xuất đầu ra trừ khi -ptùy chọn sẽ được chuyển cho alias.) Tôi không mong đợi các định nghĩa bí danh để thường gây ra vấn đề ngay cả khi họ chạy trong vỏ không tương tác. Các shell không tương tác không thực hiện mở rộng bí danh theo mặc định (mặc dù đây chỉ là mặc định). Tuy nhiên, nếu cuối cùng chúng tạo ra hiệu ứng bất ngờ, có khả năng sẽ không ai nghĩ sẽ kiểm tra điều đó.

Điều này được thừa nhận chỉ là một lý do yếu để tránh đưa các định nghĩa bí danh lên trên kiểm tra tương tác .bashrc. Tuy nhiên, vì hoàn toàn không có lợi ích gì khi làm như vậy so với việc đặt chúng ở bất kỳ nơi nào khác trong tệp, tôi khuyên bạn nên làm theo cách tiếp cận chung là chỉ đặt mã ở trên để kiểm tra xem bạn có chủ ý chạy trong shell từ xa không tương tác.


Khía cạnh thú vị khác của điều này là tại sao đây là lỗi cú pháp:

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

#bắt đầu bình luận, được phép làm theo lệnh. Tuy nhiên, #ký tự không có tác dụng bắt đầu một nhận xét khi nó xuất hiện trong một từ lớn hơn, ngoại trừ là ký tự đầu tiên của từ đó. (Theo nghĩa này, "từ" bao gồm những thứ như pbpaste='xclip -selection clipboard -o'#, do trích dẫn .) Văn bản sau đây, được dùng như một nhận xét, được lấy làm đối số bổ sung cho aliasnội dung. Nhưng một lỗi xảy ra trong khi phân tích cú pháp chúng, do sự hiện diện bất ngờ của (nó, có ý nghĩa đặc biệt với vỏ, nhưng không có ý nghĩa trong bối cảnh đó. Hiệu quả là phần aliasdựng sẵn thực sự không bao giờ chạy và thay vào đó bạn gặp lỗi cú pháp.

Do đó, thực sự có thể sửa lỗi cú pháp bằng chỉnh sửa một ký tự , bằng cách đặt khoảng trắng giữa 'và các #ký tự trên dòng đó. Nhưng như chi tiết ở trên, tôi khuyên bạn nên đi xa hơn và di chuyển các định nghĩa bí danh thấp hơn nhiều trong tệp.


1 Mặc định.bashrctrong Ubuntu có thể được xem tại/etc/skel/.bashrc, miễn là bạn chưa sửa đổi tệp đó. Điều này được sao chép vào một thư mục nhà của người dùng khi người dùng được tạo. Giống như nhiều tệp trong Ubuntu, tệp này được thay đổi tối thiểu từ Debian, bản phân phối mà Ubuntu có nguồn gốc. Lời khuyên trong bài đăng này áp dụng cho Bash trong Debian cũng như Ubuntu, nhưng nó không nhất thiết phải áp dụng mà không sửa đổi cho Bash trong tất cả các hệ thống GNU / Linux.

2 Cũng có thể , mặc dù hiếm, để bắt đầubashnhư một vỏ đăng nhập không tương tác. Giống như các vỏ đăng nhập tương tác, các nguồn vỏ như vậy~/.profiletự động và mặc định~./profiletrong các nguồn rõ ràng của Ubuntu~/.bashrc. Bên cạnh việc ngăn chặn việc thực thi không chủ ý trong các vỏ từ xa không tương tác, đặt các bổ sung của bạn xuống~/.bashrcdưới kiểm tra tương tác cũng ngăn không cho nó được thực thi ngoài ý muốn trong trường hợp lạ của vỏ đăng nhập không tương tác.

3.bashrc Kiểm tramặc định của Ubuntunếu~/.bash_aliasestồn tại ([ -f ~/.bash_aliases ]) và nguồn nó (. ~/.bash_aliases) nếu có. Mã bạn đã đăng xác minh rằng.bashrctệpđã sửa đổi của bạnthực hiện các hành động đó - có vẻ như thay đổi duy nhất đối với nó là mã bạn đã thêm ở trên cùng.


Câu trả lời đó bao gồm tất cả các câu hỏi tôi có, thật tuyệt (có lẽ nên đề cập rằng .bash_aliases dự kiến ​​sẽ có nguồn gốc từ .bashrc
eckes

@EliahKagan, thực sự, tôi đã không nhận thấy câu đó ở giữa, rất tiếc. Sự nhấn mạnh câu trả lời này đặt vào vị trí của các bí danh khiến nó đọc như thể nó sẽ là một vấn đề lớn hơn thực tế. Vì nó sẽ là nếu , ví dụ như các bí danh đã được áp dụng trong vỏ noninteractive quá ... Tôi thấy quan điểm của bạn về việc giữ gìn các điều kiện bảo vệ đầu tiên, nhưng chúng tôi dường như không đồng ý về trình tự những vấn đề khác nhau cần được ưu tiên. ;)
ilkkachu

@ilkkachu Vâng, có thể chúng tôi không đồng ý về điều đó. Mặt khác, tôi bắt đầu viết câu trả lời này sau khi mook765 đã được đăng và OP đã đánh dấu nó là chấp nhận. Vì vậy, tôi quyết định bắt đầu câu trả lời này bằng cách tham khảo câu trả lời đó (" mook765 hoàn toàn chính xác về nguyên nhân của vấn đề và giải pháp được đề xuất trong câu trả lời đó đã sửa lỗi cú pháp") trước khi thực hiện phần lớn câu trả lời còn lại của tôi về giải pháp thay thế của việc đặt chúng ở một nơi khác ngoài phần trên cùng của tệp.
Eliah Kagan

2
@eckes Cảm ơn lời khuyên - Tôi đã thêm một vài chú thích để đề cập đến vấn đề đó và một số vấn đề liên quan, cho những độc giả quan tâm. (Lý do tôi không coi việc ~/.bashrctìm nguồn cung ứng ~/.bash_aliaseslà một điểm đặc biệt quan trọng trong bối cảnh này là việc kiểm tra ~/.bashrctệp của OP cho thấy rằng mã vẫn còn nguyên vẹn. Tuy nhiên, cả hai đều có liên quan và thú vị, và bạn quyền đề nghị nó được đề cập.)
Eliah Kagan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.