Bash script not behaving like I'd expect - bash

I've poured over question after question searching here and on Google, but something in my syntax is messed up. Any assistance is appreciated.
Basically I've got another function that sets the load and threshold, as well as $FORCE variable. The script needs to do the "stuff" if it meets either the first or the second condition. The variables have been set correctly, which I've confirmed via echo in the script while debugging.
if ([ $LOAD -ge "$THRESH" ] || [ $FORCE=1 ]);
then
# do some other stuff
fi
From what I can see, my spacing of the brackets around the conditions are correct. They no longer produce bash [: missing]'` errors like they were.
The script runs fine, except for one issue...it runs no matter what. It's like it's completely ignoring the [ $FORCE=1 ] part, even though I can see that $FORCE is in fact actually 0.
Should I be using single quotes or some other method?

Try putting spaces around =:
if ([ $LOAD -ge "$THRESH" ] || [ $FORCE = 1 ]);
then
# do some other stuff
fi

Related

Bash output to same line while preserving column

Ok, this is going to seem like a basic question at first, but please hear me out. It's more complex than the title makes it seem!
Here is the goal of what I am trying to do. I would like to output to console similar to Linux boot.
Operating system is doing something... [ OK ]
Now this would seem to be obvious... Just use printf and set columns. Here is the first problem. The console needs to first print the action
Operating system is doing something...
Then it needs to actually do the work and then continue by outputting to the same line with the [ OK ].
This would again seem easy to do using printf. Simply do the work (in this case, call a function) and return a conditional check and then finish running the printf to output either [ OK ] or [ FAIL ]. This technically works, but I ran into LOTS of complications doing this. This is because the function must be called inside a subshell and I cant pass certain variables that I need. So printf is out.
How about just using echo -n? That should work right? Echo the first part, run the function, then continue echoing based on the return to the same line. The problem with this solution is I can no longer preserve the column formatting that I can with printf.
Operating system is doing something... [ OK ]
Operating system is doing something else... [ OK ]
Short example... [ OK ]
Any suggestions how I can fix any of these problems to get a working solution? Thanks
Here is another way I tried with printf. This gives the illusion of working, but the method is actually flawed because it does not give you the progress indication, ie the function runs first before it ever prints out the the function is running. The "hey im doing stuff" prints immediately with the "hey im done" message. As a result, its pointless.
VALIDATE $HOST; printf "%-50s %10s\n" " Validating and sanitizing input..." "$(if [ -z "$ERROR" ]; then echo "[$GREEN OK $RESET]"; else echo "[$RED FAIL $RESET] - $ERROR"; echo; exit; fi)"
There's no particular reason all the printf strings have to be printed together, unless you're worried some code you call is going to move the cursor.
Reordering your example:
printf "%-50s " " Validating and sanitizing input..."
VALIDATE $HOST
if [ -z "$ERROR" ]; then
printf "%10s\n" "[$GREEN OK $RESET]";
else
printf "%10s\n" "[$RED FAIL $RESET] - $ERROR"
echo
exit
fi
I have no idea what $ERROR contains or where it is supposed to display.

Check if file does have different permission than 644 in Bash

