Problema ao configurar o PATH para Java no Debian

2

Estou tentando fazer com que o Oracle Java 7 update 3 funcione corretamente no Debian 6. Eu baixei e configurei os arquivos em /usr/java/jre1.7.0_03 . Eu também defini as duas linhas seguintes no final de /etc/bash.bashrc :

export JAVA_HOME=/usr/java/jre1.7.0_03
export PATH=$PATH:$JAVA_HOME/bin

Efetuando login como outros usuários e root está bem, Java pode ser encontrado:

chris@mc:~$ java -version
java version "1.7.0_03"
Java(TM) SE Runtime Environment (build 1.7.0_03-b04)
Java HotSpot(TM) 64-Bit Server VM (build 22.1-b02, mixed mode)

No entanto, existem dois casos em que o Java não pode ser encontrado como detalhado abaixo. Note que ambos funcionaram bem quando eu instalei anteriormente o OpenJDK Java 6 através do aptitude, mas eu preciso do Oracle Java 7 por várias razões.

  1. Mais importante, não posso executar comandos como outro usuário via su , apesar do PATH mostrar que o Java deve estar presente. O usuário foi criado com adduser chris

    root@mc:~# su chris -c "echo $PATH"
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/java/jre1.7.0_03/bin:/bin
    root@mc:~# su chris -c "java -version"
    bash: java: command not found
    root@mc:~# su chris -c "/usr/java/jre1.7.0_03/bin/java -version"
    java version "1.7.0_03"
    ...
    

    Como pode estar no PATH mas não ser encontrado? Atualização 05/04/2012: explicada por Daniel, fazendo com que seja um shell não interativo, então arquivos como /etc/profile e /etc/bash.bashrc não são executados. Fazendo uma troca completa para esse usuário e executar o Java funciona:

    root@mc:~# su chris
    chris@mc:/root$ java -version
    java version "1.7.0_03"
    ...
    
  2. Eu corro um script no arranque que exibe problemas semelhantes, mas ligeiramente diferentes. O script está localizado em /etc/init.d/start-mystuff.sh e chama um jar:

    #!/bin/bash
    # /etc/init.d/start-mystuff.sh
    java -jar /opt/Mars.jar
    

    Posso confirmar que o script é executado na inicialização e o código de saída é 127, o que indica que o comando não foi encontrado. Inserir uma linha para imprimir / salvar o PATH mostra que é:

     /sbin:/usr/sbin:/bin:/usr/bin
    

    Esse segundo problema não é tão importante porque eu posso apenas apontar diretamente para o executável Java no script, mas ainda estou curioso!

Eu tentei definir o PATH e JAVA_HOME explicitamente em /etc/environment , o que não ajudou. Também tentei defini-las em /etc/profile , o que também não parece ajudar. Eu tentei entrar e sair novamente depois de definir PATH nos vários locais (duh!).

Enfim, post longo para o que provavelmente terá uma solução simples de uma linha :( Qualquer ajuda com isso seria muito apreciada, eu passei muito tempo tentando consertar isso sozinho.

Motivação

O primeiro problema pode parecer obscuro, mas no meu sistema eu tenho usuários que não são permitidos no acesso SSH mas eu ainda quero rodar processos como eles. Eu tenho uma tonelada de scripts operando dessa maneira e não quero ter que mudar todos eles.

    
por milkmansrevenge 05.04.2012 / 16:38

3 respostas

3

Veja: update-alternatives

Além disso: O Debian geralmente desencoraja desenvolvedores que confiam em variáveis ENV, você descobriu uma razão para isso.

Não é que eles sejam tabus porque não devem estar sempre disponíveis.

Nota: Adicionar seu caminho java no final do caminho existente significa que qualquer outro java será encontrado e usado primeiro.

(ou seja, o (link simbólico) em / usr / bin)

então:

ls -lah /usr/bin/java

diz:

lrwxrwxrwx 1 root root 22 Apr 22 2011 /usr/bin/java -> /etc/alternatives/java

file $(which java)

/usr/bin/java: symbolic link to '/etc/alternatives/java'

file /etc/alternatives/java

/etc/alternatives/java: symbolic link to '/usr/lib/jvm/java-6-openjdk-i386/jre/bin/java'

** < problema secundário > e também serve para demonstrar porque $ (exec no estilo subshell) é preferível, para "backtick exec mode", ou "eval this".

((como '' '' e "" fica muito confuso, pelo menos para mim, e nem sempre funciona como esperado em todos os shells o tempo todo.  Investigue o modo POSIX AKA / bin / sh))

< / assunto secundário > **

man update-alternatives explica porque este sistema alternativo existe ...

meantime

update-alternatives --config java 

pode ajudar.

/ usr / local / é um bom lugar para instalar pacotes construídos por fontes ...

Existem também outras formas de esfolar o seu gato.

Incluindo:

  • mão re-apontando o link / usr / bin / java:)

(embora esteja atento a upgrades ou instalações de dependência para redefini-lo ... não é uma boa escolha, mas funciona)

  • definindo um alias para java por usuário [1]

  • prefixando $ PATH nos usuários .bashrc

(você pode usar o .bashrc em .bash_profile se quiser)

  • chamando o caminho completo das versões específicas por instância

(aposta mais segura, mas provavelmente não é prática)

[1] .alias ou .bashrc

help alias

(é um bash construído)

Finalmente, um exemplo para o bem ou para o mal: retirado do meu Debian .bash_profile ...

# include .bashrc if it exists

if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

# set PATH so it includes user's private bin if it exists
if [ -d ~/bin ] ; then
    PATH=~/bin:"${PATH}"
fi

Espero que isso ajude em vez de dificultar

Pete

    
por 05.04.2012 / 18:14
1

Muitas perguntas de uma só vez, mas:

1. Você faz

# su chris -c "echo $PATH"

Isso substituirá a variável $PATH antes que o comando seja executado, o que dará o $PATH para a raiz. Experimente

# su chris -c "echo $HOME"

para ver o que quero dizer.

Em vez disso, você pode fazer

# su chris -c 'echo $PATH'

que impedirá o shell de expandir a variável no primeiro caso e, em vez disso, obterá chris do $PATH . Você provavelmente descobrirá que as alterações não permearam o usuário.

Por que não então? /bin/sh está ligado a /bin/dash nos sistemas Debian e não /bin/bash . O traço não lerá /etc/bash.bashrc . Talvez você tenha o Dash como shell padrão para o usuário chris quando ele foi criado. Procure em /etc/passwd para ver se este é o caso.

Talvez isso também clarifique a questão 2.

UPDATE: Ah, /etc/bash.bashrc é lido apenas para shells interativos. Leia man bash , seção "ARQUIVOS". Você não inicia um shell interativo quando usa su dessa maneira.

Atualização 2: este exemplo é de um jeito:

# su chris -c 'myvar="hi there"; echo $myvar'
hi there

ou similarmente:

# su chris -c 'export myvar="hi there"; echo $myvar; export | grep myvar'
hi there
declare -x myvar="hi there"

(com export , a variável também está disponível para subprocessos gerados, como de costume).

    
por 05.04.2012 / 16:45
0

Você pode usar

sudo -u <user> -i 

que lerá .bashrc / .bash_profile .

    
por 05.04.2012 / 20:30