As variáveis numéricas aparecem no diretório quando eu executo o script bash

2

Eu escrevi um script Bash em um diretório. Quando eu o executo e, em seguida, executo 'ls', um número aparece no nível do diretório, no qual devo usar 'rm' para me livrar dele.

Este script Bash destina-se a salvar os arquivos atuais no diretório em logstore.txt , depois obter o número antigo de linhas armazenadas em numlines.txt e, em seguida, encontrar o novo número de linhas atribuindo isso a numlines.txt e finalmente obtendo o novo número de linhas para comparar com o número antigo (o servidor está adicionando novos arquivos ao longo do tempo, se você não pudesse adivinhar), em seguida, executo uma comparação entre os comprimentos de linha antiga e nova.

Aqui está o código em um arquivo .sh.

ls /home/vcm > /home/vcm/logstore.txt
oldnumlines=$(cat /home/vcm/numlines.txt)
#log store takes the new ls of items and stores it as num lines after the old v$
cat logstore.txt | wc -l > /home/vcm/numlines.txt

newnumlines=$(cat /home/vcm/numlines.txt)

if [ ! "$newnumlines" > "$oldnumlines" ]
#[ "$a" -eq "$b" ]
#(( "$newnumlines" -le "$oldnumlines" ))
 then
   *do something*
 fi

Por que esse script está criando novas variáveis no diretório?

    
por tbrick 11.07.2018 / 04:22

2 respostas

3

Veja como depurar algo assim. Eu tenho uma versão simplificada do seu script.

$ cat var_dumper.bash
#!/bin/bash

var1=1
var2=2

if [ ! "$var1" > "$var2" ]; then
   echo "I'm inside the if/then"
fi

E nós o rodamos:

$ ./var_dumper.bash
$ ls
var_dumper.bash  2

Assim, podemos ver seu 2 sendo exibido como um arquivo. Esse é o seu problema.

Depuração

Para depurar um script de shell, sempre começo com a opção -x para o Bash. Você pode executar seu script assim:

$ bash -x ./var_dumper.bash
+ var1=1
+ var2=2
+ '[' '!' 1 ']'

Isso nos diz onde está falhando. A condição if . Então, o que há de errado com isso? Bem, a primeira pista deve ser o > . Isso é um operador de redirecionamento, em outros usos no Bash, então é isso que provavelmente está produzindo o arquivo sendo escrito.

Então reformulemos seu exemplo em um único executável:

$ var1=1 var2=2 [ "$var1" > "$var2" ] && echo success || echo failure
success

A próxima pista deve ser, por que ela está retornando um sucesso, 1 não é maior do que 2. Então, o Google e descobrimos que para comparar inteiros no Bash você não usa o operador > , você está na verdade, suponha que use este: -gt .

$ var1=1 var2=2 [ "$var1" -gt "$var2" ] && echo success || echo failure
failure

E como você queria que fosse negado, poderíamos colocar o ! de volta em:

$ var1=1 var2=2 [ ! "$var1" -gt "$var2" ] && echo success || echo failure
success

E isso funciona. Então, sua instrução if corrigida ficaria assim:

if [ ! "$var1" -gt "$var2" ]; then
   echo "I'm inside the if/then"
fi

Então, o que havia de errado com >

No seu cenário, você estava usando if [ .... ] . Esta forma de if / then é a versão compatível com POSIX. Este não suporta o operador > . O formulário que suporta isso é isto, if [[ .... ]] . A versão com colchetes duplos é o comando teste estendido mais capaz.

Então, como alternativa:

$ cat var_dumper.bash
#!/bin/bash

var1=1
var2=2

if [[ ! "$var1" > "$var2" ]]; then
   echo "I'm inside the if/then"
fi

Também funcionaria:

$ bash -x var_dumper.bash
+ var1=1
+ var2=2
+ [[ ! 1 > 2 ]]
+ echo 'I'\''m inside the if/then'
I'm inside the if/then

Referências

por 11.07.2018 / 04:53
0

Não use > em um teste digital. Porque é um operador de redirecionamento.

Sua execução é sempre verdadeira (se o arquivo estiver escrito):

$ if [ 2 > 30000 ]; then echo OK; else echo NO; fi
OK
$ ls
$ 30000
$ rm 30000

E um arquivo de 30000 foi escrito.

Não houve teste digital, mas uma gravação de arquivo, que retornou verdadeiro

$ mkdir tmp
$ chmod -w tmp
$ cd tmp
$ if [ 2 > 30000 ]; then echo OK; else echo NO; fi
-bash: 30000: Permission non accordée
NO
$ cd ..
$ rmdir tmp

Use -gt:

$ if [ 2 -gt 30000 ]; then echo OK; else echo NO; fi
NO
$ ls
    
por 12.07.2018 / 22:45