LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 08-08-2009, 08:05 AM   #1
Completely Clueless
Member
 
Registered: Mar 2008
Location: Marbella, Spain
Distribution: Many and various...
Posts: 816

Rep: Reputation: 69
Question about everyone's favorite old clunker, Bash. :-)


HI all,

I've just reached page 280 of the Linux Command Line and Shell scripting Bible (only 520 pages to go!) and have a query on this piece of code which the author is using to illustrate re-direction of loop output to a file:


Code:
#!/bin/bash

for file in /home/anton/*
do
   if [ -d “$file” ]
   then
       echo “$file is a directory”
   else
       echo “$file is a file”
   fi

done > output.txt
This code does indeed create a file called output.txt and succesfully writes a load of entries to it. My problem is I don't understand why each time the loop iterates, it doesn't over-write output.txt? From my reading of this bit of script, the output file should just get over-written the same number of times there are files and directories in /home/anton and I should just end up with 'output.txt' containing the last entry only. But this doesn't happen; the file is properly concatenated each iteration. How come?

Thanks.
 
Old 08-08-2009, 08:47 AM   #2
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959
If the redirect is placed inside the loop, each operation inside it is considered a separate process, including the opening and closing of multiple redirections. But when you place it on the outside, the loop as a whole is considered as a single process, and so it opens only a single redirect that stays open until the loop finishes.
 
Old 08-08-2009, 08:47 AM   #3
Ygrex
Member
 
Registered: Nov 2004
Location: Russia (St.Petersburg)
Distribution: Debian
Posts: 666

Rep: Reputation: 68
for redirecting each iteration distinctively, you should slightly modify the structure:
Code:
#!/bin/bash

for file in /home/anton/*
do
   { if [ -d “$file” ]
   then
       echo “$file is a directory”
   else
       echo “$file is a file”
   fi;
   } > output.txt ;
done
 
Old 08-08-2009, 09:08 AM   #4
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959
Quote:
Originally Posted by Ygrex View Post
for redirecting each iteration distinctively, you should slightly modify the structure:
Code:
#!/bin/bash

for file in /home/anton/*
do
   { if [ -d “$file” ]
   then
       echo “$file is a directory”
   else
       echo “$file is a file”
   fi;
   } > output.txt ;
done
But this does precisely what he was wondering about. Since the redirect is inside the for loop, it will overwrite the file each time, and only the last iteration will be preserved. You have to change it to ">> output.txt" if you want to save the entire output.

And the braces around the if construct aren't really necessary either. You can redirect its output directly in the same way as the loop.
 
Old 08-08-2009, 12:13 PM   #5
Completely Clueless
Member
 
Registered: Mar 2008
Location: Marbella, Spain
Distribution: Many and various...
Posts: 816

Original Poster
Rep: Reputation: 69
Quote:
Originally Posted by David the H. View Post
But this does precisely what he was wondering about. Since the redirect is inside the for loop, it will overwrite the file each time, and only the last iteration will be preserved. You have to change it to ">> output.txt" if you want to save the entire output.

And the braces around the if construct aren't really necessary either. You can redirect its output directly in the same way as the loop.
Thanks for clarifying that, David. For a while there I thought I was going nuts!
Just as an aside, and for anyone else who's working through this book and finds this post; it is riddled with typographical and syntax errors, I'm sorry to say. It doesn't unduly bother me as from my previous (fading) experience of C/C++ I can see what the author is trying to do. In the code snippet under discussion, the book states to use an 'elif' instead of an else, which of course won't run. I should have kept a note of the errors and mailed the publishers with a list of them, but I have enough to worry about with my computers in general!
 
Old 08-09-2009, 07:52 PM   #6
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.9, Centos 7.3
Posts: 17,362

Rep: Reputation: 2377Reputation: 2377Reputation: 2377Reputation: 2377Reputation: 2377Reputation: 2377Reputation: 2377Reputation: 2377Reputation: 2377Reputation: 2377Reputation: 2377
Perhaps these would be better (less errors)
http://rute.2038bug.com/index.html.gz
http://tldp.org/LDP/Bash-Beginners-G...tml/index.html
http://www.tldp.org/LDP/abs/html/

As they're online, they tend to get fixed pronto.
Also means you can copy 'n paste instead of having to type stuff in to play with it.
 
Old 08-10-2009, 06:05 AM   #7
Completely Clueless
Member
 
Registered: Mar 2008
Location: Marbella, Spain
Distribution: Many and various...
Posts: 816

Original Poster
Rep: Reputation: 69
Quote:
Originally Posted by chrism01 View Post
Perhaps these would be better (less errors)
http://rute.2038bug.com/index.html.gz
http://tldp.org/LDP/Bash-Beginners-G...tml/index.html
http://www.tldp.org/LDP/abs/html/

As they're online, they tend to get fixed pronto.
Also means you can copy 'n paste instead of having to type stuff in to play with it.
It's a shame that all such resources aren't on the web in a more downloadable form. The first one you mention above has this option; the other two don't. It would be much nicer if the tutorials were available as a single, compressed tarball which one could untar and read off-line whilst waiting for a train or whatever.
 
Old 08-10-2009, 06:10 AM   #8
mushroomboy
Member
 
Registered: Jan 2006
Distribution: Debian Testing ALWAYS!!!
Posts: 363

Rep: Reputation: 43
Actually the bit of code only inserts the output into the text file, if the text file isn't there the default action is to create it. AKA why can you do view randomfile and it "opens" the file, really it just creates it as blank. But in bash I'm guessing after insertion it saves as default, the same thing can be done in C++ though I don't quite remember how it's done. That's why when you do patch files > or other inserts with > in bash don't over wright the file, they just insert the code into the next free line (unless otherwise stated I think).
 
Old 08-10-2009, 01:44 PM   #9
Completely Clueless
Member
 
Registered: Mar 2008
Location: Marbella, Spain
Distribution: Many and various...
Posts: 816

Original Poster
Rep: Reputation: 69
Quote:
Originally Posted by mushroomboy View Post
Actually the bit of code only inserts the output into the text file, if the text file isn't there the default action is to create it. AKA why can you do view randomfile and it "opens" the file, really it just creates it as blank. But in bash I'm guessing after insertion it saves as default, the same thing can be done in C++ though I don't quite remember how it's done. That's why when you do patch files > or other inserts with > in bash don't over wright the file, they just insert the code into the next free line (unless otherwise stated I think).
I should remember how this is done in C/C++ as well, but I need a bit of a refresher after 17 years of not going near it.
As for the current subject, you can use 'touch' to create an empty file in Bash. Or in a script, just use '> [filename]' and if the file doesn't already exist, Bash creates it and writes function/command output to it. But to _append_ to an existing file, you have to use '>>' or the original file gets overwritten.
 
Old 08-11-2009, 06:07 PM   #10
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959
It's really very easy. Both > and >> will create the file if it doesn't exist. But > will always create a new file, overwriting any existing file if necessary, while >> will append to an existing text file if found.

If your script or program is using > to add material to a file, then certainly what it's really doing is copying the original file contents into its memory space, altering it there, then replacing the original file with the new version. This is usually the case if you need to add (or alter) content at a location other than at the end of the file, since that's all the >> append can do.

Quote:
Originally Posted by Completely Clueless View Post
It's a shame that all such resources aren't on the web in a more downloadable form.
You can always use a web mirroring program to download the contents of the site to a local mirror. The traditional program for doing this is httrack, but I see that there are some newcomers as well (omt,simba, w3mir), and the venerable wget can also be used as long as the mirroring job isn't too complex.

A mirrored site can be accessed with your browser directly, of course, or you can use an html-to-whatever converter to print the pages to other formats.
 
Old 08-11-2009, 06:12 PM   #11
joeBuffer
Member
 
Registered: Jul 2009
Distribution: Ubuntu 9.04
Posts: 328

Rep: Reputation: 42
Quote:
Originally Posted by Completely Clueless View Post
It's a shame that all such resources aren't on the web in a more downloadable form. The first one you mention above has this option; the other two don't. It would be much nicer if the tutorials were available as a single, compressed tarball which one could untar and read off-line whilst waiting for a train or whatever.
They do have other options for how to download them. They have them all on one html page, tarballs, PDF, Postscript, etc. Here:
http://www.tldp.org/guides.html
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
What is everyone's favorite utility for.... Zeniq Linux - General 25 10-22-2005 10:59 AM
Asking everyone's opinion..... spotz78 Linux - Distributions 7 09-23-2004 07:42 AM
Question about running 7.2 on a Pent166 clunker rhb_hj Mandriva 2 09-12-2004 03:50 PM
What's everyone's favorite car? randyriver10 General 35 07-30-2004 11:29 AM
everyone's opinion hatchetman Linux - Distributions 2 12-02-2002 02:06 PM


All times are GMT -5. The time now is 08:19 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration