Syntax error: end of file unexpected (expecting "fi")) - bash

I have the below shell script.
#!/bin/sh
i=1
for label in 'Mod Name' 'Issue No' 'UT Status' 'Dev ID' 'Loc'; do
if ! grep -q "^ $((i++)). $label:" $1; then
cat <<- EOF
Proposed message does not satisfy this repository's exacting standards
It must match the template:
1. Mod Name: xxx
2. Issue No: xxx
3. UT Status: xxx
4. Dev ID: xxx
5. Loc: xxx
The proposed message does not contain the label: $label" >&2
EOF
exit 1
fi
done
It fails with below error.
28: /mtp-test/script.sh: Syntax error: end of file unexpected (expecting "fi"))
Why does this error occur?

I tried by removing the space/tab before "EOF" as shown below and it worked. I am not sure why space creates an issue.
#!/bin/sh
i=1
label='Mod_Name'
for label in 'Mod_Name' 'Issue No' 'UT Status' 'Dev ID' 'Loc'; do
if ! grep -q "^ $((i++)). $label:" $1; then
cat <<- EOF
Proposed message does not satisfy this repository's exacting standards
It must match the template:
1. Mod_Name: xxx
2. Issue No: xxx
3. UT Status: xxx
4. Dev ID: xxx
5. Loc: xxx
The proposed message does not contain the label: $label" >&2
EOF
exit 1
fi
done

Related

How can I disable * expansion in a script?

I have a strange problem - possibly I'm just going blind. I have this short script, which replaces the string #qry# in the here-document with a select statement in a file and then pipes it to mysql:
#!/bin/bash
if [[ "$1" == "-h" ]]
then
echo "sqljob [sqlfile] [procnm] [host] [database] [config file]"
echo " sqlfile: text file containing an SQL statement"
echo " procnm: name that will given to the new, stored procedure"
echo " host: hostname of IP address of the database server"
echo " database: the procedure will be created here"
echo " config file: default configuration file with username and password"
exit
fi
infile=$1
procnm=$2
hn=$3
pn=$4
db=$5
mycfg=$6
{
set -o noglob
sed -e "s/#qry#/$(echo $(cat $infile))/g" <<!
drop procedure if exists $procnm;
delete from jobs where jobname="$procnm";
insert into jobs
set
notes="SQL job $procnm",
jobname="$procnm",
parm_tmpl='int';
delimiter //
create procedure $procnm(vqid int)
begin
call joblogmsg(vqid,0,"$procnm","","Executing #qry#");
drop table if exists ${procnm}_res;
create table ${procnm}_res as
#qry#
end//
delimiter ;
!
} | mysql --defaults-file=$mycfg -h $hn -P $pn $db
However, when the select contains *, it expands to whatever is in the directory even though I use noglob. However, it works from the command line:
$ set -o noglob
$ ls *
What am I doing wrong?
Edit
Block Comments in a Shell Script has been suggested as a duplicate, but as you will notice, I need to expand ${procnm} in the here-doc; I just need to avoid the same happening to select *.
I suspect it is because the construct echo (cat). The echo command gets the * from the cat command and the shell in which it runs expands it. In that shell set noglob is not active.
Try leaving the echo away: /$(cat $infile)/, in the end that is the data you need; then there is no extra glob expansion by a shell.

bash to verify file type integrity and create log

