bash: syntax error near unexpected token `else' formatting issue? - bash

I'm pretty new to bash and am having trouble with what I assume is formatting. I'm trying to edit the /etc/profile so it will display a login message for root and a different login message for anyone else. But I'm getting the error bash: syntax error near unexpected token else. I've tried all the different combinations of no semicolon, then on the next line etc but always get the same error. I've tried the lines separately and they display fine (except $HOSTNAME, can't get that to work). When run like this and login with root it will just jump to "Welcome $USER...".
Anyone suggestions would be appreciated!
if [ "$UID" -ne 0 ]; then
echo -e "\033[40;37;7m Danger! Root is doing stuff in `pwd`\033[0m"
else
echo "Welcome $USER! You are working on `$HOSTNAME` in `pwd`."
fi

As written, above works for me - but, as pointed out, you should change your test to -eq 0.
For the syntax error near unexpected token problem - I will guess that your file contains embedded 'control codes', i.e. most likely a carriage return \r.
Try:
cat -e ~/your_profile
see any non-printable characters? if so, remove them (cat options may vary - check you manpage) or
od -c ~/your_profile

Related

printf "-1" in bash gives error for unknown reason

In bash 3.2 (default on the recent macOS), running printf "-1" gives me some error like this:
bash: printf: -1: invalid option
Which I have no problem in zsh, indeed, a leading hyphen in any string passed to printf will trigger that error. shellcheck has not warning for this. Also tried echo "-1" and seems fine.
I know the error is avoidable by using printf "%s" "-1", but can someone explain the reason behind it? thanks.
For utilities that conform to the standard syntax (echo being a notable exception), leading operands starting with - indicate options. Operands are treated as options even if the command does not provide options by those names, causing the error message you've seen. An explicit end of the options can be indicated with --: printf -- -1 will cause the string -1 to be interpreted as the format string and printed.

parameter expansion syntax bash

I am trying to write a short script that will take two command line parameters as file extensions and change all files with the first extension to have the second extension. I am pretty sure the following script should work but for some reason it gives me a syntax error on the line where the variable name is defined and I am not sure why. I am rather new to bash scripting so any help would be greatly appreciated!
for f in "*$1" do
name=${f%.*}
mv $f "$name$2"
done
The error message printed by Bash looks like:
./script: line 4: syntax error near unexpected token `name=${f%.*}'
./script: line 4: `name=${f%.*}'
The reason is that you are missing a ; or newline before do. Also you don't want to quote * in "*$1", since the * will be taken as a literal. Corrected script:
#!/usr/bin/env bash
for f in *"$1"; do
name=${f%.*}
mv "$f" "$name$2"
done

Find string inside of an anchor tag from cURL response using bash

I am working on a small project that will scan about 6,000 url's and tell me which ones have links to my website and if they are marked rel=no-follow I am working on backlink cleanup. I need to basically search the html returned by cURL for a string and if it finds it I need it to echo it to a file. Right now the issue is that I am getting some errors:
./checkURL.sh: line 4: syntax error in conditional expression
./checkURL.sh: line 5: syntax error near `then'
./checkURL.sh: line 5: `then'
Here is my code:
#!/bin/bash
test="curl https://example.com"
result=$(eval "$test")
if [[ $result == *turtles*]]
then
echo "its there";
fi
I pulled the example of the if statement from another stackoverflow question and it appeared to work for the OP doing the same thing as me so I am not sure what went wrong in my code....
You need a space:
if [[ $result == *turtles*]]
^
|
--------------------------

-bash: syntax error near unexpected token `)'

