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 :-)
Related
This question already has answers here:
When are square brackets required in a Bash if statement?
(3 answers)
Closed 1 year ago.
I'm fairly new to Linux and I'm working my way though a course of learning. I've been working on a script to create a new group, which checks for duplicates and then also does the same for a new user and configures some parameters for the user. I've gotten so far, but I suspect, I'm either over-complicating it, or just too much of a noob.
Here's my script:
#!/bin/bash
# Challenge Lab B: Bash Scripting
# Script settings in OS:
# 1. set user owner to root
# 2. set group owner to root
# 3. set permission to include setuid (4755)
# 4. run script with sudo
echo -n 'Enter new group: '
read group_name
echo 'checking for duplicates...'
while [ grep -q "$group_name" /etc/group == 0 ]
do
echo 'group already exists; try another.'
if [ grep -q "$group_name" /etc/group == 1 ];
then
break
fi
done
echo 'group does not exist.';
echo 'creating group.';
groupadd $group_name;
echo "$group_name group created";
echo -n 'Enter new user: '
read user_name
while [ grep -q "$user_name" /etc/passwd == 0 ]
do
echo 'user already exists; try another.'
if [ grep -q "$user_name" /etc/passwd == 1 ];
then
break
fi
done
echo 'user does not exist.';
echo 'creating user directory.';
mkdir /$user_name;
echo 'creating user.';
useradd -s /bin/bash -g $group_name $user_name;
echo "changing home directory user and group ownership to $user_name";
chown $user_name:$group_name /$user_name;
echo 'changing user and group mode to RWX and setting sticky bit';
chmod 1770 /$user_name
echo "Process complete"
And here's the result:
Enter new group: test1
checking for duplicates...
./test_sc: line 25: [: too many arguments
group does not exist.
creating group.
test1 group created
Enter new user: user1
./test_sc: line 57: [: too many arguments
user does not exist.
creating user directory.
creating user.
changing home directory user and group ownership to user1
changing user and group mode to RWX and setting sticky bit
Process complete
Clearly, it kind of works, but I'm sure the low-level handling of the duplicate isn't working based upon the result.
I'm sure many will look upon my work as terrible, but this is my first one, so please bear that in mind.
Cheers,
S
if [ grep -q "$user_name" /etc/passwd == 1 ];
The brackets are not just syntax: [ is a command.
Take note of the if syntax:
$ help if
if: if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi
Execute commands based on conditional.
...
The part you put after if is a command. if branches based on the exit status of the command.
You want
if ! grep -q "$user_name" /etc/passwd; then
You should remove square brackets this way if you want to check return value (true or false):
while [ grep -q "$group_name" /etc/group == 0 ]
change to:
while grep -q "$group_name" /etc/group; do
If you want to check that this value is incorrect, add ! before the command
You should do that not only for while loops, but also for if statements
Or if you want to check return value for a specific value, let's say 15:
grep something file
ret=$(echo $?)
if [ $ret == 15 ]; then
do something;
fi
$? will return the last return value from the command that you have executed in bash
I'm new to bash so assume that I don't understand everything in this simple script as I've been putting this together as of today with no prior experience with bash.
I get this error when I run test.sh:
command substitution: line 29: syntax error near unexpected token `$1,'
./f.sh: command substitution: line 29: `index_of($1, $urls))'
FILE: f.sh
#!/bin/bash
urls=( "example.com" "example2.com")
error_exit()
{
echo "$1" 1>&2
exit 1
}
index_of(){
needle=$1
haystack=$2
for i in "${!haystack[#]}"; do
if [[ "${haystack[$i]}" = "${needle}" ]]; then
echo "${i}"
fi
done
echo -1
}
validate_url_param(){
index=-2 #-2 as flag
if [ $# -eq 0 ]; then
error_exit "No url provided. Exiting"
else
index=$(index_of($1, $urls)) #ERROR POINTS TO THIS LINE
if [ $index -eq -1 ]; then
error_exit "Provided url not found in list. Exiting"
fi
fi
echo $index
}
FILE: test.sh
#!/bin/bash
. ./f.sh
index=$(validate_url_param "example.com")
echo $index
echo "${urls[0]}"
I've lost track of all of the tweaks I tried but google is failing me and I'm sure this is some basic stuff so... thanks in advance.
The immediate error, just like the error message tells you, is that shell functions (just like shell scripts) do not require or accept commas between their arguments or parentheses around the argument list. But there are several changes you could make to improve this code.
Here's a refactored version, with inlined comments.
#!/bin/bash
urls=("example.com" "example2.com")
error_exit()
{
# Include script name in error message; echo all parameters
echo "$0: $#" 1>&2
exit 1
}
# A function can't really accept an array. But it's easy to fix:
# make the first argument the needle, and the rest, the haystack.
# Also, mark variables as local
index_of(){
local needle=$1
shift
local i
for ((i=1; i<=$#; ++i)); do
if [[ "${!i}" = "${needle}" ]]; then
echo "${i}"
# Return when you found it
return 0
fi
done
# Don't echo anything on failure; just return false
return 1
}
validate_url_param(){
# global ${urls[#]} is still a bit of a wart
if [ $# -eq 0 ]; then
error_exit "No url provided. Exiting"
else
if ! index_of "$1" "${urls[#]}"; then
error_exit "Provided url not found in list. Exiting"
fi
fi
}
# Just run the function from within the script itself
validate_url_param "example.com"
echo "${urls[0]}"
Notice how the validate_url_param function doesn't capture the output from the function it is calling. index_of simply prints the result to standard output and that's fine, just let that happen and don't intervene. The exit code tells us whether it succeeded or not.
However, reading the URLs into memory is often not useful or necessary. Perhaps you are simply looking for
grep -Fx example.com urls.txt
Trying to debug my bash script. What's wrong with my syntax here? I'm trying to evaluate a parameter entered by the user and based on that run one of my IF-THEN statements. However, I'm getting a command not found.
Here's my script thus far:
if [[ $# != 4 ]]; then
echo "Usage: ./test.sh <ABC|XYZ> <owner> <db> <TARGETHOST>" 2>&1
exit 1
fi
case $1 in
ABC|XYZ)
filename="get-$1.sql"
;;
*)echo "Must enter ABC or XYZ"
exit 1
;;
esac
export OWNER=$2
export DB=$3
export HOST_NM=$4
export PORT=5432
export LOG="test-$1.log"
PSQL=`which psql`
if [[$1=="ABC"]]; then
RUNCLI=$("$PSQL" -h $HOST_NM -p $PORT -U $OWNER $DB -F $'\t' --no-align -f get-$1.sql | tee >> $LOG)
exit 1
else
echo "Error running report ..."
fi
if [[$1=="XYZ"]]; then
RUNCLI2=$("$PSQL" -h $HOST_NM -p $PORT -U $OWNER $DB -a -f get-$1.sql | tee >> $LOG)
exit 1
else
echo "Error running report ..."
fi
Error:
./test.sh: line 41: [[XYZ==ABC]]: command not found
Error running report ...
./test.sh: line 51: [[XYZ==XYZ]]: command not found
Error running report ...
Although the question is already answered in the comment section I want to give an answer and share some knowledge which is not obvious (at least it was not for me).
The if in bash just checks the return code of the following command, which means that instead of if [ condition ]... or if [[ condition ]]... you could also write if ./configure && make....
[ and [[ are commands or shell-built-ins, respectively, as well and not part of the if syntax. An which [ for instance returns /bin/[.
At this point it is obvious that you need spaces between the brackets and the condition since it is just just a set of parameters passed to a command.
If you have this in mind, you will never forget the spaces again.
In my program, I have to check whether a command given as a input by a user exists or not and if it exists, program needs to check if the parameters of that command are correct.
For example:
ls ( is correct)
-al (is correct)
do the watch
and if I do this:
ls (is correct)
-kala (not correct)
don't do the watch.
How I can do this? Here is my script:
while true
do
echo "Insert the command"
read comm
if [ "$(type -t $comm)" != "" ]; then
echo "Insert the parameters of the command ";
read par;
echo "Insert the time of watch";
read time;
if [ $t -le 0 ]; then
echo "Value not correct";
else
clear;
while true
do
echo "$comm"
date
echo ""
$comm $par
sleep $((time))
clear
done
fi;
else
echo "Command not found, retry.";
echo "";
fi
done
You can replace the command invocation with this:
if ! $comm $par; then
exit 1
fi
to make it stop after an error. Also there is already a tool called watch but I think you already know this.
I am trying to write a shell script that will either start or stop openvpn, depending on what the user enters. When I run the script it correctly prompts me for what I want to do. But when I type "1" and hit [Enter] it outputs this and terminates:
./control-openvpn.sh: 27: ./control-openvpn.sh: Syntax error: "fi" unexpected
Here is the main part of my code. The functions are above it in the script.
# Main
echo -n "What to do? 1.Start or 2.Stop. [1/2]"
read action
if [ "$action" == "1" ]
then
start_openvpn()
elif [ "$action" == "2" ]
then
stop_openvpn()
fi
Thank you in advance
In bash, when you do start_openvpn(), you are declaring a new function. Thus, bash gets confused when the next thing it sees is fi. Something like this should work for you:
read -p 'What to do? 1.Start or 2.Stop. [1/2] ' action
if [ $action -eq 1 ]; then
start_openvpn
elif [ $action -eq 2 ]; then
stop_openvpn
fi