Question about everyone's favorite old clunker, Bash. :-)
Linux - NewbieThis 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
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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?
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.
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.
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!
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.
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).
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.
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
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.
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
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.