Unable to compare a string in if else statement in unix - shell

cat sample.sh
a=$1
if [ "$a" = "Dhinakaran Ramu" ];then
echo "Present"
else
echo "Not Present"
fi
sample.sh Dhinakaran Ramu
Answer is "Not Present"

Make sure when you run the script, send the text in quotation marks:
$ ./sample.sh "Dhinakaran Ramu"

It worked executing
sample.sh "Dhinakaran Ramu"
Note: if we execute
sample.sh Dhinakaran Ramu
then the script receives not one argument, but two. In the script you use $1, because you expect one argument.

When you run the script $1 is Dhinakaran and $2 is Ramu.
Try
sample.sh "Dhinakaran Ramu"

Related

how to assign a file name into a variable in shell

How do I assign a command to run a file into a variable.
I have this line:
file=$(./file1.sh) #how to properly do this?
if ($0 == $file)
echo "good to go!"
The goal of $file is to check the name of the shell script being run.
file should equal the command you use to run the shell script (ie "./file.sh")
How do I properly do this?
Close ..
file="file1.sh"
if [[ "${0##*/}" == "$file" ]]; then
echo "good to go!"
fi

Shell script syntax error (if, then, else)

I have been trying to make a shell script in bash that will display the following:
You are the super user (When I run the script as root).
You are the user: "user" (When I run the script as a user).
#!/bin/bash/
if { whoami | grep "root" }; then
echo $USER1
else
echo $USER2
fi
I keep recieving these syntax error messages:
script.sh: line 2: syntax error near unexpected token `then'
script.sh: line 2: `if { whoami | grep "root" }; then'
Could someone help me out?
If braces are used to chain commands then the last command must have a command separator after it.
{ foo ; bar ; }
userType="$(whoami)"
if [ "$userType" = "root" ]; then
echo "$USER1"
else
echo "$USER2"
fi
pay attention with your first line, the correct syntax for she-bang is:
#!/bin/bash
everything you put there, is the interpreter of your script, you can also put something like #!/usr/bin/python for python scripts, but your question is about the if statement, so you can do this in two ways in shell script using
if [ test ] ; then doSomething(); fi
or
if (( test )) ; then doSomething(); fi
so to answer your question basically you need to do this
#!/bin/bash
if [ `id -u` -eq 0 ] ; then
echo "you are root sir";
else
echo "you are a normal user"
fi
if (( "$USER" = "root" )); then
echo "you are root sir";
else
echo "you are a normal user"
fi
note that you could use a command using `cmd` or $(cmd) and compare using -eq (equal) or = (same), hope this help you :-)

How to pass value to read variable with pipe (stdin) in bash

