2

I have written a Bash script in a directory. When I run it and then run 'ls' a number appears in the directory level which I must then use 'rm' to get rid of.

This Bash script is meant to save the current files in the directory to logstore.txt then get the old number of lines stored in numlines.txt then find the new number of lines assigning this to numlines.txt and finally getting the new number of lines to compare to the old number (the server is adding new files over time if you couldn't guess) I then run a comparison between the old and new line lengths.

Here is the code in a .sh file.

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

Why is this script creating new variables in the directory?

3

Here's how to debug something like this. I have a simplified version of your script.

$ cat var_dumper.bash
#!/bin/bash

var1=1
var2=2

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

And we run it:

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

So we can see your 2 showing up as a file. That's your issue.

Debugging

To debug a shell script, I always start with the -x switch to Bash. You can run your script like this:

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

This tells us where it's failing. The if condition. So what's wrong with it? Well the first clue should be the >. That's a redirect operator, in other usages in Bash, so that's what's likely producing the file being written.

So let's reformulate your example into a single executable:

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

The next clue should be, why is it returning a success, 1 isn't greater than 2. So we google and we discover that to compare integers in Bash you don't use the > operator, you're actually suppose to use this one: -gt.

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

And since you originally wanted it negated, we could put the ! back in:

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

And it works. So your corrected if statement would look like this:

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

So what was wrong with >

In your scenario you were using if [ .... ]. This form of if/then is the POSIX compliant version. This one does not support the > operator. The form that does support that is this, if [[ .... ]]. The double bracketed version is the more capable extended test command.

So as an alternative:

$ cat var_dumper.bash
#!/bin/bash

var1=1
var2=2

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

Would also work:

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

References

0

Do not use > in a digital test. Because it is a redirection operator.

His execution is always true (if the file is written) :

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

And a 30000 file was written.

There was no digital test but a file write, which returned true

$ 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.