If condition not work regular in bash - bash

Code
if [ $setup==="y" ]
then
echo "kurulum:"$setup
exit
full_dir=$full_dir"/public"
else
echo "Sub-Public folder is exist? [public,web]"
read folder_extend
if [ $folder_extend ]
then
full_dir=$full_dir"/"$folder_extend
fi
fi
Setup param $setup view as "n" after run sh but still condition firts part run. Where wrong code ?
Thanks.

Change it to:
if [ "$setup" = "y" ]
then
echo "kurulum:"$setup
exit
full_dir=$full_dir"/public"
else
echo "Sub-Public folder is exist? [public,web]"
read folder_extend
if [ "$folder_extend" ]
then
full_dir=$full_dir"/"$folder_extend
fi
fi
It should just be a single =, and you need spaces around it. You should also quote variables in most contexts, in case they contain spaces.

Related

Shell Script compare the values with input parameter

apps="http:git.abc.com";
cluster-ui="http:git.xyz.com";
customer-ui="http:git.xxx.com";
SERVICE=$1;
My requirement is if I pass service name as a 'apps' then I need to clone the $apps url.
Here
if [ $Service -eq apps ]
not think a good approach as my repo url might get increased so more and more loop will come
Any suggestions?
The $ sign assigns the input argument, so we're getting first input if it matches the below variable, so do what you want inside if condition.
#!/bin/bash
apps="http:git.abc.com";
clusterui="http:git.xyz.com";
customerui="http:git.xxx.com";
#SERVICE=$1;
#Store global
repo=''
# if empty parameter is passed
if [ $# -lt 1 ] ; then
echo "Parameters Need"
exit 1
fi;
# for search the correct parameter
if [ $1 = "apps" ]; then
repo=$apps
elif [ $1 = "cluster-ui" ] ; then
repo=$clusterui
elif [ $1 = "customer-ui" ] ; then
repo=$customerui
else
echo "Not found"
fi;
echo $repo
Note just repeat elif [ ] ;then for more entries or think!
how to access run this file like this sh ./file.sh apps just replace apps with yours. make sure you have permission to execute the file if you don't have, give it to permission like below
chmod 766 file
now run the shell script sh ./file.sh clusterui
'Case statement' would suit here more than if ladder

The `continue` inside `if condition` is not going to next lines of the script

I have a bash script with an if condition and continuous lines of script. However, after if condition nothing in the script seems to run. For example, here are the lines of script (The lines after continue in if condition are not reacting).
dir=/usr/path/tofiles
for file in $(find $dir -name \*txt)
do
fbase={file%.txt}
if [ "$step" == "1" -a ! -f "${fbase}.header" ]
then
continue
fi
### From here nothing in the script runs #####
if [ -f "${fbase}merged" ]
then
echo "$file already merged"
fi
files="$files ${fbase}g.txt.gz"
cnt=$(($cnt + 1))
if [ "$cnt" -eq "$chunksize" ]
then
outid=$(uuidgen)
logfile=${outdir}/${outid}.cluster.log
echo "sh $(pwd)/mysecript.sh $outid $files"
fi
done
After the first if condition nothing in the script is running, I tried printing using echo nothing is showing up. Precisely, the issue is after the continue statement within the if condition. Any help/suggestions are much appreciated.
Thanking you
You seem to have a wrong interpretation of the continue statements.
The continue statement skips the lines below it and starts with the next iteration.
while (true) {
print(1);
if (true) {
continue;
}
print(2);
}
In the above print(2) will never get executed as it skips it everytime and starts with the next iteration.
For deeper insight please read Nested-If statements in Shell-scripting
For your scenario please try this
dir=/usr/path/tofiles
for file in $(find $dir -name \*txt)
do
fbase={file%.txt}
if ! [ "$step" == "1" -a ! -f "${fbase}.header" ]
then
if [ -f "${fbase}merged" ]
then
echo "$file already merged"
fi
files="$files ${fbase}g.txt.gz"
cnt=$(($cnt + 1))
if [ "$cnt" -eq "$chunksize" ]
then
outid=$(uuidgen)
logfile=${outdir}/${outid}.cluster.log
echo "sh $(pwd)/mysecript.sh $outid $files"
fi
fi
done
The problem with your script is, that in case your first if statement evaluates always to true you'll always skip the rest of the loop, due to the continue, so nothing else will be executed. This behavior is the same as in all other programming languages.
continue, like break, is a keyword to control the loop behavior. This means that using continueit is possible to skip the rest of the current loop iteration. And using break it is possible to exit the loop.
In case you need to go further to the next if statement, you need to nest your ifs, so that both are checked/evaluated.
More background information regarding this issue can be found here.
According to your comments, your code should include nested ifs, like:
dir=/usr/path/tofiles
for file in $(find $dir -name \*txt)
do
fbase={file%.txt}
if [ "$step" == "1" -a ! -f "${fbase}.header" ]
then
if [ -f "${fbase}merged" ]
then
echo "$file already merged"
fi
files="$files ${fbase}g.txt.gz"
cnt=$(($cnt + 1))
if [ "$cnt" -eq "$chunksize" ]
then
outid=$(uuidgen)
logfile=${outdir}/${outid}.cluster.log
echo "sh $(pwd)/mysecript.sh $outid $files"
fi
fi
done

What does [ "$var" ] && $var do?

I was going through a codebase and came across the following piece of code in a shell script:
./some_script.sh
errcode=$?
if [ "$errcode" != 0 ]; then
[ "$SCRIPT_PATH" ] && $SCRIPT_PATH do_something
fi
SCRIPT_PATH is an environment variable which expands to the path of a script (say /usr/bin/abc.sh). However, I do not understand what the code in the if loop does. What does [ "$SCRIPT_PATH" ] do? Is there any use of it or was this just something written incorrectly? Only thing I can think of is that it was supposed to be [ -f "$SCRIPT_PATH" ] to check if file exists before running it, but I'm not sure anymore.
Any idea what else this could be doing?
It runs the program in SCRIPT_PATH if it is not empty or unset (because that's what the [ one_arg ] test does.)
It's a shorthand for the following:
if [ "$errcode" != 0 ]; then
if [ "$SCRIPT_PATH" ]; then
$SCRIPT_PATH do_something
fi
fi
It works by abusing the way chained conditions "short circuit" in an if statement.
Whether this is a good idea is … debatable.

How to use if else in Shell Scripting

I am learning Shell Scripting and i got stuck that in most languages like C,C++, 0 means false and 1 means true, but in below shell script I am not able to understand, how the output is generated
if [ 0 ]
then
echo "if"
else
echo "else"
fi
No matter what i write inside if block like instead of 0, I tried 1,2,true,false it is always running if condition. How this works in shell scripting.
And what shell script returns when the expression inside if statement is false.
It is always executing if part because this condition:
[ 0 ]
will always be true as it checks if the string between [ and ] is not null/empty.
To correctly evaluate true/false use:
if true; then
echo "if"
else
echo "else"
fi
There are no booleans in Bash.
But here are some examples that are interpreted falsy:
Empty value: ""
Program exiting with non-zero code
A 0 as in your example is not falsy, because it's a non-empty value.
An example with empty value:
if [ "" ]
then
echo "if"
else
echo "else"
fi
An example with non-zero exit code (assuming there's no file named "nonexistent"):
if ls nonexistent &> /dev/null
then
echo "if"
else
echo "else"
fi
Or:
if /usr/bin/false
then
echo "if"
else
echo "else"
fi
Or:
if grep -q whatever nonexistent
then
echo "if"
else
echo "else"
fi

Shell Script not reading input

I have written a script that backs up and restores files. I have a problem in that when the user enters '2' for a restore the program says that this is an invalid input, all other options work fine. I feel it is something small that I have missed but I cant fix it
Update and Restore Script
#!/bin/bash
ROOT="/Users/Rory/Documents"
ROOT_EXCLUDE="--exclude=/dev --exclude=/proc --exclude=/sys --exclude=/temp --exclude=/run --exlucde=/mnt --exlcude=/media --exlude=/backup2.tgz"
DESTIN="/Users/Rory/test/"
BACKUP="backup2.tgz"
CREATE="/dev /proc /sys /temp /run /mnt /media "
if [ "$USER" != "root" ]; then
echo "You are not the root user"
echo "To use backup please use: sudo backup"
exit
fi
clear
echo "************************************************"
echo "********* Backup Menu **************************"
echo "************************************************"
OPTIONS="BACKUP RESTORE DESTINATION EXIT"
LIST="1)BACKUP 2)RESTORE 3)DESTINATION 4)EXIT"
select opt in $OPTIONS; do
if [ "$opt" = "EXIT" ]; then
echo "GOODBYE!"
sleep 3
clear
exit
elif [ "$opt" = "BACKUP" ]; then
echo "BACKING UP FILES..."
sleep 2
tar cvpfz $DESTIN/backup.`date +%d%m%y_%k:%M`.tgz $ROOT $ROOT_EXCLUDE_DIRS
echo "BACKUP COMPLETE"
sleep 2
exit
elif [ "$opt" = "RESTORE" ]; then
echo "RESTOTING FILES..."
sleep 2
tar xvpfz $BACKUP_FILE -C /
sleep2
echo "RESTORE COMPLETE..."
if [[ -e "/proc" ]]; then
echo "$CREATE_DIRS allready exists! "
else
mkdir $CREATE_DIRS
echo "$CREATE_DIRS are created! "
fi
exit
elif [ "$opt" = "DESTINATION" ]; then
echo "CURRENT DESTINATION: $DEST_DIR/backup.`date +%d/%m/%y_%k:%M`.tgz "
echo "TO CHANGE ENTER THE NEW DESTINATION..."
echo "TO LEAVE IT AS IS JUST PRESS ENTER..."
read NEW_DESTIN
#IF GREATER THEN 0 ASSIGN NEW DESTINATION
if [ ${#NEW_DESTIN} -gt 0 ]; then
DESTIN = "$NEW_DESTIN"
fi
clear
echo $BANNER1
echo $BANNER2
echo $BANNER3
echo $LIST
else
clear
echo "BAD INPUT!"
echo "ENTER 1 , 2, 3 or 4.."
echo $LIST
fi
done
Except where you missed the ending quote where you set ROOT_EXCLUDE (line #4), it looks okay to me. I take it the missing quote is a transcription error or your program wouldn't really work at all.
I've tried out the program and it seems to work.
A debugging trick is to put set -xv to turn on debugging in your script and set +xv to turn it off. The -x means to print out the line before executing, and the -v means to print out the line once the shell interpolates the line.
I'm sure that you'll immediately see the issue once you have set -xv in your program.
As part of this, you can set PS4 to the line prompt to print when the debugging information is printed. I like setting PS4 like this:
export PS4="[\$LINENO]> "
This way, the line prompt prints out the line it's executing which is nice.
In your case, I would put set -xv right before you set OPTIONS and then at the very end of the program. This way, you can see the if comparisons and maybe spot your issue.
export PS4="[\$LINENO]> "
set -xv
OPTIONS="BACKUP RESTORE DESTINATION EXIT"
LIST="1)BACKUP 2)RESTORE 3)DESTINATION 4)EXIT"
select opt in $OPTIONS; do
if [ "$opt" = "EXIT" ]; then
echo "GOODBYE!"
set +xv
By the way, it's better to use double square brackets like [[ ... ]] for testing rather than the single square brackets like [ ... ]. This has to do with the way the shell interpolates the values in the test.
The [ ... ] is an alias to the built in test command. The shell interpolates the line as is and the entire line is executed.
The [[ ... ]] are a compound statement where the shell will interpolate variables, but not the entire line. The line is kept as whole:
foo="one thing"
bar="another thing"
This will work:
if [ "$foo" = "$bar" ]
then
echo "Foo and bar are the same"
fi
This won't:
if [ $foo = $bar ]
then
echo "Foo and bar are the same"
fi
The shell interpolates the line as is:
if [ one thing = another thing ]
And this is the same as:
if test one thing = another thing
The test command looks at the first item to see if it's a standard test, or assumes three items and the second item is a comparison. In this case, neither is true.
However, this will work:
if [[ $foo = $bar ]] # Quotes aren't needed
then
echo "Foo and bar are the same"
fi
With the [[ ... ]] being a compound command, the $foo and $bar are replaced with their values, but their positions are kept. Thus, the = is recognized as a comparison operator.
Using [[ ... ]] instead of [ ... ] has solved a lot of hard to find shell scripting bugs I have.

Resources