Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
is there a way to make a "GOTO" statement in bash?
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Portage & Programming
View previous topic :: View next topic  
Author Message
swooshOnLn
l33t
l33t


Joined: 28 Feb 2006
Posts: 741
Location: Charlotte, North Carolina

PostPosted: Thu Apr 27, 2006 5:28 am    Post subject: is there a way to make a "GOTO" statement in bash? Reply with quote

Is there some way to make a "GOTO" statement in bash? like:

Code:

:start
echo "one"
echo "two"
echo "three"
goto start;

_________________
"WARNING: you may LOL"

This is my font size, color, and signature. It will change to whatever I pick. How cool is that?
Back to top
View user's profile Send private message
frostschutz
Advocate
Advocate


Joined: 22 Feb 2005
Posts: 2977
Location: Germany

PostPosted: Thu Apr 27, 2006 5:50 am    Post subject: Reply with quote

Code:
function start
{
    echo "one"
    echo "two"
    echo "three"
}

start


don't use goto, it makes your code hard to understand.
Back to top
View user's profile Send private message
Jake
Veteran
Veteran


Joined: 31 Jul 2003
Posts: 1132

PostPosted: Thu Apr 27, 2006 6:01 am    Post subject: Reply with quote

better for your purposes:
Code:
while true
do
        echo "one"
        echo "two"
        echo "three"
done
Back to top
View user's profile Send private message
wjholden
l33t
l33t


Joined: 01 Mar 2004
Posts: 826
Location: Augusta, GA

PostPosted: Thu Apr 27, 2006 6:07 am    Post subject: Reply with quote

Google is your friend: http://heather.cs.ucdavis.edu/~matloff/UnixAndC/Unix/CShellII.html

