Qual é o significado de if [-n “$ (que voltdb 2 / dev / null)”] ;?

3

Eu tenho habilidades linux muito básicas e agora estou tentando analisar alguns scripts de shell. Eu vejo essa linha em um dos scripts:

if [ -n "$(which voltdb 2> /dev/null)" ];

Eu sei que / dev / null é o bit bucket e o que imprime o caminho que teria sido executado se eu tivesse executado o voltdb na linha de comando. Além disso, a linha inteira é obviamente uma declaração if. Mas estou confuso sobre muitas outras coisas aqui.

  1. Por que 2 está sendo comparado a / dev / null? Estes parecem tipos incompatíveis.
  2. O que a opção -n faz? Estou acostumado a usar switches como rm -r filename mas o -n não parece emparelhar com nenhum comando
  3. O que os colchetes fazem? Eles parecem significar algo mais aqui do que nesta expressão Qual é a significado desta expressão de teste []?

Basicamente, o que essa linha faz? Há muitas incógnitas nisso para mim - então é um pouco como ouvir uma frase em uma língua estrangeira e perder tantas palavras que você não consegue entender a estrutura básica.

    
por bernie2436 10.10.2013 / 21:06

2 respostas

4

Há muita coisa acontecendo nesse fragmento de código. Trabalhando de dentro para fora:

which voltdb 2> /dev/null - O comando executado aqui é which . which como invocado, irá procurar todas as entradas na variável de ambiente PATH para encontrar um comando chamado "voltdb". Se encontrar um arquivo executável chamado "voltdb" em um dos diretórios nomeados em PATH , ele imprimirá o nome completo do arquivo executável voltdb .

Para responder ao seu # 1, o "2 >" é um exemplo de redirecionamento. Todo processo Unix / Linux / * BSD possui 3 entradas e saídas padrão, 0 é stdin, 1 é stdout, 2 é stderr. Programas destinados a executar na linha de comando normalmente imprimem mensagens de erro para stderr. Então, "2 > / dev / null" não está comparando numericamente 2 com "/ dev / null", ele está enviando qualquer saída de erro which para /dev/null , um arquivo especial que apenas come qualquer entrada e devolve 0 bytes de saída.

Fora isso, a construção $(...) significa "execute o comando incluído e substitua lexicamente qualquer saída aqui, entre '$ (' e ')'". Essa é a substituição de saída, algo que os programas shell fazem.

Fora da substituição de saída, o fragmento faz if [ -n "something" ]; , onde "algo" é o que which teria impresso. O "if" é uma construção de fluxo de controle do shell, fazendo com que um bloco de código seja executado quando o pipeline de comandos após o "if" sair com um status de "sucesso".

O [ é realmente um executável, que examina os argumentos da linha de comando até o ] . O sinalizador "-n" geralmente significa "true no próximo argumento de comprimento de cadeia não zero". Essa é a resposta para suas perguntas # 2 e # 3. A construção [ ... ] fornece respostas verdadeiras (saída com código de sucesso) ou falsas (saída com código de falha) para algumas condições lógicas, neste caso "comprimento de cadeia diferente de zero".

Em última análise, esse fragmento executaria a cláusula "true" de um fluxo de controle if-then-fi ou if-then-fi-fi quando o PATH desse shell tiver um diretório com um arquivo executável voltdb .

    
por 10.10.2013 / 21:19
2

Esse código está fazendo o seguinte:

if [ -n "...." ];

A declaração if é verdadeira se os resultados do código quando executados nas aspas duplas estiverem vazios.

O código entre aspas duplas:

$(which voltdb 2> /dev/null)

Executa o comando which voltdb e redireciona qualquer saída desse comando que ocorra no STDERR (erro padrão) para /dev/null . Basicamente não estamos interessados nisso, então estamos ignorando isso.

Os resultados de which voltdb retornarão o caminho para qualquer executável em seu PATH que corresponda à cadeia voltdb.

Exemplo

$ which time
/usr/bin/time

$ which time 2> /dev/null
/usr/bin/time

E quanto ao 2> ?

2> é uma notação abreviada para redirecionar a saída de um dos fluxos configurados automaticamente para um programa quando é executado. Os fluxos são os seguintes:

  • 0 - padrão em (também conhecido como STDIN)
  • 1 - saída padrão (também conhecida como STDOUT)
  • 2 - erro padrão (também conhecido como STDERR)

Então, se você quiser pegar o resultado do STDERR e se livrar dele:

$ which time 2> /dev/null

Se você quiser pegar a saída do STDOUT e redirecioná-la para o STDERR:

    
por 10.10.2013 / 21:12