Bash coding error

OK, I need a little help on a simple Bash script. I would use up a whole page listing what I tried, but I didn’t keep track of every change, plus no use to show what doesn’t work. I read two different pages on the web, but still something does not click with me on what I believe is a simple Bash shell problem.
#!/bin/bash
clear
echo { 1=mp4, 2=avi, 3=wmv, 4=VOB }
read ty
echo $ty

if [ $ty = “1” ] then $mv=“mp4” fi

if [ $ty = “2” ] then $mv=“avi” fi

echo $ty
echo $mv
exit

  • And this is what I get;
    { 1=mp4, 2=avi, 3=wmv, 4=VOB }
    2
    2
    ./chope: line 24: syntax error: unexpected end of file
    easyt50@X220:~/Videos$

someone else may come along with great insight, but i wanted to pass along this option. there is a site you can use to check scripts called: https://www.shellcheck.net/

2 Likes

You have a couple of syntax errors in your file.

First, you use plain read instruction, even though one should usually use read -r, except you explicitly need read.
Second, your if statements have missing command terminators and contain other syntax errors.
Your

if [ $ty = “1” ] then $mv=“mp4” fi

should actually be

if [ $ty = 1 ]; then mv="mp4"; fi

or

if [ $ty = 1 ]; then
  mv="mp4"
fi

I suggest you look up a simple bash beginner’s guide to get started with bash scripting.

The unexpected end of file error occurs, because the if statements aren’t ever terminated, therefore they are waiting for their demise, but instead of the statement terminator they encounter the end of file, i. e. end of the script.

5 Likes