I read a lot about passing piping stdin to bash read function, but nothing seems to work for my bash version!!
GNU bash, version 3.2.51(1)-release (x86_64-suse-linux-gnu)
I have a bash script that in some point asks the user "yes/no" with variable CONTINUEQUESTION:
echo "Do you want to continue? (yes/no):"
read CONTINUEQUESTION
tmp=$(tr '[:upper:]' '[:lower:]' <<<$CONTINUEQUESTION)
if [[ "$tmp" != 'y' && "$tmp" != 'yes' ]]; then
echo "Aborting because of input '$CONTINUEQUESTION'"
exit
fi
I would like to pipe a "yes or no" to this question without user input!
Yes i know i could use expect, but i don't prefer it in this case.
So i tried several things:
CONTINUEQUESTION='yes'
echo $CONTINUEQUESTION | ./myscript.sh
Aborting because of input ''
./myscript.sh <<< "$CONTINUEQUESTION"
Aborting because of input ''
...and many other, nothing worked!?
O.k. now I did a bit revers thinking and find out that the below line causes the problem with the pipe...because when i remarked it out all the below answers are working just fine, but not when this line is executed:
running=`ssh root#${HOSTNAME} 'su - root -c "/bin/tools list | grep \"system running\"" 2>&1'`
But, i need this line before the read! What do i need to reverse the 2>&1????
My script look like this and is working without this try to over come the user intervantion:
LIST_FILE_NAME=$1
STILL_RUNNING=0
running=`ssh root#${HOSTNAME} 'su - root -c "cat '$LIST_FILE_NAME' | grep \"system running\"" 2>&1'`
if [[ $running =~ .*running.* ]]; then
STILL_RUNNING=1
echo "NODE $NODE running stop before continuing."
fi
if [ $STILL_RUNNING -eq 1 ]; then
echo "Aborting system was still running!"
exit 1
fi
echo "Do you want to continue? (yes/no):"
read CONTINUEQUESTION
tmp=$(tr '[:upper:]' '[:lower:]' <<<$CONTINUEQUESTION)
if [[ "$tmp" != 'y' && "$tmp" != 'yes' ]]; then
echo "Aborting because of input '$CONTINUEQUESTION'"
exit
fi
echo "o.k."
4 points:
list.log can have a line with "system running" or "system notrunning"
if list.log has a line with "system notrunning" than the bash script continue towards the question
at the question i never got it right to inject the 'y' or 'yes' so the bash aborts because of input ''
i execute this like: ./myscript.sh list list.log (normal way)
This bash runs well if the user interacts at the question!
Thanks for you time!!!
Consider this variation as well:
#!/bin/bash
read -p "Do you want to continue? (yes/no): " CONTINUEQUESTION
if [[ $CONTINUEQUESTION != [Yy] && $CONTINUEQUESTION != [Yy][Ee][Ss] ]]; then
echo "Aborting because of input '$CONTINUEQUESTION'."
exit
fi
Tested with:
bash script.sh <<< yes
If it doesn't work, show the output of:
bash -x script.sh <<< yes
Your line
$CONTINUEQUESTION='yes'
shoul really be
CONTINUEQUESTION='yes'
I am not sure then that your are feeding stdin with the word 'yes'. You could add an echo after the read to be sure.
You can use heredoc:
bash -ex ./myscript.sh << 'EOF'
yes
EOF
Search for Here Documents in man bash.
EDIT: Based on comments you can use this ssh command:
running=$(ssh -t -t root#${HOSTNAME} "grep 'system running' \"$LIST_FILE_NAME\"")

Check if file exists [BASH]

How do I check if file exists in bash?
When I try to do it like this:
FILE1="${#:$OPTIND:1}"
if [ ! -e "$FILE1" ]
then
echo "requested file doesn't exist" >&2
exit 1
elif
<more code follows>
I always get following output:
requested file doesn't exist
The program is used like this:
script.sh [-g] [-p] [-r FUNCTION_ID|-d FUNCTION_ID] FILE
Any ideas please?
I will be glad for any help.
P.S. I wish I could show the entire file without the risk of being fired from school for having a duplicate. If there is a private method of communication I will happily oblige.
My mistake. Fas forcing a binary file into a wrong place. Thanks for everyone's help.
Little trick to debugging problems like this. Add these lines to the top of your script:
export PS4="\$LINENO: "
set -xv
The set -xv will print out each line before it is executed, and then the line once the shell interpolates variables, etc. The $PS4 is the prompt used by set -xv. This will print the line number of the shell script as it executes. You'll be able to follow what is going on and where you may have problems.
Here's an example of a test script:
#! /bin/bash
export PS4="\$LINENO: "
set -xv
FILE1="${#:$OPTIND:1}" # Line 6
if [ ! -e "$FILE1" ] # Line 7
then
echo "requested file doesn't exist" >&2
exit 1
else
echo "Found File $FILE1" # Line 12
fi
And here's what I get when I run it:
$ ./test.sh .profile
FILE1="${#:$OPTIND:1}"
6: FILE1=.profile
if [ ! -e "$FILE1" ]
then
echo "requested file doesn't exist" >&2
exit 1
else
echo "Found File $FILE1"
fi
7: [ ! -e .profile ]
12: echo 'Found File .profile'
Found File .profile
Here, I can see that I set $FILE1 to .profile, and that my script understood that ${#:$OPTIND:1}. The best thing about this is that it works on all shells down to the original Bourne shell. That means if you aren't running Bash as you think you might be, you'll see where your script is failing, and maybe fix the issue.
I suspect you might not be running your script in Bash. Did you put #! /bin/bash on the top?
script.sh [-g] [-p] [-r FUNCTION_ID|-d FUNCTION_ID] FILE
You may want to use getopts to parse your parameters:
#! /bin/bash
USAGE=" Usage:
script.sh [-g] [-p] [-r FUNCTION_ID|-d FUNCTION_ID] FILE
"
while getopts gpr:d: option
do
case $option in
g) g_opt=1;;
p) p_opt=1;;
r) rfunction_id="$OPTARG";;
d) dfunction_id="$OPTARG";;
[?])
echo "Invalid Usage" 1>&2
echo "$USAGE" 1>&2
exit 2
;;
esac
done
if [[ -n $rfunction_id && -n $dfunction_id ]]
then
echo "Invalid Usage: You can't specify both -r and -d" 1>&2
echo "$USAGE" >2&
exit 2
fi
shift $(($OPTIND - 1))
[[ -n $g_opt ]] && echo "-g was set"
[[ -n $p_opt ]] && echo "-p was set"
[[ -n $rfunction_id ]] && echo "-r was set to $rfunction_id"
[[ -n $dfunction_id ]] && echo "-d was set to $dfunction_id"
[[ -n $1 ]] && echo "File is $1"
To (recap) and add to #DavidW.'s excellent answer:
Check the shebang line (first line) of your script to ensure that it's executed by bash: is it #!/bin/bash or #!/usr/bin/env bash?
Inspect your script file for hidden control characters (such as \r) that can result in unexpected behavior; run cat -v scriptFile | fgrep ^ - it should produce NO output; if the file does contain \r chars., they would show as ^M.
To remove the \r instances (more accurately, to convert Windows-style \r\n newline sequences to Unix \n-only sequences), you can use dos2unix file to convert in place; if you don't have this utility, you can use sed 's/'$'\r''$//' file > outfile (CAVEAT: use a DIFFERENT output file, otherwise you'll destroy your input file); to remove all \r instances (even if not followed by \n), use tr -d '\r' < file > outfile (CAVEAT: use a DIFFERENT output file, otherwise you'll destroy your input file).
In addition to #DavidW.'s great debugging technique, you can add the following to visually inspect all arguments passed to your script:
i=0; for a; do echo "\$$((i+=1))=[$a]"; done
(The purpose of enclosing the value in [...] (for example), is to see the exact boundaries of the values.)
This will yield something like:
$1=[-g]
$2=[input.txt]
...
Note, though, that nothing at all is printed if no arguments were passed.
Try to print FILE1 to see if it has the value you want, if it is not the problem, here is a simple script (site below):
#!/bin/bash
file="${#:$OPTIND:1}"
if [ -f "$file" ]
then
echo "$file found."
else
echo "$file not found."
fi
http://www.cyberciti.biz/faq/unix-linux-test-existence-of-file-in-bash/
Instead of plucking an item out of "$#" in a tricky way, why don't you shift off the args you've processed with getopts:
while getopts ...
done
shift $(( OPTIND - 1 ))
FILE1=$1

Shell script to check one script output and then run second script

I want a script to run a main.ksh to run both one.ksh and second.ksh only if output of one.ksh matches "1". So if the output is anything other than "1" then second.ksh shouyld not run.
cat one.ksh
#!/usr/bin/ksh
echo "1"
cat second.ksh
#!/usr/bin/ksh
echo "2"
I did this:
#!/usr/bin/ksh
ksh .ksh > one.txt
file="one.txt"
while read line
do
if [ $line -eq 2 ] ;then
ksh second.ksh
else
echo "one.ksh is no good"
fi
done <"$file"
Any better way ro this is good?
Instead of echo 1 to proceed from the first script, you should use exit 0. If it shouldn't proceed, exit 1.
This is the standard way of signaling success and failure in Unix.
Once you do this, you can use any of:
first.ksh && second.ksh
or
if first.ksh
then
second.ksh
fi
or
set -e # Automatically exit script if a command fails
first.ksh
second.ksh
out=`one.ksh`
if [ "x$out" == "x1" ]; then
second.ksh
fi

Resources