LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   [BASH] here document creates problem with if-fi statemens. (https://www.linuxquestions.org/questions/programming-9/%5Bbash%5D-here-document-creates-problem-with-if-fi-statemens-750440/)

RaptorX 08-26-2009 01:34 PM

[BASH] here document creates problem with if-fi statemens.
 
Hi guys!

I am reading the Advanced Bash Scripting and I decided to practice a bit and create my own little script.

I am trying to insert a little here document within an if-fi statement but i get a little problem:
Code:

if [ $0 = "mountemall" ]; then

      [chunk of code]

      cat <<SUCCESS
      Operation Successful!
      >>-----------------------------
      $count files mounted correctly.
      SUCCESS
fi

      [more code]

I am using vi and this is what happens:

when you put the << to start the here document everything gets red bellow that point until you put the keyword. But in my case even though I put the keyword as I showed you the fi and everything below it stays in red as if it were commented...

now if I do this:

Code:

if [ $0 = "mountemall" ]; then

      [chunk of code]

      cat <<SUCCESS
      Operation Successful!
      >>-----------------------------
      $count files mounted correctly.
     
fi
SUCCESS
      [more code]

Then everything gets to normal color again... But i assume it will brake my if-fi statement...

Why does that happens?
if you want I can post the whole code in case the problem can be within the code itself.

GrapefruiTgirl 08-26-2009 01:40 PM

Since the redirect into `cat`, once opened, will stay open until the process completes (or some other error occurs), you only need a single < to accomplish the task.

I tried your first example with only a single < and it works for me.

Sasha

RaptorX 08-26-2009 01:55 PM

Quote:

Originally Posted by GrapefruiTgirl (Post 3658612)
Since the redirect into `cat`, once opened, will stay open until the process completes (or some other error occurs), you only need a single < to accomplish the task.

I tried your first example with only a single < and it works for me.

Sasha

Thanks for the pointer, I did found out what was wrong... and it is stupid... :D

as you can see I was doing:

Code:

            cat <<SUCCESS
            [text]
            SUCCESS

but vi is expecting:

Code:


            cat <<SUCCESS
            [text]
SUCCESS

for some reason vi appends the tab to the keyword and it kept looking for it... once i eliminated the space it right away worked as it should.

In the other hand I think that if you do "cat <SUCCESS" it will try to open a file called "SUCCESS" which doesnt exist, am I wrong on that?

GrapefruiTgirl 08-26-2009 02:01 PM

Ohhh, my goodness, that hadn't occurred to me about the tabulation of the keyword ;) nice catch!

And as for the opening of a file, if you wanted to, try this:

Code:

cat << SUCCESS > filename.txt

hello
goodbye
something else

SUCCESS

NOTICE that in this case, there are a double << -- and you will get the lines catted into a file called 'filename.txt'

I'm not certain about your last question; try it out and see :) and let me know (it seems you're right though)

Sasha

colucix 08-26-2009 02:09 PM

You can still use indentation with TABs in here documents if you use the syntax <<- as in the following example:
Code:

#!/bin/bash
cat > testfile <<-SUCCESS
        hello world
        SUCCESS

Note there is a TAB before the limit string at the end. Blank spaces are not valid, anyway.

RaptorX 08-26-2009 02:12 PM

exactly as expected:

Code:

#!/bin/bash
#temp file

cat <SUCCESS
this is a temp file
SUCCESS

returns:

Code:

[~]$ temp.sh
./temp.sh: line 4: SUCCESS: No such file or directory
./temp.sh: line 5: this: command not found
./temp.sh: line 6: SUCCESS: command not found

In my original code I am not using "cat <<SUCCESS > file" because I want the output to come to the stdout, im using it that way because:

Code:

echo
echo this
echo is
echo uglier
echo


Code:

cat <<END

than
something written like this
which is nicer...

END

And it still has the same effect. ^^

catkin 08-26-2009 02:26 PM