I'm probably missing something very basic. I have a web script that tells a shell script to update some database records. These records are for statistics, and this way the web script does not have to wait while the database records are updated. However, I can't actually make the shell script work running it from commandline. Here is the code that I'm trying:
perl async_sql.pl 'UPDATE some_table set i = i + 1 WHERE (n in (\'328430\',\'334969\',\'330179\',\'335290\',\'335285\',\'335284\',\'335264\',\'335145\',\'335146\',\'335147\',\'335148\',\'335149\',\'335230\',\'335201\',\'335198\',\'335196\',\'335167\',\'335151\',\'335152\',\'335143\',\'334969\',\'334972\',\'334977\',\'334978\',\'334979\',\'334980\',\'334982\',\'334983\',\'334984\',\'334934\',\'334947\',\'334948\',\'334950\',\'334992\',\'335014\',\'335026\',\'335030\',\'335032\',\'334864\',\'334862\',\'334861\',\'334858\',\'334855\',\'334852\',\'334850\',\'334849\',\'334848\',\'334847\',\'334844\',\'334842\'))'
Bash tells me:
-bash: syntax error near unexpected token `)'
What am I missing?
It is not possible to escape single quote in single quotes. Use " " instead
perl async_sql.pl "UPDATE some_table set i = i + 1 WHERE (n in ('328430','334969','330179','335290','335285','335284','335264','335145','335146','335147','335148','335149','335230','335201','335198','335196','335167','335151','335152','335143','334969','334972','334977','334978','334979','334980','334982','334983','334984','334934','334947','334948','334950','334992','335014','335026','335030','335032','334864','334862','334861','334858','334855','334852','334850','334849','334848','334847','334844','334842'))"
Also, there are other ways to deal with this problem:
echo "quote'test"
echo 'quote'"'"'test'
echo 'quote'\''test'
echo $'quote\'test'
All these should print quote'test as a single parameter. Which means that another great solution for your problem is:
perl async_sql.pl $'UPDATE some_table set i = i + 1 WHERE (n in (\'328430\',\'334969\',\'330179\',\'335290\',\'335285\',\'335284\',\'335264\',\'335145\',\'335146\',\'335147\',\'335148\',\'335149\',\'335230\',\'335201\',\'335198\',\'335196\',\'335167\',\'335151\',\'335152\',\'335143\',\'334969\',\'334972\',\'334977\',\'334978\',\'334979\',\'334980\',\'334982\',\'334983\',\'334984\',\'334934\',\'334947\',\'334948\',\'334950\',\'334992\',\'335014\',\'335026\',\'335030\',\'335032\',\'334864\',\'334862\',\'334861\',\'334858\',\'334855\',\'334852\',\'334850\',\'334849\',\'334848\',\'334847\',\'334844\',\'334842\'))'
I have only placed a dollar sign $ right before the parameter. That's it. A dollar sign before single quotes turns on ANSI-C Quoting
bash: syntax error near unexpected token `('
this type of error can be solve by the turn on extended globbing by git bash command is "shopt -s extglob"

Bash-script File creation and fill

I am trying to write a bash-script which will create a certain number of files which are passed into an argument, and also fill that file with relevant information. However, for some reason I can't get it to work properly, and googling turned up nothing.
I want it to create files like the following:
FileName:
Prob_3_ch_17.cpp
Filled as the following:
/*
User: Johnny Smith
Prob: 3
Output:
*/
Where the first command line argument is the chapter number. The second is the starting number, and the third is the ending number. So if the following is ran
sh ../FileMaker.sh 17 1 10
It will make 10 files, each filled with the appropriate data and proper file names, for chapter 17. This is the script that I came up with.
#!/bin/bash
# Syntax:
# $1 = Chapter Number
# $2 = Starting Number
# $3 = Ending Number
CHAPTER=$1
FIRST=$2
LAST=$3
U_NAME="Johnny Smith"
# Name: Prob_$NUMBER_Ch_$1.cpp
for ((NUMBER=$FIRST; $NUMBER<=$LAST; $NUMBER++));
do
if [ -e "Prob_$NUMBER_Ch_$CHAPTER.cpp" ]; then
echo "File Prob_$NUMBER_Ch_$CHAPTER.cpp already exists!"
else
echo "/* \n User: $U_NAME \n Problem: $NUMBER \n Output: \n */" >> "Prob_$NUMBER_Ch_$CHAPTER.cpp"
done
However, it doesn't run. I get the following error:
../FileMaker.sh: line 21: syntax error near unexpected token `done'
../FileMaker.sh: line 21: `done'
I've googled and found other people have had the same problem, but I didn't fully understand what was meant in the solution. Can someone please help me? I'm not the best at shell scripting, and I'm trying to learn by making scripts like this.
Thanks in advanced.
Syntax for if block and for-loop is wrong. correct syntax would be -
for ((NUMBER=FIRST; NUMBER<=LAST; NUMBER++));
do
if [ -e "Prob_$NUMBER_Ch_$CHAPTER.cpp" ]; then
echo "File Prob_$NUMBER_Ch_$CHAPTER.cpp already exists!"
else
echo "/* \n User: $U_NAME \n Problem: $NUMBER \n Output: \n */" >> "Prob_$NUMBER_Ch_$CHAPTER.cpp"
fi
done
See example 11.12 for c style for loop.
To create files use "Prob_"$NUMBER"Ch"$CHAPTER".cpp" at all the places.
Most shells allow a set -x at the top. This show you tracing of the script as it executes.
You need a trailing fi to close the if statement.
Shell math need NUMBER=$(expr $NUMBER + 1), it doesn't understand $NUMBER++.
You might find the printf command more handy than echo.
You will still have your variable use wrong in the loop and are only creating one file. I hope you can figure that out as this seems like homework.

Resources