Bash Script Unexpected End of File - new coder - bash

I'm new to bash, I'm just trying to pick in up in my free time. I'm writing a simple script that prints out the filename I supply as many times as there are characters in the filename, and then positive or negative based on the second argument. I'm getting an unexpected end of file error on this script, and I'm not sure why.
#!/bin/bash
FILENAME=$1
NUMBER=$2
COUNT=0;
STR=${#FILENAME}
while ($COUNT < $STR){
echo $FILENAME
$COUNT++
}
if ($NUMBER < 0)
echo "Negative"
if ($NUMBER > 0)
echo "Positive"
exit
I'm executing with
./script1.sh hello 2
and I'm expecting the output to be
hello
hello
hello
hello
hello
Positive
If anyone could shed some light as to what's going on with the error, that'd be great.
edit: forgot to add the second condition to add to the COUNT variable, and now I'm getting an error:
line 9: syntax error near unexpected token `{'
line 9: `while ($COUNT < $STR){'

Basically you are confusing Bash's syntax with some other language.
In Bash, if's syntax (if not using else) is if condition;then commands;fi. Your code does not have then and fi. Also, the condition should be (( $NUMBER > 0 )).
The syntax of while is while condition;do commands;done, and your code is also wrong.

Related

What this symbol mean "#?" in ksh

What does "#?" mean in ksh script? e.g:
tt=03
while [ "$tt" !=' ' ];
do
tt=${tt#"?}
done
echo $tt
I will get nothing here. So what "#?" means in this scipt? Thank you.
Assuming corrected syntax on the while as downtheroad suggested (need blank after [ and before ]) and also omitting the " in tt=${tt#"?} (the omitted version is what you cite).
Also the test in the while condition needs to be against an empty string'', otherwise the loop does not terminate.
tt=${tt#?}
chops off the first character from the string.
See this test program (I added the 2 echos and the parens to be able to see the exact contents of tt in the loop before and after chopping:
tt=03
while [ "$tt" != '' ]
do
echo "A: (tt=$tt)"
tt=${tt#?}
echo "B: (tt=$tt)"
done
echo $tt
gives this result (note the empty last line from the last echo):
A: (tt=03)
B: (tt=3)
A: (tt=3)
B: (tt=)

bash - difference between two text files

Let's say there are two text files and I need to check if they are different.
If they are, I need to make some changes to them and display information on the terminal.
Will something like this work?
diff file1.txt file2.txt > difference.txt
if [ -s difference.txt ]
then
.....
else
.....
fi
I also tried to find some other ways of writing this in bash, and I've found this code :
DIFF_OUTPUT="$(diff new.html old.html)"
if [ "0" != "${#DIFF_OUTPUT}" ]; then
But I can't quite understand it.
I guess in the first line we create a variable DIFF_OUTPUT which works just like difference.txt in my code?
Then there's
${#DIFF_OUTPUT}
which I don't understand at all. What's going on here?
I apologise if my questions are very basic, but I couldn't find an answer anywhere else.
diff has an exit status of 1 if the files are different.
diff file1.txt file2.txt > difference.txt
status=$?
case $status in
0) echo "Files are the same"
# more code here
;;
1) echo "Files are different"
# more code here
;;
*) echo "Error occurred: $status"
# more code here
;;
esac
If you aren't concerned with errors, then just check for a zero-vs-non-zero condition:
if diff file1.txt file2.txt > difference.txt; then
# exit status was 0, files are the same
else
# exit status was > 0, files are different or an error occurred
fi
The first line sets a variable DIFF_OUTPUT as the output/terminal result of the command diff new.html old.html.
This is called command substitution. You can encapsulate an expression inline by using $(). Think of it as copying the expression into a terminal and running it and then pasting the result straight back into your code.
So, DIFF_OUTPUT now contains the output of the diff of the two files. If the files are identical, then diff will output nothing, thus the variable DIFF_OUTPUT will be assigned an empty string.
${#variable} returns the length of a variable in bash. Thus, if there was no difference between the files, the variable (DIFF_OUTPUT) will be an empty string - which has a length of 0. Thus, ${#DIFF_OUTPUT} == "0", meaning that, if there was a difference in the files, ${#DIFF_OUTPUT} != "0" and your condition is satisfied.
DIFF_OUTPUT="$(diff new.html old.html)"
The first line saves the output of a command diff into a variable DIFF_OUTPUT.
${#DIFF_OUTPUT}
and this expression outputs the length of DIFF_OUTPUT. ${#VAR } syntax will calculate the number of characters in a variable

Unix case statement in OSX

I am trying to port some Windows bat files to Mac shell scripts
I get a syntax error when executing a file containing the following case statement:
case ${1} in
( C | c ) echo "hoera";;
where argument ${1} is given as 'C'
The message is:
-bash: even: line 6: syntax error near unexpected token `newline'
'bash: even: line 6: ` ( C | c ) echo "hoera";;
I think the syntax is correct according to the documentation. Where am I going wrong?
Syntax should be:
case $var in
CASE1) COMMAND-LIST;;
CASE2) COMMAND-LIST;;
esac
Each case consists of one or more shell patterns, separated by pipes - you don't need an opening parenthesis to match the closing one. Your example should instead be:
case ${1} in
C|c) echo "hoera";;
Or possibly:
case ${1} in
[Cc]) echo "hoera";;

(standard_in) 1: syntax error in bash script

I'm trying to generate some quasi random numbers to feed into a monte carlo simulation. I'm using bash. I seem to have hit a syntax error which I've narrowed down to being in this bit of code.
randno4=($RANDOM % 100001)
upper_limit4=$(echo "scale=10; 1*75.3689"|bc)
lower_limit4=$(echo "scale=10; 1*75.1689"|bc)
range4=$(echo "scale=10; $upper_limit4-$lower_limit4"|bc)
t_twall=`echo "scale=10; ${lower_limit4}+${range4}*${randno3}/100001" |bc`
echo "$t_twall"
Does anyone know why I the below output and not a value between 75.3689 and 75.1689 as that is what I would be expecting?
(standard_in) 1: syntax error
The first line should looks like :
randno4=$((RANDOM % 100001))
(( )) is bash arithmetic, with the leading $ , the value is substituted : $(( ))
When you wrote
randno4=( )
you try to feed an ARRAY with a arithmetic expression with the wrong syntax.
See http://wiki.bash-hackers.org/syntax/arith_expr
And finally, like Etan Reisner said, You also use $randno3 in the t_twall assignment line which is undefined

Line error in shell script

I have the following code in a shell script.
This only seems to work when it is not defined in a function.
The problematic line is the one containing the "<<".
The error message is
"./run: line 210: syntax error:
unexpected end of file"
How can I write this correctly within a function?
init_database()
{
cd ../cfg
db.sh << ENDC
$DB_ADMIN
0
y
n
ENDC
check_status
sqlplus $DB_SCHEMA#$DB_NAME < initial_data.sql
cd -
}
There are a number of ways to fix that problem.
1/ Unindent the here document end marker, such as:
cat <<EOF
hello
$PWD
EOF
but that will make your code look ugly.
2/ "Indent" the here document begin marker:
cat <<' EOF'
hello
$PWD
EOF
where that bit before the first EOF is exactly the same as the before the second (tab, four spaces, two tabs, whatever). This allows you to keep your nice indenting, although it doesn't expand variables inside the here-document ($PWD doesn't change).
3/ Allow tabs to be stripped from the start of input lines and the end marker.
cat <<-EOF
hello
$PWD
EOF
but there's no way to get tabs into the beginnings of lines.
4/ For your purposes, you can also use:
( echo "$DB_ADMIN";
echo "" ;
echo "0" ;
echo "y" ;
echo "n"
) | db.sh
check_status
sqlplus $DB_SCHEMA#$DB_NAME < initial_data.sql
cd -
I believe number 4 is the best option for you. It allows nice lining up of the input, tabs and spaces anywhere in the lines and variable expansion.
The end of your "Here document" needs to be unindented, I'm afraid.
The ENDC label must be alone in a line without leading/trailing whitspaces.

Resources