Quote:

Originally Posted by GrapefruiTgirl (Post 3658639)
Code:

cat << SUCCESS > filename.txt

hello
goodbye
something else

SUCCESS


That works, which was educational! :)

One of the Here Document "gotchas" was you couldn't have a space between << (or <<-) and the delimiter word. I just checked the bash references and some examples in ABSG and that's how they show it, with no space, but Sasha's code works perfectly. A welcome change in the specification and thanks for illustrating it.

catkin 08-26-2009 02:30 PM

Quote:

Originally Posted by RaptorX (Post 3658651)
Code:

cat <<END

than
something written like this
which is nicer...

END


Code:

echo 'And
this is
sweet, too
(and doesn't start a sub-process)'


GrapefruiTgirl 08-26-2009 02:40 PM

cat << DOG > animals.txt
 
Quote:

Originally Posted by catkin (Post 3658660)
That works, which was educational! :)


Thanks -- I almost always try to look into these sorts of threads (even if I can't provide *any* input) because not only are the various documentation sometimes outdated or contain typos, but as you mentioned, sometimes things get updated, and yet are not documented anywhere!

I find this << SUCCESS >> cat thread educational < as a whole >

because there are < cat EOF
so many different ways to > redirect things :confused: it's no wonder we get confused :p

Cheers,
Sasha

PS - here's a novelty I didn't know of till a few weeks ago: Did you guys know there's a `tac` command? It's the opposite of `cat` in that it starts at the END (or bottom) of a file/data stream, and works backwards ;)

colucix 08-26-2009 02:47 PM

Another trick in here documents is that they permit shell substitution, so that you can embed shell variables, arithmetics and results of commands inside the block of code:
Code:

#!/bin/bash
count=3
cat > testfile << SUCCESS
  $HOME
  $(date)
  $((++count))
SUCCESS

The content of testfile in this case will be:
Code:

$ cat testfile
  /home/alex
  Wed Aug 26 21:43:40 CEST 2009
  4

but if you embed one or more character of the limit string in quotes (double or single) the shell substitutions are not performed and the block of code is interpreted literally:
Code:

#!/bin/bash
count=3
cat > testfile << SUCCES'S'
  $HOME
  $(date)
  $((++count))
SUCCESS

In this case you will get:
Code:

$ cat testfile
  $HOME
  $(date)
  $((++count))


GrapefruiTgirl 08-26-2009 02:49 PM

[off topic]
@ colucix -- P.S. I have always liked your signature!
[/off topic]

RaptorX 08-26-2009 03:03 PM

@colucix

now, that is something cool to know!!

@fruitygirl

that with the tac is very interesting, I keep finding out more and more commands to do what you want to do in every single way you can think of!

@catkin

actually you are right! echo is the quick and dirty solution.

catkin 08-26-2009 03:17 PM

Quote:

Originally Posted by GrapefruiTgirl (Post 3658673)
PS - here's a novelty I didn't know of till a few weeks ago: Did you guys know there's a `tac` command? It's the opposite of `cat` in that it starts at the END (or bottom) of a file/data stream, and works backwards ;)

No -- I didn't. One day it will come in handy ... :)

colucix 08-26-2009 03:23 PM

Quote:

Originally Posted by GrapefruiTgirl (Post 3658685)
[off topic]
@ colucix -- P.S. I have always liked your signature!
[/off topic]

Thank you! I think it fits well to many issues about computers. Indeed I still wonder how it is possible that such a microscopic piece of silicon is able to accomplish so many tasks! :eek:

colucix 08-26-2009 03:29 PM

Quote:

Originally Posted by RaptorX (Post 3658702)
that with the tac is very interesting, I keep finding out more and more commands to do what you want to do in every single way you can think of!

What about rev?
Code:

$ echo This is a reversed line | rev
enil desrever a si sihT

It does not work with palindromes, anyway! ;)


All times are GMT -5. The time now is 07:17 AM.