/ usr / bin / que retorna erro enigmático “which: no ls in ((null))”

3

Eu estou escrevendo um programa shell simples. Quando uso / usr / bin / com meu shell no mac osx e no ubuntu, ele age normalmente. Quando eu uso exatamente o mesmo comando na versão 6.3 (Santiago) do Red Hat Enterprise Linux Client, recebo este erro: "which: no ANYCOMMANDHERE in ((null))".

Existe alguma intuição para isso? Eu não consigo nem encontrar o que o erro significa (deixe-me saber se mostrar minha fonte vai ajudar).

EDIT: Meu caminho é (de dentro do shell):

$ echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin

Obrigado Jon

    
por Jonathan Friedman 08.10.2012 / 23:17

5 respostas

4

A string (null) é substituída por algumas bibliotecas C por argumentos para o especificador de conversão %s (string) do printf, quando o argumento correspondente é um apontador NULL, por ex. para

 char *path = 0; /* This would normally be = getenv("PATH"). */
 printf ("which: no foobar in (%s)\n", path);

Parece que a variável de ambiente PATH não está definida ou não foi exportada. Nesses casos, getenv("PATH") retorna 0. Como última possibilidade, seu utilitário which pode ter um bug poderoso).

Funciona corretamente se você diz export PATH ?

    
por 08.10.2012 / 23:26
2

Na verdade, o que todas as outras pessoas aqui já responderam - o PATH não está sendo definido, é verdadeiro de uma maneira, mas falso de outra maneira.

Eu tive o mesmo problema (usando o bash). Ao que parece, um "recurso" bash se transforma em um recurso errado: Bash cria uma variável de shell (não uma variável de ambiente!) PATH, que então é usada para pesquisas.

Então, a situação é: Existe uma variável de shell chamada PATH. Mas não é uma variável de ambiente. Isso significa que não é exportado para processos filhos recém-criados. Uma coisa, devemos aprender com isso, é que usando     echo $ PATH não é possível descobrir se a variável ambiente PATH está definida. Mesmo prolema com     conjunto | grep "^ PATH=" No entanto, uma maneira de fazer isso é usando o comando external env:     env | grep "^ PATH="

Exemplo de sessão de shell:

$ env -i bash
# A new shell is started with empty environment.
# What follows happens in this new shell:
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
$ set | grep "^PATH="
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
$ env | grep "^PATH="
$ which ls
which: no ls in ((null))
$ export PATH
$ env | grep "^PATH="
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
$ which ls
/bin/ls

Dependendo do que você está tentando alcançar, você pode pedir ao shell para agir como um shell de login, para bash it's -l. Com isso, / etc / profile e outros arquivos são fontes que configuram o PATH corretamente por padrão:

$ env -i bash -l
$ which ls
/bin/ls

A alternativa é exportar o PATH, veja acima.

    
por 13.09.2015 / 11:03
1

Eu posso reproduzir a mesma saída do tcsh:

env -u PATH which ls
which: no ls in ((null))

Em csh e tcsh, há uma distinção entre variáveis de ambiente (que são comuns a todos os processos) e variáveis de shell (que são locais para a invocação atual do shell). Ele usa a mesma sintaxe para se referir a ambos, por exemplo, $PATH . Se você tiver uma variável shell e uma variável de ambiente com o mesmo nome, então $PATH refere-se à variável shell.

[t] csh usa uma sintaxe diferente para definir shell vs. variáveis de ambiente:

set shell_var = foo
setenv env_var bar

(shells baseados em Bourne, como o bash, têm uma sintaxe diferente e uma terminologia diferente; uma variável de ambiente é uma variável do shell que foi "exportada" ou herdada do processo de chamada).

Com base nos sintomas que você descreve, você tem uma variável de shell $PATH (que é inútil), mas nenhuma variável de ambiente com o mesmo nome. Isso normalmente não deveria acontecer. Verifique seus arquivos .cshrc , .tcshrc e / ou .login para instruções que definem $PATH .

Você deve conseguir contornar o problema imediato como este:

setenv PATH "$PATH"   # set the environment variable
unset PATH            # unset the shell variable, just to avoid confusion

(Não faça o unset PATH até confirmar que as coisas estão funcionando corretamente.)

Só para aumentar a frivolidade, [t] csh tem uma variável especial shell $path (nota minúscula); seu valor é uma matriz que consiste nos componentes separados por : da variável de ambiente $PATH . A configuração atualizará automaticamente a outra:

 setenv PATH /usr/bin:/bin # sets $path to ( /usr/bin /bin )
 set path = ( /usr/local/bin $path ) # sets $PATH to '/usr/local/bin:/usr/bin:/bin'

Isso pode ser conveniente, mas se você preferir, pode ignorar $path e lidar com $PATH . Apenas certifique-se de que você está configurando a variável de ambiente $PATH (usando setenv ), não a variável de shell inútil do mesmo nome.

    
por 09.10.2012 / 02:50
0

Parece que sua variável de ambiente PATH é o problema. Por exemplo, se você executar which asdf normalmente, terá algo como:

which: no asdf in (/usr/local/bin:/usr/bin:...)

Portanto, parece que sua variável de ambiente PATH é algo como (NULL) . A outra possibilidade é que há algo errado com o binário em sua caixa do RHEL.

    
por 08.10.2012 / 23:21
0

Então, a questão é específica do redhat e do mecanismo de bifurcação. Processos filho não recebem o padrão env envs, enquanto no Ubuntu e Mac OSX eles são. Isso significa que eu tive que definir explicitamente o envp para o pai (em uma chamada para execve).

Pedimos desculpas pelo fraseado enganoso da minha pergunta (embora seja difícil identificar esse tipo de coisa).

Obrigado por toda a ajuda! Jon

    
por 09.10.2012 / 03:36

Tags