I am trying to use bash to verify the integrity of specific downloads .bam files. There are two parts (bash 1) runs the command to verify the .bam files which creates .txt files, and creates a process.log. That part works perfect, what I am getting an error in is checking each of the .txt files for a string (SUCCESS) and if it is found then in the process.log that file is verified if it is not found then that file is corrupt. Currently the terminal displays the status and then gives an error. Thank you :).
bash part 1
logfile=/home/cmccabe/Desktop/NGS/API/5-4-2016/process.log
for f in /home/cmccabe/Desktop/NGS/API/5-4-2016/*.bam ; do
echo "Start bam validation creation: $(date) - File: $f"
bname=`basename $f`
pref=${bname%%.bam}
bam validate --in $f --verbose 2> /home/cmccabe/Desktop/NGS/API/5-4-2016/bam_validation/${pref}_validation.txt
echo "End bam validation creation: $(date) - File: $f"
done >> "$logfile"
echo "Start verifying $(date) - File: $file"
value=$( grep -ic "(SUCCESS)" /home/cmccabe/Desktop/NGS/API/5-4-2016/bam_validation/*.txt )
bash part 2
if [ $value -eq 1 ]
then
echo "bam file is verified and complete"
else
echo "bam is corrupt, check log for reason"
echo "End bam verify: $(date) - File: $f"
fi
done >> "$logfile"
erorr
Start verifying Thu May 5 12:49:10 CDT 2016 - File:
/home/cmccabe/Desktop/loop.sh: line 11: [: too many arguments
bam is corrupt, check log for reason
End bam verify: Thu May 5 12:49:10 CDT 2016 - File: /home/cmccabe/Desktop/NGS/API/5-4-2016/NA19240.bam
/home/cmccabe/Desktop/loop.sh: line 18: syntax error near unexpected token `done'
/home/cmccabe/Desktop/loop.sh: line 18: `done >> "$logfile"'
file that is created to check for SUCCESS
Number of records read = 24723078
Number of valid records = 24723078
TotalReads(e6) 24.72
MappedReads(e6) 24.57
PairedReads(e6) 0.00
ProperPair(e6) 0.00
DuplicateReads(e6) 7.33
QCFailureReads(e6) 0.00
MappingRate(%) 99.38
PairedReads(%) 0.00
ProperPair(%) 0.00
DupRate(%) 29.66
QCFailRate(%) 0.00
TotalBases(e6) 4332.46
BasesInMappedReads(e6) 4325.68
Returning: 0 (SUCCESS)
The error is due to simplest of the reasons, in bash if you use a single parentheses [] to evaluate a condition, it is nothing but an implicit way of using the bash test expression which expands the $value as a string containing spaces, special characters as separate parameters. Here you have left the variable ambiguous which could be expanded to multiple parameters for some error cases.
All you need to do is enclose that variable within double quotes, so that it is treated as one single string.
if [ "$value" == 1 ]; then

unix shell script not working gives me error

what is wrong with my code this is it -
export -P ttiUsername="Username: " || ^
i get an error about command ^ and the -p
here is my error
/Users/michaelgray/Desktop/ToontownWorld/ToontownInfiniteRetro/start_game.sh: line 3: export: -P: invalid option
export: usage: export [-nf] [name[=value] ...] or export -p
/Users/michaelgray/Desktop/ToontownWorld/ToontownInfiniteRetro/start_game.sh: line 3: ^: command not found
edit: i lowercased the p but it doesnt prompt u to enter username like it should
The problem with your code is this line:
export -P ttiUsername="Username: " || ^
It's wrong because export doesn't read data, -P is not a valid option, and ^ is not a valid command. None of it makes sense if the goal is to read data.
To read data from the user, use read:
read -p "Username: " ttiUsername
echo "You wrote: $ttiUsername"

Execute psql query in bash

I have a problem with executing a psql-query in a bash script.
Below is my code.
run_sql(){
sql_sel="$1;";#sql select
table=$2;#table name
for i in "${!GP_SERVER_NAMES[#]}"
do
logmsg "Executing [$sql_sel] on "${GP_SERVER_NAMES[$i]}": " $loglvl;
result_host[$i]=`${PSQL_HOST[$i]}${sql_sel}`;
#result_host[$i]=cleanresult "`$(${PSQL_HOST[$i]} "$tx_fix $sql_sel" 2>&1`");
if [[ `checkresult "${result_host[$i]}"` != 'true' ]]; then
logmsg "Error occured during sql select: Result for "${GP_SERVER_NAMES[$i]}" '${table}': ${result_host[$i]};" '1' '1';
raise_alarm "${GP_SYNC_SQL_ERR}" "${i}" "${table}" "${result_host}";
fi
logmsg "Result for" ${GP_SERVER_NAMES[$i]} " '${table}': ${result_host[$i]}";
done
final_result='true';
for i in "${!result_host[#]}"
do
if [[ `checkresult "${result_host[$i]}"` = 'true' ]]; then
final_result='false';
I am trying to executing the query on many different servers, with the following command
result_host[$i]=${PSQL_HOST[$i]}${sql_sel};
The above variables have the following meaning:
1. result_host[$i] : is an array that holds the i-th result of the sql query.
2. PSQL_HOST[$i] : is the command line psql-statement, including the IP address which is of the form
psql -t -q -h -U password -d database -c
3. $sql_sel : is the sql_statement
When I run the script, I get the following output.
scriptname.sh: line 168: SELECT: command not found
ERROR: syntax error at end of input
LINE 1: SELECT
^
Why is that? Any help, comments or suggestions would be appreciated.

Putting the output of a command with interaction inside a variable while using grep in bash

This program I use has it's own variables to set when you run it, so I want to set those variables and then greping the output then storing it inside a variable. However, I don't know how to go about this the correct way. The idea I have doesn't work. The focus is on lines 7 through 14.
1 #!/usr/local/bin/bash
2 source /home/gempak/NAWIPS/Gemenviron.profile
3 FILENAME="$(date -u '+%Y%m%d')_sao.gem"
4 SFFILE="$GEMDATA/surface/$FILENAME"
5 echo -n "Enter the station ID: "
6 read -e STATION
7 OUTPUT=$(sflist << EOF
8 SFFILE = $SFFILE
9 AREA = #$STATION
10 DATTIM = all
11 SFPARM = TMPF;DWPF
12 run
13 exit
14 EOF)
15 echo $OUTPUT
But I get this:
./listweather: line 7: unexpected EOF while looking for matching `)'
./listweather: line 16: syntax error: unexpected end of file
Putting together everyone's answers, I came across a working solution myself. This code works for me:
#!/usr/local/bin/bash
source /home/gempak/NAWIPS/Gemenviron.profile
FILENAME="$(date -u '+%Y%m%d')_sao.gem"
SFFILE="$GEMDATA/surface/$FILENAME"
echo -n "Enter the station ID: "
read -e STATION
OUTPUT=$(sflist << EOF
SFFILE = $SFFILE
AREA = #$STATION
DATTIM = ALL
SFPARM = TMPF;DWPF
run
exit
EOF
)
echo $OUTPUT | grep $STATION
Thanks everyone!
I'd put your program to run in a separate .sh script file, and then run the script from your first file, passing the arguments you want to pass as command line arguments. That way you can test them separately.
You could also do it in a function, but I like the modularity of the second script. I don't udnerstand exactly what you are trying to do above, but something like:
runsflist.sh:
#!/bin/bash
FILENAME="$(date -u '+%Y%m%d')_sao.gem"
SFFILE="$GEMDATA/surface/$FILENAME"
AREA = #$STATION
DATTIM = all
SFPARM = TMPF;DWPF
grep $STATION | sflist
main.sh:
#!/bin/bash
echo -n "Enter the station ID: "
read -e STATION
OUTPUT=`runsflist.sh`
echo $OUTPUT
If sflist needs interaction, I'd try something like this:
SFFILE=$(
( echo SFFILE = "$SFFILE"
echo AREA = "#$STATION"
echo DATTIM = all
echo SFPARM = TMPF;DWPF
echo run
cat
) | sflist)
Unfortunately, you have to type exit as part of the interaction.

Resources