Getting error:
syntax error near unexpected token `elif'
`elif [ "$PROJECT_DIR" = "Automation" ] then'
I'm saving in Unix line format in Textpad++ so I'm not sure what the problem is...
#!/bin/bash
....
if [ "$PROJECT_DIR" = "Utility" ] then
echo "$PROJECT_DIR: Compiling..."
javac -sourcepath $SOURCE -classpath $CLASSPATH -d $OUTPUT $SOURCE/*.java -deprecation
echo "$PROJECT_DIR: Compiling..."
javac -sourcepath $SOURCE -classpath $CLASSPATH -d $OUTPUT $SOURCE/*.java -deprecation
elif [ "$PROJECT_DIR" = "Automation" ] then
echo "$PROJECT_NAME: Compiling..."
javac -sourcepath $SOURCE -classpath $CLASSPATH -d $OUTPUT $SOURCE/*.java
elif [ "$PROJECT_DIR" = "Sync" ] then
echo "$PROJECT_DIR: Compiling..."
javac -sourcepath $SOURCE -classpath $CLASSPATH -d $OUTPUT $SOURCE/*.java -deprecation
echo "$PROJECT_DIR: Compiling..."
javac -sourcepath $SOURCE -classpath $CLASSPATH -d $OUTPUT $SOURCE/*.java -deprecation
echo "$PROJECT_DIR: Compiling..."
javac -sourcepath $SOURCE -classpath $CLASSPATH -d $OUTPUT $SOURCE/*.java -deprecation
fi
The problem is that you need a semicolon (or a newline) between the ] and the then.
[ is not part of the shell's syntax. It's a built-in command, equivalent to the test command (except that [ requires a ] as its last argument and test doesn't).
(On the other hand, the keywords if, then, elif, and fi as well as the semicolon, are part of the shell's syntax.)
So if you write:
if [ "$PROJECT_DIR" = "Utility" ] then
the word then is simply another argument to the [ command.
Changing each occurrence of ] then to ] ; then should fix the problem.
Try like this instead (Removed most of the code lines to keep the answer short). no need of last elif condition elif [ "$PROJECT_DIR" = "Sync" ]. It should just be an else part as pointed below.
if [ "$PROJECT_DIR" = "Utility" ]
then
echo "$PROJECT_DIR: Compiling..."
elif [ "$PROJECT_DIR" = "Automation" ]
then
echo "$PROJECT_NAME: Compiling..."
else
echo "$PROJECT_DIR: Compiling..."
fi
Related
I wrote the following code :
echo "Choose between the following options:"
echo "1 - Create a new file"
echo "2 - Write in an existing file"
echo "3 - Change the path of a file"
echo "4 - Display a file"
echo "5 - Exit"
read number
while [ $number -ne 1 -o $number -ne 2 -o $number -ne 3 -o $number -ne 4 -o $number -ne 5 ]
do
echo "Enter a number between 1 and 5"
read number
done
if [ $number -eq 1 ]; then
echo "Enter a folder name"
read name
while [ -e $name ]
do
echo "The file name already exists enter a new name:"
read name
done
touch $name
fi
if [ $number -eq 2 ]; then
echo "Enter the folder name you want to edit :"
read name
while [ ! -f $name ]
do
echo "The file you are looking does not exist. Enter another file name :"
read name
done
echo "Enter what you want to put in the file :"
read input
echo $input >> $name
fi
if [ $number -eq 3 ]; then
echo "Enter the folder name :"
read name
while [ ! -f $name ]
do
echo "The file you are looking does not exist. Enter another file name :"
read name
done
if [ $number -eq 4 ]; then
echo "Enter the folder name you want to see :"
read name
while [ ! -f $name ]
do
echo "The file you are looking does not exist. Enter another file name :"
read name
done
cat $name
fi
if [ $number -eq 5 ]; then
exit 0
fi
The code works just fine, but on the first condition :
while [ $number -ne 1 -o $number -ne 2 -o $number -ne 3 -o $number -ne 4 -o $number -ne 5 ]
I would like it to work to whatever number or string I put.
For example, if I put hello the program will crash.
Can someone tell me what should my first condition be?
Thank you for your help. And forgive me if my question is not in the rules of the forum (I just subscribed).
Your script says:
while [ $number -ne 1 -o $number -ne 2 -o $number -ne 3 -o $number -ne 4 -o $number -ne 5 ]
So, if $number is 1, it's not equal to 2. And if it's 2, it's not equal to 1. This will always evaluate as true, so you'll never exit the loop.
A variety of options exist that will be compatible with a numeric value and still gracefully handle non-numeric input. The following uses a basic regular expression to determine whether input is a digit from 1 to 5:
while read number && ! expr "$number" : '[1-5]$' >/dev/null; do
echo "Try again" >&2
done
You would probably be better off, though, using a case statement:
while read number; do
case "$number" in
1) function_1 ;;
2) function_2 ;;
... etc
*) echo "Invalid input, please try again." >&2; continue ;;
esac
break
done
The case statement is a more graceful way of expressing what might otherwise be achieved using if..elif..elif..fi:
while read number && ! expr "$number" : '[1-5]$' >/dev/null; do
echo "Try again" >&2
done
if [ "$number" = 1 ]; then
: do_something
elif [ "$number" = 2 ]; then
: do_something
elif [ "$number" = 3 ]; then
: do_something
elif [ "$number" = 4 ]; then
: do_something
elif [ "$number" = 5 ]; then
: do_something
else
echo "What am I doing?" >&2
fi
While this construct technically works, it's inelegant and harder to read. Much better to put your functionality into functions which get called from a case statement.
Note that it's always a good idea to quote your variables within a script like this. Do you know what happens with unquoted variables? If not, then quote your variables. :)
I would strongly suggest structuring your code with a case statement:
case $number in
1) code_for_1;;
2) code_for_2;;
...
*) echo "Invalid number" >&2;;
esac
If you wish to repeat (I would actually recommend taking the number as a command line argument instead of reading from stdin and aborting on an error), you could simply do:
while read number; do
case $number in
...
*) echo 'Invalid number' >&2; continue;;
esac
break
done
And write code_for_{1,2,3,4,5} as functions to factor out the logic. For example:
create_file() {
echo "Enter a file name"
while read name; do
if test -e "$name"; then
echo "The file $name already exists enter a new name" >&2
continue
fi
touch "$name"
break
done
}
while read number; do
case $number in
1) create_file;;
...
*) echo 'Invalid number' >&2; continue;;
esac
break
done
I am trying to set up a new work environment, using zsh and an old set of dotfiles. I have this error with git information and I do not know how to solve it. Here is the error from iTerm2 as soon as I cd into my dotfiles repo:
~ ✔ cd dotfiles
_git_prompt_color:3: = not found
dotfiles ✔ _git_prompt_color:3: = not found
I am assuming the issue surrounds line 3 of the _git_prompt_color method?
Here is the file where I think the issue is:
_git_prompt_info() {
ref=$(git symbolic-ref HEAD 2> /dev/null)
if [ -n $ref ]; then
branch_name="${ref#refs/heads/}"
branch_name_max_length=$(($COLUMNS/5))
if [ ${#branch_name} -gt $branch_name_max_length ]; then
echo "$branch_name[0,$(($branch_name_max_length-3))]..."
else
echo $branch_name
fi
fi
}
_git_status() {
git_status=$(cat "/tmp/git-status-$$")
if [ -n "$(echo $git_status | grep "Changes not staged")" ]; then
echo "changed"
elif [ -n "$(echo $git_status | grep "Changes to be committed")" ]; then
echo "pending"
elif [ -n "$(echo $git_status | grep "Untracked files")" ]; then
echo "untracked"
else
echo "unchanged"
fi
}
_git_prompt_color() {
if [ -n "$1" ]; then
current_git_status=$(_git_status)
if [ "changed" == $current_git_status ]; then
echo "$(_red $1)"
elif [ "pending" == $current_git_status ]; then
echo "$(_yellow $1)"
elif [ "unchanged" == $current_git_status ]; then
echo "$(_green $1)"
elif [ "untracked" == $current_git_status ]; then
echo "$(_cyan $1)"
fi
else
echo "$1"
fi
}
_color() {
if [ -n "$1" ]; then
echo "%{$fg_bold[$2]%}$1%{$reset_color%}"
fi
}
_separate() { if [ -n "$1" ]; then echo " $1"; fi }
_grey() { echo "$(_color "$1" grey)" }
_yellow() { echo "$(_color "$1" yellow)" }
_green() { echo "$(_color "$1" green)" }
_red() { echo "$(_color "$1" red)" }
_cyan() { echo "$(_color "$1" cyan)" }
_blue() { echo "$(_color "$1" blue)" }
_full_path() { echo "$(_blue "%~")" }
_working_directory() { echo "$(_blue "%c")" }
_colored_git_branch() { echo "$(_git_prompt_color "$(_git_prompt_info)")" }
_display_current_vim_mode() {
if [[ $VIMODE == 'vicmd' ]]; then
echo "$(_red "✘")"
else
echo "$(_green "✔")"
fi
}
function zle-line-init zle-keymap-select {
VIMODE=$KEYMAP
zle reset-prompt
}
zle -N zle-line-init
zle -N zle-keymap-select
function precmd {
$(git status 2> /dev/null >! "/tmp/git-status-$$")
}
PROMPT='$(_working_directory)$(_separate $(_colored_git_branch)) $(_display_current_vim_mode) '
Any help on this issue would be much appreciated!
[ do not support the == operator. You've to either use = or perform the comparison using [[ operator. [ offers only limited functionality but it's POSIX compliant, While [[ isn't.
Here it would be
if [[ "changed" == $current_git_status ]]
or
if [ "changed" = $current_git_status ]
Difference between test, [ and [[
Tip :
Try using vcs_info to obtain basic version control information.
vcs_info documentation
vcs_info examples
n='!' && [ -n ${n} ] && echo "n=$n"
produces the following message
[: too many arguments
Why?
EDIT:
I'm using zsh
➔ echo $ZSH_VERSION
5.0.7
(with oh-my-zsh)
Seems to work for me fine:
☻ n='!' && [ -n ${n} ] && echo "n=$n"
n=!
~
☻ echo $ZSH_VERSION
5.0.8
(With prezto)
This might be related to the zsh version itself and hence is useful as an 'answer'.
I have the below script that is expected to work when the user invokes sh <scriptName> <propertyfile> It does work when I provide this at the dollar prompt. However, I am having two issues with the script.
If I provide just one argument, ie if I do - sh <scriptName>, I see the below error -
my-llt-utvsg$ sh temp.sh
Usage temp.sh
When I do -help, I see the below error -
my-llt-utvsg$ sh tmp.sh -help
-help does not exist
What am I doing wrong? Can someone please advise? I am a software developer that very rarely needs to do shell scripting, so please go easy on me ;)
#!/bin/bash
FILE="system.properties"
FILE=$1
if [ ! -f $FILE ];
then
echo "$FILE does not exist"
exit
fi
usage ()
{
echo "Usage $0 $FILE"
exit
}
if [ "$#" -ne 1 ]
then
usage
fi
if [ "$1" = "-help" ] ; then
echo ""
echo '############ HELP PROPERTIES ############ '
echo ""
echo 'Blah.'
exit
The reason your
if [ "$1" = "-help" ] ; then
check is not working is that it only checks $1 or the first argument.
Try instead:
for var in "$#"
do
if [ "$var" = "-help" ] ; then
echo ""
echo '############ HELP PROPERTIES ############ '
echo ""
echo 'Blah.'
fi
done
Which will loop over each argument and so will run if any of them are -help.
Try this as well:
#!/bin/bash
FILES=()
function show_help_info_and_exit {
echo ""
echo '############ HELP PROPERTIES ############ '
echo ""
echo 'Blah.'
exit
}
function show_usage_and_exit {
echo "Usage: $0 file"
exit
}
for __; do
if [[ $__ == -help ]]; then
show_help_info_and_exit
elif [[ -f $__ ]]; then
FILES+=("$__")
else
echo "Invalid argument or file does not exist: $__"
show_usage_and_exit
fi
done
if [[ ${#FILES[#]} -ne 1 ]]; then
echo "Invalid number of file arguments."
show_usage_and_exit
fi
echo "$FILES"
Following error returned after trying to run makefile:
#if [ ! -z "$(WL_BASE)" ]; then \
$(DIR_JAVA_WEB_BUILD)/JavaWSWebLogicInstall! \
fi
#if [ ! -z "$(GF_HOME)" ]; then \
$(DIR_JAVA_WEB_BUILD)/JavaWSGlassfishInstall! \
fi
Any suggestions?
Thanks!
I'll go out on a limb and suggest that you're missing a couple of semicolons. Try:
#if [ ! -z "$(WL_BASE)" ]; then \
$(DIR_JAVA_WEB_BUILD)/JavaWSWebLogicInstall! ; \
fi
#if [ ! -z "$(GF_HOME)" ]; then \
$(DIR_JAVA_WEB_BUILD)/JavaWSGlassfishInstall! ; \
fi
If that doesn't work, try something simpler. Verify that this works from the command line:
#if [ ! -z "$(WL_BASE)" ]; then $(DIR_JAVA_WEB_BUILD)/JavaWSWebLogicInstall! fi
and tell us the result (make sure to define $(DIR_JAVA_WEB_BUILD) first), and we'll go from there.