Eu tenho o Fedora 20 e o Gnome3 classic e estou tentando usar as janelas do terminal CTRL/ALT/Fn. Quando desejo editar um arquivo com o emacs, uso o seguinte script para que meu arquivo de dicas seja exibido automaticamente e o emacs seja executado como um trabalho de fundo. Isso funciona bem no terminal sem login dos aplicativos de desktop Gnome, mas no terminal de login recebo mensagens de erro: (obtido por redirecionamento com '&> e' na janela CTL/ALT/F2)
home/Harry/bin/emx: line 4: t: Permission denied
+---------------------------------------------------+
| EmacsHints.txt found and displayed |
| Usage: ./emx <filename> .. |
| .. Opens EmacsHints.txt and <filename> in emacs |
+---------------------------------------------------+
emacs: standard input is not a tty
Por favor, alguém pode explicar isso e me dizer como evitá-los e usar o script emx (sem dúvida modificado) com êxito em terminais com e sem login?
Versão revisada do meu script emx, incluí minhas notas e material de depuração:
#!/bin/sh
emxhn="EmacsHints.txt"
emxhf="/home/Harry/emacs/$emxhn"
ps aux | grep $emxhn > t
T=`wc -l t` # no spaces allowed between T and = and value
# echo $T
wc -l t > t1
T=`awk '$1' t1`
# echo $T
echo "+---------------------------------------------------+"
# In the test "" needed round $T else it is split into two commands ..
# .. so are the spaces after [ and before ]
# could be if ( [...] ) then or if [...] ; then
if [ "$T" = "2 t" ]; then
# echo "+----------------------------------------------+"
echo "| $emxhn already present"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ "|"
else
emacs $emxhf &
echo "| $emxhn found and displayed"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ "|"
fi
if [ "$#" = "1" ]; then
emacs $1 &
else
echo "| Usage: ./emx <filename> .." \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ "|"
echo "|" \ ".. Opens $emxhn and <filename> in emacs" "|"
fi
echo "+---------------------------------------------------+"
Sim, entendo, caí na armadilha XY, perguntando a X quando deveria ter perguntado a Y, então aqui está Y
Eu uso muito o emacs, mas não o tempo todo, e também tenho um arquivo de dicas, no qual anoto como executar as tarefas que encontro, e gosto de ter essas dicas disponíveis enquanto uso o emacs. Tentei automatizar isso para que sempre que eu iniciar o emacs, se as dicas ainda não estiverem lá, o arquivo também será aberto. Esse script foi minha tentativa de fazer isso e funcionou bem enquanto eu executava o emacs a partir de um terminal sem login em minha GUI de estilo clássico do Gnome3. Tentar em um terminal de login com CTL/ALT/F2 deu as mensagens de erro citadas.
Eu uso e adoro Unix e Fedora Linux há muitos anos, mas obviamente ainda há muito mais para aprender.
Responder1
Abaixo, analiso seu roteiro. Mas tendo feito isso, acho que a resposta para apergunta que você deveria ter feitoé:
- Corra
emacs --daemon
do seu.profile
. Isso cria uma instância de segundo plano do Emacs. - Execute
emacsclient FILENAME
para abrir um arquivo no Emacs. Isso cria uma nova janela (uma janela X11 ou uma janela usando o terminal atual). - Carregue o
EmacsHints
arquivo no arquivo de inicialização do Emacs: coloque(find-file "/home/Harry/emacs/EmacsHints.txt")
no seu arquivo.emacs
.
Não podemos dizer ao certo por que você está recebendo t: Permission denied
, já que você não postou o script que gerou esse erro (o script que você postou tem um comentário na linha 4). Mas você está criando um arquivo temporário no diretório atual; isso é uma má ideia em todas as circunstâncias e provavelmente não funciona quando você não tem permissão para gravar o diretório atual.
Se você precisar criar um arquivo temporário, usemktemp
. Porém, aqui, os arquivos temporários são uma complicação desnecessária: use a substituição de comandos para armazenar a saída dos comandos em uma variável.
#!/bin/sh
ps_lines=$(ps aux | grep EmacsHints)
line_count=$(echo "$ps_lines" | wc -l)
T=$(echo "$line_count" | awk '$1')
if [ "$T" = "2" ]; then …
Tudo isso, por sua vez, é muito complicado - basta canalizar a saída grep
into wc
, e a etapa awk não fará nada de útil.
if [ "$(ps aux | grep EmacsHints | wc -l)" = 2 ]; then …
Além disso, seu teste não é confiável: quando o EmacsHints
arquivo está aberto, às vezes ps
retornará uma linha contendo EmacsHints
, às vezes duas: depende do tempo dos processos ps
e grep
. Em vez de construir o seu próprio (o que não está funcionando), use ferramentas dedicadas para essa finalidade:pidof
oupgrep
.
#!/bin/sh
if pgrep -f 'EmacsHints\.txt' >/dev/null; then …
Voilá! Mais simples e realmente funciona.
Bemmajoritariamentefunciona. Se você abrir o EmacsHints
arquivo no Emacs sem especificá-lo na linha de comando, isso não será detectado. Eu ofereceria uma solução melhor, mas não entendo o que você está tentando realizar. Se você sempre quiser que o EmacsHints
arquivo seja aberto no Emacs, abra-o no seu arquivo .emacs
.
O Emacs é um pouco lento para iniciar, mas muitos usuários (inclusive eu) o configuram para ser executado quando você faz login e nunca sai dele. Corra emacs --daemon
do seu .profile
. Para abrir um arquivo na instância existente do Emacs, chame emacsclient
.
Em relação à “entrada padrão não é um tty”, você pode executar o Emacs em segundo plano apenas se estiver abrindo uma janela GUI. Se você estiver executando o Emacs no terminal, ele deverá estar em primeiro plano, caso contrário não poderá acessar o terminal. Se você deseja executar o Emacs em segundo plano apenas no X:
if [ -n "$DISPLAY" ]; then
emacs "$1" &
else
emacs "$1"
fi
A propósito, em um script de shell, sempre coloque aspas duplas em torno de substituições de variáveis e comandos: "$1"
, "$foo"
, "$(somecommand)"
, etc. Quando a substituição não está entre aspas duplas, o valor é interpretado não como uma string, mas como uma lista de padrões glob. Esse problema normalmente se manifesta com scripts que falham em nomes de arquivos que contêm espaços. Se você não entende o que tudo isso significa, basta usar aspas duplas.
Ou você pode simplesmente usar emacsclient
.
Responder2
Em relação a esta mensagem:
emx: line 4: t: permission denied
A primeira está lhe dizendo que seu comando:
ps aux | grep EmacsHints > t
não tem permissão para gravar o arquivo t
em qualquer diretório em que ele esteja quando executado. Melhor especificar um caminho completo, sugiro usar /tmp/t
assim:
ps aux | grep EmacsHints > /tmp/t
A outra mensagem:
emacs: standard input is not a tty
Está lhe dizendo que o script não tem acesso a um TTY para exibir o emacs. Para executar uma ferramenta como emacs
ou vim
dessa maneira, muitas vezes você precisará ter acesso a um dispositivo TTY para poder obter acesso ao seu STDIN e STDOUT.
Se você está desesperado ou não se importa com a falta de STDIN/STDOUT você pode criar um novo dentro do seu script assim:
emacs < $(tty) > $(tty)
Existem outros métodos para lidar com isso, consulte estas perguntas e respostas do SO intituladas:Como inicio um editor a partir de um script de shell?.