I have to change permission of a file to 644 if the file does have a different permission than 644.
I have thought of something like this:
if [ $(stat -c %A $soubor) ! -eq (-rw-r--r--) ];then...
However, it gives errors like:
integer expression expected
or if I modify it a little, then:
syntax error):
You're using [ wrong. It's the same as test, so man test gives you the manual page to it.
Basically, [ is a program you call with arguments. For nicer looks, [ requires the last paramter to be ], but there is not technical reason for that.
When you call [ $a == $b ], it fails because [ will compare $a to = and complain about the $b which it does not expect. So if you want to develop it POSIX-compliant, you need to use = instead of ==.
-eq does a numeric compare so -rw-r--r-- will cause a syntax error because it's not numeric.
= will do a string compare, so this is what you need.
You compare with (-rw-r--r--) which will be evaulated as command, so you need to add quotes around it (see my comment on your question, I used the octal syntax).
Also, you need to remove the braces so it becomes '-rw-r--r--'. I assume you added them because they were on the left side of your if statement.
The reason for the braces on the left is command execution. When you wrap something into $(), it will get executed and the output of the command will be filled in there. So after the shell evaluated the expression, it can look like this:
'[' '-rw-rw-rw-' '=' '-rw-r--r--' ']'
When you use set -x anywhere in your shell script, you can see what it acutally does which helps a lot. You can disable it with set +x afterwards as it's very verbose.

While loop in .sh file with condition to compare if a string contains a substring

I have a .sh file in which I have written the following function. The command that calls this function will have the arguments- file1.war, file2.war ... fileN.war and other arguments.
I want to do a certain operation to the .war files and something else for the arguments after it. So I have written a while loop that will run till the arguments are .war files, and when an argument is encountered without .war extention, it will exit the loop and run the code below it for the rest of the arguments.
Here is the function in .sh file :
copyWarFiles()
{
downloadFileName=$1
shift 1
extn=".war"
while [ condition ]
do
log "war file $downloadFileName .."
#some operation..
downloadFileName=$1
shift 1
done
#operations for the rest of the arguments...
}
What should I give as condition that will return true if $downloadFileName ends with .war? I tried giving
$downloadFileName==*".war" (following the accepted answer in this )
and I also tried this :
`test "${downloadFileName#*$extn}" != "$downloadFileName"`
(following the accepted answer here) where extn is another variable I declared and assigned to .war.
But in both the cases, I see that it never enters the while loop. I think I have gone wrong with the syntax or something. Thank you for your help in advance.
What should I give as condition that will return true if $downloadFileName ends with ".war"? I tried giving $downloadFileName==*".war" […]
Bash, unlike typical programming languages, doesn't recognize == as a special operator; it's just yet another argument to the [ command. So you need to set it off with spaces.
Also, the [ command doesn't support having a pattern on the right-hand-side of ==; you need to use the special [[ ... ]] notation.
So:
while [[ $downloadFileName == *".war" ]]
Note, though, that the double-quotes around .war don't actually have any effect: none of the characters in .war are special characters that need to be quoted. Conversely, it's a best practice to always put variable expansions in double-quotes, in case the variables contain special characters. ([[ actually negates most of the problematic behaviors, but it's just a good habit to be in.)
So:
while [[ "$downloadFileName" == *.war ]]
Why not just:
check=`echo $downloadFile | grep '\.war'`
if [ -n "$check" ]; then
echo $downloadFile ends in .war
fi

Error: =: command not found (Bash Script)

I found a nifty little shell script that I wanted to use from this website here. I have followed everything step-by-step, but receive the following error when running this on my CentOS box.
./deploy: line 3: =: command not found
Line 3 only contains...
$ERRORSTRING = "Error. Please make sure you've indicated correct parameters"
I've tried toying around with a bit, but don't understand why it won't accept the "=" character. Is there something wrong with the script, or is it merely something different in the way that my server processes the script?
Thanks!
Gah, that script is full of bad scripting practices (in addition to the outright error you're running into). Here's the outright error:
$ERRORSTRING = "Error. Please make sure you've indicated correct parameters"
As devnull pointed out, this should be:
ERRORSTRING="Error. Please make sure you've indicated correct parameters"
A couple of lines down (and again near the end), we have:
echo $ERRORSTRING;
...which works, but contains two bad ideas: a variable reference without double-quotes around it (which will sometimes be parsed in unexpected ways), and a semicolon at the end of the line (which is a sign that someone is trying to write C or Java or something in a shell script). Use this instead:
echo "$ERRORSTRING"
The next line is:
elif [ $1 == "live" ]
...which might work, depending on whether the value of $1 has spaces, or is defined-but-blank, or anything like that (again, use double-quotes to prevent misparsing!). Also, the == comparison operator is nonstandard -- it'll work, because bash supports it in its [ ... ] builtin syntax, but if you're counting on having bash extensions available, why not use the much cleaner [[ ... ]] replacement? Any of these would be a better replacement for that line:
elif [ "$1" = "live" ]
elif [[ $1 == "live" ]]
elif [[ "$1" == "live" ]]
Personally, I prefer the last. The double-quotes aren't needed in this particular case, but IMO it's safest to just double-quote all variable references unless there's a specific reason not to. A bit further down, there's a elif [ $2 == "go" ] that the same comments apply to.
BTW, there's a good sanity-checking tool for shell scripts at www.shellcheck.net. It's not quite as picky as I am (e.g. it doesn't flag semicolons at the ends of lines), but it pointed out all of the actual errors in this script...
"Devnulls" answer was correct -- I had to remove the spaces around the "=" and remove the "$" from that line as well. The end result was...
ERRORSTRING="Error. Please make sure you've indicated correct parameters"
I've upvoted Devnull and gniourf_gniourf's comments.
Thank you to all whom have assisted!

comparing variables in bash script using if statements

So I'm pretty new to bash scripting but so far tldp.org has been a good friend. Anyways I've confused myself and swearing to much so looking for help in clarification: I declare a variable like such
MAXseeds=-1;
sumS=0
I do a bunch of things in my script and get a new value for sumS which is an integer value. I would then like to compare MAXseeds and sumS if sumS is larger make MAXseeds equal to sumS. I do this by:
echo $MAXseeds
echo $sumS
if [ $MAXseeds -lt $sumS ];
then
MAXseeds = $sumS
best_file=$COUNT
fi
echo $MAXseeds
This from what I can tell should work however the terminal output I get when running over this section of script is
-1
492
lookup.sh: line 34: MAXseeds: command not found
-1
Basically I am wondering what I am doing wrong here? why does it respond with command not found? Any explanation to why this is incorrect would be greatly appreciated.
Try this:
if [ $MAXseeds -lt $sumS ];
then
MAXseeds=$sumS
best_file=$COUNT
fi
Without the spaces around "=".
If you put a space after "MAXseeds", then it will be interpreted as a command. And of course, it is not a command, thus you get your error message.

Resources