Lubuntu를 12.10에서 13.04로 업그레이드 한 후이 문제가 발생합니다.
Ctrl+ Alt+ 1를 누르고 로그인, 비밀번호를 입력 한 후 2 초 동안 기다렸다가 다음을 얻습니다 ♦: command not found"
. 이 메시지 후에 문제없이 명령을 입력 할 수 있지만 무엇입니까?
echo $PATH
/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/vitaly/bin:/usr/java/jdk1.7.0_17/bin
내 .bashrc
파일은 다음과 같습니다
# ~/.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) 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
# 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
내 .profile
파일은 다음과 같습니다
# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.
# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022
# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi
파일 /etc/profile
은 여기에 있습니다 : http://paste.ubuntu.com/5781361/
답변
해결 방법
먼저, tty1- Ctrl+ Alt+에 갈 때 참조한다고 생각합니다 F1.
이제 ♦와 같은 이상한 문자 ( 다이아몬드 문자 또는 askubuntu 중재자의 특수 배지 ) ~/.bashrc
또는 ~/.profile
파일 또는 다양한 초기화 명령이 포함 된 기타 파일 이 있기 때문에 가장 가능성이 높은 것으로 생각 됩니다.
다음 이미지에서 볼 수 있듯이 ~/.bashrc
♦ 문자 안에있는 파일을 한 줄에 편집했습니다 . 결과적으로 터미널을 열면 설명 된 문제가 발생합니다.
내가 tty1에 Ctrl+ Alt+ 로 갈 때도 마찬가지 F1입니다.
쉘이 호출 될 때 초기화 명령을 포함 파일 : /etc/profile
, /etc/bashrc
, ~/.bash_login
, ~/.profile
, ~/.bashrc
, ~/.bash_aliases
어쩌면 다른 사람. 셸 초기화 파일을 참조하십시오 .
이러한 파일 중 하나에 잘못된 내용이 있는지 빠르게 확인하려면 source
command 를 사용할 수 있습니다 . 예를 들면 다음과 같습니다.
source ~/.bashrc
마지막 해결책
검사 후 /etc/profile
로부터 http://paste.ubuntu.com/5781361/ , I 라인 31에 있다는 것을 발견 – “오른쪽에서 왼쪽으로 재정의”‮
유니 코드 문자. 로 /etc/profile
파일을 열기 만하면 sudo -H gedit /etc/profile
이상한 문자를 삭제하면 문제가 사라집니다.
예를 들어 HTML에서 오락으로, ‮
줄 앞에 십진수 코드 ( )를 사용하여이 유니 코드 문자를 삽입하면 어떤 일이 발생하는지보십시오.
text이 본문은 아랍어로되어 있습니다!
더 일반화 된 또 다른 솔루션
” trap “을 사용하여 오류를 일으키는 정확한 명령을 찾을 수 있습니다.
먼저 ~/bin
디렉토리에 새 스크립트 파일을 만들어야합니다 . 다음과 같이 내부 파일 lib.trap.sh
( gedit ~/bin/lib.trap.sh
)을 호출합니다 .
lib_name='trap'
lib_version=20130620
#changed from lib_version=20121026 found it at /programming//a/13099228/2353900 to work well at initialization of the shell
stderr_log="/dev/shm/stderr.log"
#
# TO BE SOURCED ONLY ONCE:
#
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##
if test "${g_libs[$lib_name]+_}"; then
return 0
else
if test ${#g_libs[@]} == 0; then
declare -A g_libs
fi
g_libs[$lib_name]=$lib_version
fi
#
# MAIN CODE:
#
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##
set -o pipefail # trace ERR through pipes
set -o errtrace # trace ERR through 'time command' and other functions
set -o nounset ## set -u : exit the script if you try to use an uninitialised variable
set -o errexit ## set -e : exit the script if any statement returns a non-true return value
exec 2>"$stderr_log"
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##
#
# FUNCTION: EXIT_HANDLER
#
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##
function exit_handler ()
{
local error_code="$?"
test $error_code == 0 && return;
#
# LOCAL VARIABLES:
# ------------------------------------------------------------------
#
local i=0
local regex=''
local mem=''
local error_file=''
local error_lineno=''
local error_message='unknown'
local lineno=''
#
# PRINT THE HEADER:
# ------------------------------------------------------------------
#
# Color the output if it's an interactive terminal
test -t 1 && tput bold; tput setf 4 ## red bold
echo -e "\n(!) EXIT HANDLER\n"
#
# GETTING LAST ERROR OCCURRED:
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
#
# Read last file from the error log
# ------------------------------------------------------------------
#
if test -f "$stderr_log"
then
stderr=$( tail -n 1 "$stderr_log" )
rm "$stderr_log"
fi
#
# Managing the line to extract information:
# ------------------------------------------------------------------
#
if test -n "$stderr"
then
# Exploding stderr on :
mem="$IFS"
local shrunk_stderr=$( echo "$stderr" | sed 's/\: /\:/g' )
IFS=':'
local stderr_parts=( $shrunk_stderr )
IFS="$mem"
# Storing information on the error
error_file="${stderr_parts[0]}"
error_lineno="${stderr_parts[1]}"
error_message=""
for (( i = 3; i <= ${#stderr_parts[@]}; i++ ))
do
error_message="$error_message "${stderr_parts[$i-1]}": "
done
# Removing last ':' (colon character)
error_message="${error_message%:*}"
# Trim
error_message="$( echo "$error_message" | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//' )"
fi
#
# GETTING BACKTRACE:
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
_backtrace=$( backtrace 2 )
#
# MANAGING THE OUTPUT:
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
local lineno=""
regex='^([a-z]{1,}) ([0-9]{1,})$'
if [[ $error_lineno =~ $regex ]]
# The error line was found on the log
# (e.g. type 'ff' without quotes wherever)
# --------------------------------------------------------------
then
local row="${BASH_REMATCH[1]}"
lineno="${BASH_REMATCH[2]}"
echo -e "FILE:\t\t${error_file}"
echo -e "${row^^}:\t\t${lineno}\n"
echo -e "ERROR CODE:\t${error_code}"
test -t 1 && tput setf 6 ## white yellow
echo -e "ERROR MESSAGE:\n$error_message"
else
regex="^${error_file}\$|^${error_file}\s+|\s+${error_file}\s+|\s+${error_file}\$"
if [[ "$_backtrace" =~ $regex ]]
# The file was found on the log but not the error line
# (could not reproduce this case so far)
# ------------------------------------------------------
then
echo -e "FILE:\t\t$error_file"
echo -e "ROW:\t\tunknown\n"
echo -e "ERROR CODE:\t${error_code}"
test -t 1 && tput setf 6 ## white yellow
echo -e "ERROR MESSAGE:\n${stderr}"
# Neither the error line nor the error file was found on the log
# (e.g. type 'cp ffd fdf' without quotes wherever)
# ------------------------------------------------------
else
#
# The error file is the first on backtrace list:
# Exploding backtrace on newlines
mem=$IFS
IFS='
'
#
# Substring: I keep only the carriage return
# (others needed only for tabbing purpose)
IFS=${IFS:0:1}
local lines=( $_backtrace )
IFS=$mem
error_file=""
if test -n "${lines[1]}"
then
array=( ${lines[1]} )
for (( i=2; i<${#array[@]}; i++ ))
do
error_file="$error_file ${array[$i]}"
done
# Trim
error_file="$( echo "$error_file" | sed -e 's/^[ \t]*//' | sed -e 's/[ \t]*$//' )"
fi
echo -e "ROW, FILE:\t\t${lines[2] }\n"
echo -e "ERROR CODE:\t${error_code}"
test -t 1 && tput setf 6 ## white yellow
if test -n "${stderr}"
then
echo -e "ERROR MESSAGE:\n${stderr}"
else
echo -e "ERROR MESSAGE:\n${error_message}"
fi
fi
fi
#
# PRINTING THE BACKTRACE:
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
test -t 1 && tput setf 7 ## white bold
echo -e "\n$_backtrace\n"
#
# EXITING:
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
test -t 1 && tput setf 4 ## red bold
echo "Exiting!"
test -t 1 && tput sgr0 # Reset terminal
exit "$error_code"
}
trap exit_handler ERR # ! ! ! TRAP EXIT ! ! !
#trap exit ERR # ! ! ! TRAP ERR ! ! !
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##
#
# FUNCTION: BACKTRACE
#
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##
function backtrace
{
local _start_from_=0
local params=( "$@" )
if (( "${#params[@]}" >= "1" ))
then
_start_from_="$1"
fi
local i=0
local first=false
while caller $i > /dev/null
do
if test -n "$_start_from_" && (( "$i" + 1 >= "$_start_from_" ))
then
if test "$first" == false
then
echo "BACKTRACE IS:"
first=true
fi
caller $i
fi
let "i=i+1"
done
}
return 0
이제해야 할 일은 파일의 시작 부분에 다음 줄을 두는 것입니다 /etc/profile
( sudo -H gedit /etc/profile
).
source '/home/<user_name>/bin/lib.trap.sh'
<user_name>
사용자 이름으로 변경하십시오 . 이와 같이, 쉘이 호출 될 때 초기화 명령을 포함하는 모든 파일은 “트랩”을 통과합니다.
/etc/profile
예를 들어 잘못된 명령이 있는지 테스트하려면 다음 명령에서 터미널을 실행하십시오.
bash 소스 / etc / profile
이 경우와 같이 무언가 잘못되면 결과는 다음과 같습니다.
이제 32 행의 파일에 문제 ( command not found
) 가 있음을 확실히 알 수 있습니다 ( /etc/profile
파일의 시작 부분에 새 행을 삽입했기 때문에 위의 31 행이 아님).
이 일반화 된 솔루션을 완성하는 데 도움 이 된 이 답변의 스크립트에 대해 Luca Borrione 에게 감사드립니다 .
답변
bash의 초기화 스크립트를 디버깅하려면 (가상 콘솔에 로그인 한 후) 다음을 실행하십시오.
PS4='+ $BASH_SOURCE:$LINENO:' bash -xlic ''
위의 내용은 가상 콘솔에 로그인 할 때 프로그램 과 동일한 방식 으로 대화식 ( -i
) 로그인 ( -l
) 모드 에서 bash를 실행 login
합니다. -c ''
이 초기화 스크립트를 통해 실행 한 후 즉시 종료하게하고, -x
그리고 PS4=...
는 그 명령의 파일 이름과 라인 번호와 함께,이를 실행하기 전에, 그것을 출력 각 명령을합니다. 유효하지 않은 명령이있는 파일의 라인을 결정하는 데 도움이됩니다.
참고로, ♦는 가상 콘솔의 기본 글꼴이 심볼이없는 문자를 인쇄하는 데 사용하는 심볼입니다.
답변
초기화 파일을 검색하는 동안 ♦를 출력하는 데 사용되는 16 진수를 찾는 것이 도움이 될 수 있습니다. 유니 코드 문자 ‘BLACK DIAMOND SUIT’ 에 따르면 ♦의 16 진수 코드는 2666 입니다. 참고 : 동일하거나 유사한 모양의 기호를 생성하는 하나 이상의 다른 16 진 코드 25C6이 있습니다. “diamond”에 대한 검색 결과를 참조하십시오. 유니 코드 문자 검색
아마도 \u2666
스크립트 중 하나에 있을 것 입니다. 에서 에코 수동 배쉬 참조 – “\ 어 – 유니 코드 (ISO / IEC 10646) 값을 16 진수 값이 HHHH입니다 문자 (1 ~ 4 개의 16 진수)”
사용되는 문자 인코딩에 따라 다르므로 가장 가능성이 높은 문자를 먼저 검색 할 수 있습니다. echo $LC_CTYPE
쉘에서 사용하는 문자 인코딩을 반환해야합니다. 터미널의 문자 인코딩을 얻는 방법을 참조하십시오
답변
bashrc 파일의 전체 경로와 함께 bashrc 파일을 편집 할 수있는 알려진 도구의 전체 경로를 작성하십시오.
/bin/nano /home/username/.bashrc
PATH
변수에 대한 남용을 찾아서 주석 처리하십시오. 아마도 경로에 무언가를 추가하려고 할 때 큰 따옴표 대신 작은 따옴표로 표시되었습니다.
PATH='$PATH:/path/to/new/tool' # very BAD, single quotes won't expand PATH
# ^ ^
PATH="$PATH:/path/to/new/tool" # Good! The double quotes allow variable expansion
bash를 https://www.shellcheck.net/ 과 같은 도구에 복사하여 bash 사용에 눈에 띄는 문제가 있는지 확인하십시오.
희망이 도움이됩니다.