Bash test wc com '-ge' - divisão por erro 0

2

Abaixo do script, está ocorrendo erro:

#!/bin/bash  
if [[ $(wc -l "/disk1/environment.sh") -ge 0 ]];then  
   echo "File has data"  
fi

line 2: [[: 5 /disk1/environment.sh: division by 0 (error token is "/environment.sh")

Mas o código abaixo está funcionando bem:

#!/bin/bash  
  if [[ $(wc -l "/disk1/environment.sh") > 0 ]];then  
    echo "File has data"  
  fi

Alguém poderia me dizer por que '-ge' e '>' está se comportando diferente aqui?
versão bash: GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)

    
por penguin 07.02.2017 / 04:44

2 respostas

7

Por causa da saída de wc -l /filename , isso produziria, por exemplo:

5 /filename

mas você está fazendo uma comparação de inteiros (operador: -ge ), portanto, a parte estranha /filename é inválida, levando à mensagem de erro.

Basta passar o nome do arquivo para wc via STDIN para que wc apenas retorne a contagem:

[[ $(wc -l </disk1/environment.sh) -ge 0 ]]

No segundo caso, [[ $(wc -l /disk1/environment.sh) > 0 ]] , você está simplesmente verificando se a saída da substituição do comando, $(wc -l /disk1/environment.sh) , classifica após 0 , lexicograficamente; que sempre será o caso, a menos que wc retorne algum erro e não produza nada no STDOUT.

Apenas para observar, [[ não suporta operadores aritméticos como > , >= , < , <= , você precisa da palavra-chave (( para estes:

(( $(wc -l </disk1/environment.sh) > 0 ))
    
por 07.02.2017 / 04:48
0

A segunda tentativa não produz um erro, mas não funciona bem, supondo que sua tentativa seja testar se o arquivo contém pelo menos uma linha.

A saída de wc -l "/disk1/environment.sh" consiste no número de linhas no arquivo, um espaço e o nome do arquivo. Se você quiser usar o número de linhas, você precisa extraí-lo. Em vez de dividir a saída, há uma maneira mais fácil: em vez de passar o nome do arquivo na linha de comando, redirecione a saída de wc do arquivo. Então, wc apenas imprime o número sem nome de arquivo.

if [[ $(wc -l <"/disk1/environment.sh") -ge 0 ]];then  
   echo "File has data"  
fi

Ou, como você está usando a sintaxe bash de qualquer maneira,

if (($(wc -l <"/disk1/environment.sh") >= 0)); then  
   echo "File has data"  
fi

Claro que isso é sempre verdade, já que o número de linhas é sempre maior ou igual a 0. Mas você pode obter resultados úteis com outros números.

Na sua primeira tentativa, você usa o operador -ge . Este é um operador em números inteiros. Você recebe uma mensagem de erro porque o lado esquerdo não é um inteiro, mas algo como 42 /disk1/environment.sh .

Na sua segunda tentativa, você usa o operador < em uma instrução condicional. Este operador é uma comparação de string (em ordem lexical). Acontece que a saída de wc -l /disk1/environment.sh é sempre ordenada lexicalmente após 0 , já que começa com um dígito, portanto [[ $(wc -l <"/disk1/environment.sh") > 0 ]] é sempre verdadeiro. A exceção é quando /disk1/environment.sh não existe; Nesse caso, wc -l não produz nada na saída padrão (ele grava uma mensagem de erro no erro padrão) e a comparação é falsa.

Comparar o número de linhas em um arquivo como 0 não é muito útil. Nos sistemas modernos, wc -l conta o número de novas linhas. Em um arquivo de texto, o número de novas linhas será 0 somente se o arquivo estiver vazio. (Em geral, wc -l retorna 0 se o arquivo não contém nenhum caractere de nova linha; um arquivo de texto contém uma nova linha no final de cada linha eo número de novas linhas em arquivos que não são texto raramente é uma informação útil.) operador em expressões condicionais para testar se um arquivo está vazio, você não precisa invocar wc .

if [[ ! -e /disk1/environment.sh ]]; then
  if [[ -L /disk1/environment.sh ]]; then
    echo "/disk1/environment.sh is a broken symbolic link"
  else
    echo "/disk1/environment.sh does not exist"
  fi
elif [[ ! -r /disk1/environment.sh ]]; then
  echo "/disk1/environment.sh exists but is not readable"
elif [[ ! -s /disk1/environment.sh ]]; then
  echo "/disk1/environment.sh is empty or is a special file (name pipe, etc.)"
else
  echo "/disk1/environment.sh is not empty"
fi
    
por 08.02.2017 / 03:00