Qual é o significado de if [ -n "$(qual voltdb 2> /dev/null)" ];?

Qual é o significado de if [ -n "$(qual voltdb 2> /dev/null)" ];?

Tenho habilidades básicas em Linux e agora estou tentando analisar alguns scripts de shell. Vejo esta linha em um dos scripts:

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

Eu sei que /dev/null é o bloco de bits e aquele que imprime o caminho que teria sido executado se eu tivesse executado voltdb na linha de comando. Além disso, toda a linha é obviamente uma instruçã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 opções como rm -r filename, mas o -n não parece emparelhar com nenhum comando
  3. O que os colchetes fazem? Eles parecem significar algo diferente aqui do que nesta expressãoQual é o significado desta expressão de teste []?

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

Responder1

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

which voltdb 2> /dev/null- O comando executado aqui é which. whichconforme invocado, procurará todas as entradas na PATHvariável de ambiente 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 voltdbarquivo executável.

Para responder ao seu número 1, o "2>" é um exemplo de redirecionamento. Cada processo Unix/Linux/*BSD possui 3 entradas e saídas padrão, 0 é stdin, 1 é stdout, 2 é stderr. Os programas destinados a serem executados na linha de comando normalmente imprimem mensagens de erro no stderr. Portanto, "2> /dev/null" não está comparando numericamente 2 com "/dev/null", está enviando qualquer whichsaída de erro para /dev/null, um arquivo especial que apenas come qualquer entrada e retorna 0 bytes de saída.

Fora disso, a $(...)construção significa "executar o comando incluído e substituir lexicamente qualquer saída aqui, entre '$(' e ')'". Isso é 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 "alguma coisa" é o que whichteria sido 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" sai com um status de "sucesso".

Na [verdade, é um executável que analisa os argumentos da linha de comando até o arquivo ]. O sinalizador "-n" geralmente significa "verdadeiro no próximo argumento com comprimento de string diferente de zero". Essa é a resposta às suas perguntas nº 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 string 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-else-fi quando o PATH desse shell tiver um diretório com um voltdbarquivo executável nele.

Responder2

Esse código está fazendo o seguinte:

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

A instrução if é verdadeira se os resultados do código quando executado entre aspas duplas estiverem vazios.

O código entre aspas duplas:

$(which voltdb 2> /dev/null)

Executa o which voltdbcomando e redireciona qualquer saída desse comando que ocorre em STDERR (erro padrão) para /dev/null. Basicamente não estamos interessados ​​nisso, então estamos ignorando.

Os resultados de which voltdbretornarão o caminho para qualquer executável em seu PATH que corresponda à string 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 dosfluxosque é configurado automaticamente para um programa quando ele é executado. Os fluxos são os seguintes:

  • 0 - entrada padrão (também conhecida 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 a saída do STDERR e se livrar dela:

$ which time 2> /dev/null

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

informação relacionada