So I have this If statement that checks what the exit code of the script is:
if [ $? -eq 0 ]; then
wasSuccessful=true;
fi
In other languages, I would do something like:
while wasSuccessful == false
And then the loop would keep running until the exit code was true. (I plan to implement a loop counter as well for too many failed attempts, but that's a different problem to solve)
I think I need a here-string, but I'm not exactly sure how that would look. Here's a rough outline of my code right now, in Bash:
wasSuccessful=false
while [ "$wasSuccessful" = "false" ]
do
#Bunch of code here, then the check for exit code
if [ $? -eq 0 ]; then
wasSuccessful=true;
fi
done
Any suggestions on how to do something like this would be much appreciated :)
The question is how to exit while loop when the latest command execute successfully inside while loop?
You don't need a global variable to check. Just check the status of previous command and break it if succeed.
while true
do
# a bunch of code here
[ $? -eq 0 ] && break
done
Related
I'm using the using the cmp command to check if two files are identical. I would like to stick the command into a one line if statement but it's not working as expected. When comparing two files and one the files doesn't exist, cmp returns 2. Since 2 is non-zero, I would expect the if statement to evaluate to true, but it does not and I don't understand why.
I want to write something like:
if cmp -s tickets.txt tickets_orig.txt; then
#do stuff here
fi
because I find it short, sweet and more intuitive. Is this possible?
I was able to create a workaround by using $?, but I don't understand why the code below will evaluate to true and the code above will evaluate to false when the command returns 2:
cmp -s tickets.txt tickets_orig.txt
if [ $? -ne 0 ]; then
#do stuff here
fi
Exit status ($?) = 0 means success in shell logic, it allows to define different error codes 1 to 127 for anormal status
if command; then #...
is equivalent to
command;
if [ $? -eq 0 ]; then #...
and
command;
if [ $? -ne 0 ]; then #...
equivalent to
if ! command; then #...
So here's my situation.
I want to be able to exit RC/RC1 which has a non-zero value. When the below code is executed if RC is 0 RC1 is returned with a non-zero exit code(best case scenario) if RC is non-zero and RC1 is also non-zero i will miss exit code of RC1(meaning i will not be able to use RC1's exit code). How can i send the right exit code? In essence i would like to email the non-zero variable
if [ $RC -ne 0 ] || [ $RC1 -ne 0 ]; then
if [ $RC -ne 0 ]; then
exit $RC
else
exit $RC1
fi
You want to return two exit codes at the same time? I guess that, when driving a car, you also want to sit on the front seat and on the back seat at the same time. You can do it, but you need a special car for this. Here are two ideas for making such a car:
If you know that in this context each exit code must be a 1-digit number, you could return something like $((RC*10+RC2)) - I'm using bash/zsh syntax here, as you didn't say which shell you are using. If necessary, you have to adapt this to your shell.
You could adapt the interface of your script, by printing something like "$RC1 $RC2" to stderr if at least one of them is non-zero, i.e.:
if [ $RC -ne 0 ] || [ $RC1 -ne 0 ]; then
echo "$RC $RC1" 1>&2
exit 1
else
exit 0
fi
In both cases, the calling process has to take apart the combined exit code to get back the original ones.
Looking at correcting an issue in /etc/init.d/hostapd on Debian. However, I have no clue what this line of code does nor how it works
[ -n "$DAEMON_CONF" ] || exit 0
In searching online for bash tutorials, I've never seen anyone do this
When I run the code, my shell window closes (because $DAEMON_CONF is not set to anything). If I change the code to
[ -n "not empty" ] || exit 0
my console window does not close.
so, -n evaluates to true, and or'ed with exit 0, is what?
If the expression in [] returns false, do the thing after the or || (and exit 0). Otherwise, it will short circuit and the next statement will be evaluated.
[ is and alternate name for the command test. You can learn about the parameters/flags whatnot by looking at test's manpage:
man test
You'll see for -n:
-n STRING
the length of STRING is nonzero
Furthemore || means OR. So if the test command returns False then the stuff after the || will be executed. If test returns true, then it won't be executed.
Written out your command says: "If the variable $DAEMON_CONF lacks a value, then exit with return code 0"
The longhand version would be something like:
if test ! -n "$DAEMON_CONF"; then
exit 0
fi
[ -n "$DAEMON_CONF" ] || exit 0
It's an unnecessary double negative. This would do the same thing:
[ -z "$DAEMON_CONF" ] && exit 0
Or it could be done without any flag:
[ "$DAEMON_CONF" ] || exit 0
It checks if the environment variable is defined, if $DAEMON_CONF is not present the it will exit with 0 code, a better code would be.
[ -n "$DAEMON_CONF" ] || echo "exiting as DAEMON_CONF is not set" && exit 1
I'm trying to customize my bash prompt. I want it so change color if I enter a command that doesn't exist, or for some other reason fails. I'm fairly new with coding bash scripts, so I looked at some other scripts so get some help, but something's not working. Here's my code:
export PROMPT_COMMAND="
PS1='`
if [ $? -eq 0 ];
then echo '
\[\033[00;32m\]┌─\[\033[00;35m\]\u\[\033[01;32m\]#
\[\033[00;35m\]\h\n\[\033[00;32m\]└─\[\033[01;32m\]
(\[\033[01;35m\]\W\[\033[01;32m\])\[\033[00;32m\]\$';
else echo '
\[\033[00;31m\]┌─\[\033[00;35m\]\u\[\033[01;31m\]#
\[\033[00;35m\]\h\n\[\033[00;31m\]└─\[\033[01;31m\]
(\[\033[35m\]\W\[\033[31m\])\[\033[00;31m\]\$';
fi`\[\033[0m\]'"
I do not have any linebreaks in the actual code, since that would be messy with PS1, I just added them to make the code easier to read.
So, I want to compare the exit status, $?, to 0. For some reason the variable $? doesn't change at all in the script. It just remains 0, so the first condition is always true, even when I issue a faulty command. I've tried adding echo $? to the code before the if-case, and this always returns 0, even if issuing echo $? as a command to the terminal returns something different. I've tried copying working code into mine, but that doesn't solve it either. Also, it worked when I used ' as the outer citation and " as the second. I changed this because the script wouldn't accept ( as a character otherwise.
Any ideas why this is and how I can fix it?
The problem in your code is that that your quotation is broken:
export PROMPT_COMMAND="
PS1='`
if [ $? -eq 0 ];
then echo '
Generally it should work, try this:
PS1='`if [ $? -eq 0 ] ; then echo Y:; else echo N:; fi`
Here is the output after applying the code:
$ PS1='`if [ $? -eq 0 ] ; then echo Y:; else echo N:; fi`'
Y:
Y:
Y:
Y:false
N:
N:
N:true
Y:
Y:
Note: Simply pressing the ENTER key, doesn't change the prompt.
Just as as a follow up to H.-Dirk Schmitt's great answer, this works for me (I'm not going to bother explaining the code, that has been done already better than I could);
PS1='`
if [ $? -eq 0 ];
then echo -n "\[\033\[00;35m\]\u\[\033\[01;32m\]#\[\033\[00;35m\]\h\[\033\[00;32m\](\[\033\[01;35m\]\W\[\033\[01;32m\])\[\033\[00;32m\]\$";
else echo -n "\[\033\[00;35m\]\u\[\033\[01;31m\]#\[\033\[00;35m\]\h\[\033\[01;31m\](\[\033\[35m\]\W\[\033\[31m\])\[\033\[00;31m\]\$";
fi`\[\033\[0m\]'
Ok I know I've asked a similar question, I understand how to do an infinate loop:
while [ 1 ]
do
foo
bar
then
sleep 10
done
But if I want to run some (quite a few) IF ELSE Statements in this loop how would I get the script to carry on looping once they had completed how would I go about this?
while :; do
if cond1; then
whatever
elif cond2; then
something else
else
break
fi
done
You do infinite loop using while true or using true's shorter alias :. [ 1 ] is needlessly complicated and is not what you think it is ([ 0 ] is also true!). Remember, the condition in if and while is arbitrary command whose exit status (zero = true, nonzero = false) is used as the condition value and [ is just alias for special test command (both built-in in most shells, but they don't have to be).
Any shell construct is allowed between do/done including conditionals, more loops and cases.
Use break to terminate innermost loop from inside (just like most other languages).
An if in bash is just: if [ some test ]; then some_command; fi:
while [ 1 ]
do
if [ some test ]
then
some command
else
other cmd
fi
sleep 10
done
Bash Scripting Guide
Correction to chown case added brake to finish the loop
Corrected
while [ 1 ]
do
if [ some test ]
then
some command
brake
else
other cmd
fi
sleep 10
done