Thanks to @01101111 and @Akito I do not any errors in the script.
But … it does not work.
My output is 2, 2, (blank).
Correct output is 2, 2, avi.
I need to some more reading.
PS. I not completely new to programming. I know 2 mainframe languages (Cobol & ALC (Assembler). And I know Basic for PC.

The condition for the statements is probably not met. Did you remove the wrong quotes from your original version?

Thanks for your help @Akito. The script is close to working, but no cigar.
The script now looks like this: #!/bin/bash
clear
one=“1”
two=“2”
mf=“xxx”
mp4=“mp4”
avi=“avi”
echo " 1=$mp4, 2=avi, 3=wmf, 4=VOB "
echo “$mf”
read ty
echo “$ty”
if (( ty == one )); then (( mf=mp4 )); fi

if (( ty == two )); then (( $mf=$avi )); fi
echo “$mf”
exit
The run of the script now looks like this for reply 1:
1=mp4, 2=avi, 3=wmf, 4=VOB
xxx
1
1
./chope: line 16: ((: mp4: expression recursion level exceeded (error token is “mp4”)
xxx
And for reply 2:
1=mp4, 2=avi, 3=wmf, 4=VOB
xxx
2
2
./chope: line 18: ((: avi: expression recursion level exceeded (error token is “avi”)
xxx

As I already said twice, you must not use the weird quotes. Remove the quotes. It is not a valid character for quoting strings.

Additionally, you have built in new syntax mistakes, especially in those if statements.

It would be also much easier to help if you explained what the script is supposed to achieve or which problem it tries to solve.

1 Like

Sorry you don’t like the weird quotes. Running the script thru “ShellCheck” suggested the quotes. Beside Bash is not complaining about them.
It’s the if statements I’m having a problem with! (See error message) I try 6 ways to Sunday in changing the if statement, but so far no luck.
Shell Script specs per request;
Accept input value from user. Input is to be a 1, 2, 3 or 4.
Based on input, assign a variable (mf) the following value from table;
1 = mp4
2 = avi
3 = wmv
4 = VOB

It’s not that I don’t like them, it’s that they are incompatible with the shell. If ShellCheck doesn’t report any errors, then it is obviously wrong in doing so. That’s why I refrain from recommending such tools to beginners.

Bash is not complaining about the quotes, because the quotes are part of the value.
Here the proof:

akito@localhost:~$
mp4=“mp4”
akito@localhost:~$
echo $mp4
“mp4”

Do you understand now that you have to remove the WRONG quotes that do not work with bash the way you want it to work?

Additionally, you still did not explain what the script is supposed to do in the first place.

2 Likes

do you need to declare all of those variables beforehand? can’t you just assign a value to mf with the if statements after getting a value for $ty from read?

3 Likes

Sorry to disagree with you, for your knowledge of Linux is far greater then mine.
I will re-print some of the script and it’s output from posting above;
Script,
one=“1”
two=“2”
mf=“xxx”
mp4=“mp4”
avi=“avi”
echo " 1=$mp4, 2=avi, 3=wmf, 4=VOB "
echo “$mf”
read ty
echo “$ty”
Output,
1=mp4, 2=avi, 3=wmf, 4=VOB
xxx ---------> This from the echo “$mf” which was define as mf=“xxx”. No quotes on output
1 -------> Response to terminal asking for input.
1 -------> From echo “$ty”
ALSO – it looks like our PC’s do not agree on scripts!
easyt50@X220:~$ mp4=“xxx”
easyt50@X220:~$ echo $mp4
xxx <------------------------------------ No qoutes
easyt50@X220:~$ echo $SHELL
/bin/bash
easyt50@X220:~$

I’m not sure how to explain more basic, but I’ll try.
If user reply 1 then place value mp4 into a string.
If 2, place avi into a string
After input of either 1 or 2, string will equal mp4 or avi


But maybe you are asking “why”? I have 4 shell script, that are working, that will copy part of a movie. Like split or cut a portion. The 4 scripts are the same except for the movie type. If I can make the move type a variable then I would only have one script.

@01101111, this was just the nth time I was trying something out. But I do believe you are correct. After looking at several web pages I could not find a comparison (If statement) that compared a string to a numeric. I could find string to string and numeric to numeric examples.
So, I try placing my numeric into a string to see if I had better luck that way. But no luck.
@Akito had some good advice, but it looks like his PC and my PC treat scripts different. I was not able to reproduce a sample he gave me.
Thanks for you input.

my thought was that you wouldn’t need to compare the string to anything. if the only input options are 1-4, then 4 if statements could assign the value to mf according to what that input is:
if [ $ty = 1 ]; mf=“mp4”; fi
if [ $ty = 2 ]; mf=“avi”; fi
if [ $ty = 3 ]; mf=“wmf”; fi
if [ $ty = 4 ]; mf=“VOB”; fi

an array might make that a little easier/shorter: type=(‘null’ ‘mp4’ ‘avi’ ‘wmf’ ‘VOB’) then assign the value to mf depending on the specific element and $ty?

edit: missed the part where you wanted the video type value assigned to a variable. adjusted accordingly :upside_down_face:

1 Like

WOW! @01101111, I’m impressed. :fireworks:
Your sample was close but it did not work for me.
BUT playing with it a little and this did work!
if [ $ty = 1 ]; then mf=mp4 ; fi
I just added ‘then’ and took off the " from mp4.
Thanks again to you @01101111 and @Akito for many helpful replies.
I still don’t understand the difference between [[, ((, $ty, and ty, but I got an example that works!

1 Like

i gotta admit i edited that thing so many times i am surprised any of it was helpful :crazy_face: the commands involved were interesting subjects to read about.

i was wondering about the single [ compared to the [[ as well. i suppose if i keep reading bits here and there it will probably pop up one of these days.

my take on that is the first is the value (1-4) and the second is the name of the variable. so the comparison needed the value (1 = 1? or 2 = 2? instead of ty = 1) instead of the name. maybe? :slight_smile:

100% agree. I edit the script so many times that I forget what I try and what I did not. I try changing only one thing at a time, test, read error, repeat. :thinking:

2 Likes

Looking back over the posts, you had the correct format too and it help me with the terminators and syntax. But for some reason I did not test / play with the actual command.
Thanks again for your help. :smile:

2 Likes

The quotes are removed, that’s why it works.

If the following example works for you:

Then this means you weren’t using those weird quotes in the actual shell, but they actually got converted on the way to this post. Which means the actual shell script contains the correct quotes while your post does not. We both use the same shell, so it is technically impossible that different behaviour is shown, especially when this shell is decades old and is so stable, you could build a house on it. Therefore, the quotes in your post are still wrong and the quotes I proposed are the right ones. Which are the same you are using in your script.

2 Likes

i thought i would add this bit since i read it last night after the discussion (from here):

  • Use the = operator with the test [ command.
  • Use the == operator with the [[ command for pattern matching.
1 Like

The difference mainly roots in compatability between different shells. While [[ and other specialties are bash only functionalities, the less readable and less user-friendly [ and similar commands are compatible with any POSIX shell, like ash, csh, sh, etc. So using commands like [ is only needed if you care about compatability across platforms. If you make your own script for an OS like Mint or Ubuntu, where bash is always the main shell, then one should use the advanced bash features like the double bracket, proper evaluation operators like == and built-in regex functionality i.e. =~.

3 Likes