Although I know that gotos can be used in TCSH, I've never felt like doing so. If you want complex logic from a shell script I would recommend CCSH. Here's an example of a CCSH script using gotos (it's really C):
Code:
#!/usr/bin/ccsh

int main () {
        int x = 1;
        loop:
        if (x <= 10) {
                printf("%d\n", x++);
                goto loop;
        }
        return(1);
}
Respectfully, I find Perl much easier for any/all logic than shell scripts.
Back to top
View user's profile Send private message
swooshOnLn
l33t
l33t


Joined: 28 Feb 2006
Posts: 741
Location: Charlotte, North Carolina

PostPosted: Thu Apr 27, 2006 6:28 am    Post subject: Reply with quote

welll, heres the general idea of what i am trying to do:

Code:

#!/bin/bash

function check {
check_for_emerge=$(pgrep emerge | gawk '{print $1}')

if [ "$check_for_emerge" != "" ] then
        umount /usr/portage
        mke2fs -j /dev/hdb4
        mount /usr/portage
        emerge --sync
        exit;
else
        sleep 60;
        check;
}



is that right?
_________________
"WARNING: you may LOL"

This is my font size, color, and signature. It will change to whatever I pick. How cool is that?
Back to top
View user's profile Send private message
TNorthover
Guru
Guru


Joined: 25 Jan 2004
Posts: 434
Location: Edinburgh, UK

PostPosted: Thu Apr 27, 2006 7:04 am    Post subject: Reply with quote

swooshOnLn wrote:
is that right?


I doubt bash is tail-recursive, so in theory that snippet would have a memory leak as the call-stack grows. There's also a couple of syntax mistakes. I'd probably write it:
Code:
while true
do
    check_for_emerge=$(pgrep emerge | gawk '{print $1}')

    if [ "$check_for_emerge" != "" ] ; then
        umount /usr/portage
        mke2fs -j /dev/hdb4
        mount /usr/portage
        emerge --sync
        exit
    fi
    sleep 60
done


Any particular reason you want to wipe portage frequently? I'm assuming hdb4 is /usr/portage.
Back to top
View user's profile Send private message
swooshOnLn
l33t
l33t


Joined: 28 Feb 2006
Posts: 741
Location: Charlotte, North Carolina

PostPosted: Thu Apr 27, 2006 7:09 am    Post subject: Reply with quote

well, because you cant really "deframent", I figured the only way to fix fragmentation over time would be to simply recreate the partition each sync. Therefore, you will more than likley have very little fragmentation.
_________________
"WARNING: you may LOL"

This is my font size, color, and signature. It will change to whatever I pick. How cool is that?
Back to top
View user's profile Send private message
TNorthover
Guru
Guru


Joined: 25 Jan 2004
Posts: 434
Location: Edinburgh, UK

PostPosted: Thu Apr 27, 2006 7:21 am    Post subject: Reply with quote

swooshOnLn wrote:
well, because you cant really "deframent", I figured the only way to fix fragmentation over time would be to simply recreate the partition each sync. Therefore, you will more than likley have very little fragmentation.


If you're doing it every time, I'd look into replacing the "emerge --sync" with directly downloading a snapshot and unpacking it (GENTOO_MIRROR/snapshots/portage-latest.tar.bz2 looks hopeful). It'd certainly be less load on the gentoo servers, and I strongly suspect it'd be quicker for you as well.
Back to top
View user's profile Send private message
swooshOnLn
l33t
l33t


Joined: 28 Feb 2006
Posts: 741
Location: Charlotte, North Carolina

PostPosted: Thu Apr 27, 2006 7:29 am    Post subject: Reply with quote

good Idea, ill look into it in the mornign, im tired :-p
_________________
"WARNING: you may LOL"

This is my font size, color, and signature. It will change to whatever I pick. How cool is that?
Back to top
View user's profile Send private message
ecatmur
Advocate
Advocate


Joined: 20 Oct 2003
Posts: 3595
Location: Edinburgh

PostPosted: Thu Apr 27, 2006 7:42 am    Post subject: Reply with quote

Yeah, Don't Do That; it's abuse of the gentoo servers. Fragmentation really isn't a problem.

For jumping out of multiple enclosing loops, write a function and use return. It makes for cleaner code.

For longjmp() equivalent, use a signal handler (trap) and signal the current shell (kill -s SIGUSR2 $$).
_________________
No more cruft
dep: Revdeps that work
Using command-line ACCEPT_KEYWORDS?
Back to top
View user's profile Send private message
BitJam
Advocate
Advocate


Joined: 12 Aug 2003
Posts: 2506
Location: Silver City, NM

PostPosted: Thu Apr 27, 2006 8:00 am    Post subject: Reply with quote

I think it is way overkill to defragment every emerge --sync. Doing it every 10 or so emerge --syncs would be much more sensible. But an even bigger problem is that downloading the entire portage tree is a truly bone-headed way of defragging (I'm sorry if that sounds offensive).

A much more sensible way to defrag is to make a local copy on a different partition. If you don't have a spare partition for this, you could probably use your root partition since the copy won't be fragmented at all. A spare partition is preferred.

Also, you don't want to defrag the /usr/portage/distfiles directory. Therefore you need to make /usr/portage/distfiles a symlink to a directory outside of /usr/portage. Once you do this, the following commands should do a reasonably good job at defragging:
Code:
# cp -a /usr/portage /var
# rm -r /usr/portage
# cp -a /var/portage /usr
# rm -r /var/portage

Instead of the rm between the copies, you could reformat as per your original idea. You should really consider using "-O dir_index" when making the ext3 filesystem since this speeds things up especially for large directories.

The above instructions put the copy in /var/portage. You may prefer a different location such as /tmp/portage, but even better would be a spare partition.
Back to top
View user's profile Send private message
synss
Apprentice
Apprentice


Joined: 08 Mar 2006
Posts: 282
Location: Dijon > Berlin > Tokyo > Nürnberg > München

PostPosted: Sun Apr 30, 2006 3:17 pm    Post subject: Reply with quote

I'll add my .02$

1. You do not need a journal on that partition, just use plain ext2 and if something goes wrong, wipe it and download another tree. That should speed things up.
2. Another tip, you should use as small a block size as possible, since these are mostly small files and your partition should be MUCH smaller, that is saving place like from 900M to 200M! check mkfs.ext2 -b 1024 -O dir_index -T news for example.
3. It seems your tree is already in a separate partition, hence you do not frag your /usr, hence why do you care about fragging?
4. I do not use a spare partition myself but a mounted file laying on my ext2 /var partition. Check the wiki for that, I find it easier to handle than having tons of half empty partitions around.
Back to top
View user's profile Send private message
BitJam
Advocate
Advocate


Joined: 12 Aug 2003
Posts: 2506
Location: Silver City, NM

PostPosted: Sun Apr 30, 2006 10:12 pm    Post subject: Reply with quote

Wow! Great tips synss. Here is a link to the Gentoo Wiki Article if others want to try this too.

On my system, the time it takes to "du -sh /usr/portage" dropped from over 3 minutes to under 20 seconds. I made my portageFile 1 Gig because I didn't trust that the size requirement would shrink from roughly 600M to roughly 200M, but it did! So I think the 1 Gig size is a bit overkill. I also doubled the number of inodes to 400000 (because of the larger size) and I doubt this was needed.

Here are the commands I used. They are slightly different from those in the Wiki article because I used an ext2 filesystem instead of Reiser:
Code:
# time du -sh /usr/portage/
# dd if=/dev/null of=/var/portageFile bs=1M count=0 seek=1024
# mke2fs -b 1024 -N 400000 -m 0 -O "dir_index" -F /var/portageFile
# tune2fs -c 0 -i 0 /var/portageFile
# mv /usr/portage /var/portage.old
# mkdir /usr/portage
# mount -o loop,noatime /var/portageFile /usr/portage
# df -h
# cp -a /var/portage.old/* /usr/portage/
# df -h
# time du -sh /usr/portage/
# time du -sh /var/portage.old/
# time du -sh /usr/portage/

Don't use these commands blindly, I edited them to remove false starts and to compensate for the fact that my /usr/portage was a symlink to /var/portage. But maybe the will be of some use as a supplement to the wiki article for someone who wants to try this with ext2. Here is the line I added to my fstab:
Code:
/var/portageFile /usr/portage ext2 loop,noatime  0 0


Also, note that I already had made /usr/portage/distfiles a symlink to a directory on a different partition so the size requirements do not reflect the size of distfiles.

Finally, I want to note that this seemed to drastically increase the speed of "emerge --sync" as the timings of the du command would suggest. My current system is less than 2 months old so I am surprised that it got so fragmented so quickly (but I do sync often as I am still trying things out). I am going to monitor the results of:
Code:
#time du -sh /usr/portage

and if that starts to creep up to one minute, I will create a new portageFile and cp -a over to it in order to defrag again.
Back to top
View user's profile Send private message
frostschutz
Advocate
Advocate


Joined: 22 Feb 2005
Posts: 2977
Location: Germany

PostPosted: Sun Apr 30, 2006 10:17 pm    Post subject: Reply with quote

There's also another thread that does basically the same thing (create a filesystem image file for Portage), only they use SquashFS (compressed read-only filesystem) together with UnionFS (in order to be able to sync), and reduce the size again to about 20MB...

Personally, I just got one whopping big root partition for everything and no problems with fragmentation... and no space issues either, as my old disk broke some time ago and I had to get a new one which was twice as big. :lol:
Back to top
View user's profile Send private message
cgmd
Veteran
Veteran


Joined: 17 Feb 2005
Posts: 1585
Location: Louisiana

PostPosted: Thu Apr 05, 2007 8:44 pm    Post subject: Reply with quote

BitJam wrote...
Quote:

Here are the commands I used. They are slightly different from those in the Wiki article because I used an ext2 filesystem instead of Reiser:
Code:
# time du -sh /usr/portage/
# dd if=/dev/null of=/var/portageFile bs=1M count=0 seek=1024
# mke2fs -b 1024 -N 400000 -m 0 -O "dir_index" -F /var/portageFile
# tune2fs -c 0 -i 0 /var/portageFile
# mv /usr/portage /var/portage.old
# mkdir /usr/portage
# mount -o loop,noatime /var/portageFile /usr/portage
# df -h
# cp -a /var/portage.old/* /usr/portage/
# df -h
# time du -sh /usr/portage/
# time du -sh /var/portage.old/
# time du -sh /usr/portage/


I'm curious as to whether /var/portageFile was created on a separate partition for portage (as per the Wiki article referenced)? If so, what is the partition's file system?

Thanks!
_________________
"Primum non nocere" ---Galen
Back to top
View user's profile Send private message
BitJam
Advocate
Advocate


Joined: 12 Aug 2003
Posts: 2506
Location: Silver City, NM

PostPosted: Thu Apr 05, 2007 9:21 pm    Post subject: Reply with quote

There seems to be a little confusion here. the portageFile is the separate partition. If there was actually a small spare partition on a hard drive then it would be preferable to just make a file system on that physical partition with a small block size. Take a look at this thread for suggestions on how to do that.

The filesystem that my portageFile resides on is ext3 with the standard blocksize. As per the suggestions in the above thread I tried making a portageFile with an xfs filesystem on it but I did not see any significant speed difference. I suspect that the optimal configuration is to give portage its own physical partition of less than 1 Gig using a small block xfs file system. If you don't have a small spare partition available then the portageFile trick can give you a significant speed boost even if it is not optimal.
Back to top
View user's profile Send private message
cgmd
Veteran
Veteran


Joined: 17 Feb 2005
Posts: 1585
Location: Louisiana

PostPosted: Thu Apr 05, 2007 10:56 pm    Post subject: Reply with quote

BitJam...

Thanks for clearing that up, and , also for the link to the other thread...

I have an unused partition on my machine of ~4GB.

I would consider breaking off ~1GB for this purpose and trying it with an xfs file system, as you (and "the link") suggest.
Unfortunately, I have never used an xfs file system... Would you have any tips I can follow to set it up on my partition? :?

Thanks, again!
_________________
"Primum non nocere" ---Galen
Back to top
View user's profile Send private message
BitJam
Advocate
Advocate


Joined: 12 Aug 2003
Posts: 2506
Location: Silver City, NM

PostPosted: Fri Apr 06, 2007 12:16 am    Post subject: Reply with quote

You need to enable xfs support in your kernel. It is in the file systems section. Then you need to emerge xfsprogs.

As I said, I didn't see much improvement when I tried xfs in a portageFile. My recommendation of xfs was based on the results posted in the thread I linked to.
Back to top
View user's profile Send private message
Akkara
Bodhisattva
Bodhisattva


Joined: 28 Mar 2006
Posts: 6702
Location: &akkara

PostPosted: Fri Apr 06, 2007 2:15 am    Post subject: Reply with quote

If you use xfs, there is xfs_fsr which defragments live xfs partitions (it basically loops copying each file to a known-contiguous place, then renaming it back to the original name). I beleive it is part of the sys-fs/xfsdump package.

(Oh - and if you use xfs, be sure you're not running one of the early 2.6.17 kernels - there was a bug that corrupted xfs filesystems on rare occasions.)
Back to top
View user's profile Send private message
cgmd
Veteran
Veteran


Joined: 17 Feb 2005
Posts: 1585
Location: Louisiana

PostPosted: Fri Apr 06, 2007 3:00 am    Post subject: Reply with quote

It's now a done deal! The new xfs partition is mounted to /usr/portage. That, along with moving distfiles elsewhere, has resulted in the fastest emerge --sync and emerge -auDN world, I have ever experienced! I'm amazed!

Thanks to the authors of both posts, above, for their helpful comments.
_________________
"Primum non nocere" ---Galen
Back to top
View user's profile Send private message
Akkara
Bodhisattva
Bodhisattva


Joined: 28 Mar 2006
Posts: 6702
Location: &akkara

PostPosted: Fri Apr 06, 2007 6:05 am    Post subject: Reply with quote

Glad it worked out, cgmd!

Oh, and to answer the original question regarding shell gotos just for completeness:

I don't think bash even has a goto.

Often the easiest way around it is to reverse the sense of the test:
Code:
check_for_emerge=$(pgrep emerge | gawk '{print $1}')
while [ "$check_for_emerge" == "" ]; do
   sleep 60
   check_for_emerge=$(pgrep emerge | gawk '{print $1}')
done
#...stuff to do after "$check_for_emerge" becomes non-empty


A way to avoid long stacking of tail-recursive shell calls is to use exec, which replaces the running process with another.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Portage & Programming All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum