Solução alternativa
Primeiro, eu acho que você se refere quando você vai em tty1 - Ctrl + Alt + F1 .
Agora, acho que está acontecendo o que você disse mais provavelmente porque você tem um personagem estranho como ♦ ( personagem de terno de diamante ou o distintivo especial para um moderador de askubuntu ) ~/.bashrc
ou ~/.profile
arquivo ou outro arquivo que contém vários comandos de inicialização.
Como você pode ver na próxima imagem, eu editei o arquivo ~/.bashrc
colocando dentro do caractere ♦ em uma única linha. Como resultado, quando abro o terminal, obtenho o problema descrito por você:
Está acontecendo da mesma maneira quando eu entro em tty1 com Ctrl + Alt + F1 .
Arquivos que contêm comandos de inicialização quando um shell é chamado: /etc/profile
, /etc/bashrc
, ~/.bash_login
, ~/.profile
, ~/.bashrc
, ~/.bash_aliases
e talvez outros. Consulte os arquivos de inicialização do Shell .
Para verificar rapidamente se algum desses arquivos tem algo errado, você pode usar o comando source
. Por exemplo:
source ~/.bashrc
Solução final
Após inspecionar /etc/profile
do link , descobri que na linha 31 existe "Right-To-Left Override "- ‮
caractere unicode. Apenas abra o arquivo /etc/profile
com sudo -H gedit /etc/profile
, certifique-se de excluir este caractere estranho e o problema desaparecerá.
Por diversão, em HTML, por exemplo, se você inserir esse caractere unicode usando o código decimal ( ‮
) na frente de uma linha, veja o que está acontecendo:
Este texto está em árabe-inglês!
Outra solução mais generalizada
Nós encontraremos o comando exato que causa o erro usando uma " interceptação " .
Primeiro, temos que fazer um novo arquivo de script no diretório ~/bin
, vamos chamá-lo de lib.trap.sh
( gedit ~/bin/lib.trap.sh
), com o seguinte:
lib_name='trap'
lib_version=20130620
#changed from lib_version=20121026 found it at https://stackoverflow.com/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_=""
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
Agora, a única coisa que você precisa fazer é colocar a próxima linha no início do arquivo /etc/profile
( sudo -H gedit /etc/profile
):
source '/home/<user_name>/bin/lib.trap.sh'
Altere <user_name>
com seu nome de usuário. Assim, todos os arquivos que contêm comandos de inicialização quando um shell é invocado passarão pelo "trap".
Para testar se há um comando errado em /etc/profile
, por exemplo, execute os próximos comandos do terminal:
bash fonte / etc / profile
Se algo estiver errado, como neste caso, o resultado será:
Então, agora sabemos com certeza que há um problema ( command not found
) no arquivo /etc/profile
na linha 32 (não está na linha 31 como acima porque inserimos uma nova linha no início do arquivo).
Muito obrigado a Luca Borrione por seu roteiro de esta resposta que me ajudou a completar esta solução generalizada.