Difference between pages "Awk by Example, Part 3" and "Welcome"

From Funtoo
(Difference between pages)
Jump to navigation Jump to search
 
 
Line 1: Line 1:
{{Article
<div class="container" style="font-family: Open Sans; font-size: 14px; line-height: 20px;"><div class="row"><div class="col-xs-12 col-md-8 col-lg-8">
|Author=Drobbins
{{Slideshow}}
|Previous in Series=Awk by Example, Part 2
</div><div class="col-xs-12 col-md-4 col-lg-4">
}}
'''Funtoo Linux''' is a Linux-based operating system that is a variant of [http://en.wikipedia.org/wiki/Gentoo_Linux Gentoo Linux], led by [[User:Drobbins|Daniel Robbins]] (the creator and former Chief Architect of Gentoo) who serves as benevolent dictator for life (BDFL) of the project. ''Funtoo Linux is optimized for the best possible performance, supporting Intel Core i7, AMD FX Processors, and others.''  [[Subarches|See what we support.]] See [[#Distinctives|Distinctives]], below, for more information about what makes us special.
== String functions and ... checkbooks? ==


=== Formatting output ===
'''Other Funtoo Projects include''':
While awk's print statement does do the job most of the time, sometimes more is needed. For those times, awk offers two good old friends called printf() and sprintf(). Yes, these functions, like so many other awk parts, are identical to their C counterparts. printf() will print a formatted string to stdout, while sprintf() returns a formatted string that can be assigned to a variable. If you're not familiar with printf() and sprintf(), an introductory C text will quickly get you up to speed on these two essential printing functions. You can view the printf() man page by typing "man 3 printf" on your Linux system.
*  '''[[Keychain]]''', an SSH/GPG agent front-end.
* '''[[Metro]]''', automated Funtoo build engine.
* '''[[Linux_Fundamentals,_Part_1|Learn Linux]]'''! [[Awk_by_Example,_Part_1|Awk]], [[Bash_by_Example,_Part_1|Bash]], [[Sed_by_Example,_Part_1|Sed]]  and more.


Here's some sample awk sprintf() and printf() code. As you can see in the following script, everything looks almost identical to C.
<pre>
#!/usr/bin/awk -f
BEGIN {
x=1
b="foo"
printf("%s got a %d on the last test\n","Jim",83)
myout=sprintf("%s-%d",b,x)
print myout
}
</pre>
This code will print:
<pre>
Jim got a 83 on the last test
foo-1
</pre>


=== String functions ===
'''Ebuild pages recently updated:''' {{#ask: [[Category:Ebuilds]]
Awk has a plethora of string functions, and that's a good thing. In awk, you really need string functions, since you can't treat a string as an array of characters as you can in other languages like C, C++, and Python. For example, if you execute the following code:
| order=descending
<pre>
| sort=Modification date
mystring="How are you doing today?"
| format=list
print mystring[3]
| limit=10
</pre>
| searchlabel=
You'll receive an error that looks something like this:
}} [[Ebuilds|more...]]
<pre>
awk: string.gawk:59: fatal: attempt to use scalar as array
</pre>
Oh, well. While not as convenient as Python's sequence types, awk's string functions get the job done. Let's take a look at them.


First, we have the basic length() function, which returns the length of a string. Here's how to use it:
'''Want to submit a screenshot? [http://forums.funtoo.org/index.php?/topic/180-screenshots/ See here.]'''
<pre>
</div></div><div class="row"><div class="col-xs-12">
print length(mystring)
{{Announce|[[Support Funtoo]] and help us grow! '''Donate $15 per month and get a free SSD-based [[Funtoo Hosting|Funtoo Virtual Container]].'''}}
</pre>
</div></div><div class="row"><div class="col-xs-12 col-md-4 col-lg-4">
This code will print the value:
=== News ===
<pre>
{{NewsList|3}}
24
[[News|View More News...]]
</pre>
OK, let's keep going. The next string function is called index, and will return the position of the occurrence of a substring in another string, or it will return 0 if the string isn't found. Using mystring, we can call it this way:
<pre>
print index(mystring,"you")
</pre>
Awk prints:
<pre>
9
</pre>
We move on to two more easy functions, tolower() and toupper(). As you might guess, these functions will return the string with all characters converted to lowercase or uppercase respectively. Notice that tolower() and toupper() return the new string, and don't modify the original. This code:
<pre>
print tolower(mystring)
print toupper(mystring)
print mystring
</pre>
....will produce this output:
<pre>
how are you doing today?
HOW ARE YOU DOING TODAY?
How are you doing today?
</pre>
So far so good, but how exactly do we select a substring or even a single character from a string? That's where substr() comes in. Here's how to call substr():
<pre>
mysub=substr(mystring,startpos,maxlen)
</pre>
mystring should be either a string variable or a literal string from which you'd like to extract a substring. startpos should be set to the starting character position, and maxlen should contain the maximum length of the string you'd like to extract. Notice that I said maximum length; if length(mystring) is shorter than startpos+maxlen, your result will be truncated. substr() won't modify the original string, but returns the substring instead. Here's an example:
<pre>
print substr(mystring,9,3)
</pre>
Awk will print:
<pre>
you
</pre>
If you regularly program in a language that uses array indices to access parts of a string (and who doesn't), make a mental note that substr() is your awk substitute. You'll need to use it to extract single characters and substrings; because awk is a string-based language, you'll be using it often.


Now, we move on to some meatier functions, the first of which is called match(). match() is a lot like index(), except instead of searching for a substring like index() does, it searches for a regular expression. The match() function will return the starting position of the match, or zero if no match is found. In addition, match() will set two variables called RSTART and RLENGTH. RSTART contains the return value (the location of the first match), and RLENGTH specifies its span in characters (or -1 if no match was found). Using RSTART, RLENGTH, substr(), and a small loop, you can easily iterate through every match in your string. Here's an example match() call:
=== Expand the wiki! ===
<pre>
print match(mystring,/you/), RSTART, RLENGTH
</pre>
Awk will print:
<pre>
9 9 3
</pre>


=== String substitution ===
The [[:Help:Funtoo_Editing_Guidelines | How to 'wiki']] will help get you started on wiki editing. Have a look at [[Requested-Documents]] and [[:Category:Needs_Updates | pages that need to be updated.]]
Now, we're going to look at a couple of string substitution functions, sub() and gsub(). These guys differ slightly from the functions we've looked at so far in that they actually modify the original string. Here's a template that shows how to call sub():
<pre>
sub(regexp,replstring,mystring)
</pre>
When you call sub(), it'll find the first sequence of characters in mystring that matches regexp, and it'll replace that sequence with replstring. sub() and gsub() have identical arguments; the only way they differ is that sub() will replace the first regexp match (if any), and gsub() will perform a global replace, swapping out all matches in the string. Here's an example sub() and gsub() call:
<pre>
sub(/o/,"O",mystring)
print mystring
mystring="How are you doing today?"
gsub(/o/,"O",mystring)
print mystring
</pre>
We had to reset mystring to its original value because the first sub() call modified mystring directly. When executed, this code will cause awk to output:
<pre>
HOw are you doing today?
HOw are yOu dOing tOday?
</pre>
Of course, more complex regular expressions are possible. I'll leave it up to you to test out some complicated regexps.


We wrap up our string function coverage by introducing you to a function called split(). split()'s job is to "chop up" a string and place the various parts into an integer-indexed array. Here's an example split() call:
See [[:Category:Ebuilds|Ebuilds]] for a list of all ebuild pages, and [[Adding an Ebuild to the Wiki]] for information on how to add one.
<pre>
</div><div class="col-sm-12 col-xs-12 col-md-4 col-lg-4">
numelements=split("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec",mymonths,",")
=== Distinctives ===
</pre>
When calling split(), the first argument contains the literal string or string variable to be chopped. In the second argument, you should specify the name of the array that split() will stuff the chopped parts into. In the third element, specify the separator that will be used to chop the strings up. When split() returns, it'll return the number of string elements that were split. split() assigns each one to an array index starting with one, so the following code:
<pre>
print mymonths[1],mymonths[numelements]
</pre>
....will print:
<pre>
Jan Dec
</pre>


=== Special string forms ===
Funtoo Linux is a meta-distribution, which means it is built (fully automatically) with the functionality and optimizations that ''you'' want, not what some distro maintainer thought was best for you. Packages are installed directly from source code, thanks to the [http://en.wikipedia.org/wiki/Portage_(software) Portage ports system], inspired by the FreeBSD ports system, written in Python and with full advanced package management functionality.  
A quick note -- when calling length(), sub(), or gsub(), you can drop the last argument and awk will apply the function call to $0 (the entire current line). To print the length of each line in a file, use this awk script:
<pre>
{
    print length()
}
</pre>


=== Financial fun ===
''Benefits for desktops'': leaner, optimized, faster system. ''Additional benefits for servers'': enable only what you actually need to reduce attack surface, thus improving security.
A few weeks ago, I decided to write my own checkbook balancing program in awk. I decided that I'd like to have a simple tab-delimited text file into which I can enter my most recent deposits and withdrawals. The idea was to hand this data to an awk script that would automatically add up all the amounts and tell me my balance. Here's how I decided to record all my transactions into my "ASCII checkbook":
<pre>
23 Aug 2000    food    -    -    Y    Jimmy's Buffet    30.25
</pre>
Every field in this file is separated by one or more tabs. After the date (field 1, $1), there are two fields called "expense category" and "income category". When I'm entering an expense like on the above line, I put a four-letter nickname in the exp field, and a "-" (blank entry) in the inc field. This signifies that this particular item is a "food expense" :) Here's what a deposit looks like:
<pre>
23 Aug 2000    -    inco    -    Y    Boss Man        2001.00
</pre>
In this case, I put a "-" (blank) in the exp category, and put "inco" in the inc category. "inco" is my nickname for generic (paycheck-style) income. Using category nicknames allows me to generate a breakdown of my income and expenditures by category. As far as the rest of the records, all the other fields are fairly self-explanatory. The cleared? field ("Y" or "N") records whether the transaction has been posted to my account; beyond that, there's a transaction description, and a positive dollar amount.


The algorithm used to compute the current balance isn't too hard. Awk simply needs to read in each line, one by one. If an expense category is listed but there is no income category (denoted by "-"), then this item is a debit. If an income category is listed, but no expense category (denoted by "-") is present, then the dollar amount is a credit. And, if there is both an expense and income category listed, then this amount is a "category transfer"; that is, the dollar amount will be subtracted from the expense category and added to the income category. Again, all these categories are virtual, but are very useful for tracking income and expenditures, as well as for budgeting.
We use [http://en.wikipedia.org/wiki/Git_(software) Git] for all our development, and we also use Git to deliver our ports tree to you.


=== The code ===
In contrast to Gentoo Linux, we offer a number of innovations, including our extensive use of git, [[Funtoo 1.0 Profile|our profile system]], [[Package:Boot-Update|boot-update]] boot management tool, our incredibly flexible [[Funtoo Linux Networking|template-based networking scripts]], [[Metro Quick Start Tutorial|Metro]] distribution build system, support of Debian, RHEL and other kernels, [[Creating_Python-related_Ebuilds|enhanced Python support]], Portage mini-manifests, user-centric distribution model, and a large number of community infrastructure improvements.
Time to look at the code. We'll start off with the first line, the BEGIN block and a function definition:
</div><div class="col-sm-12 col-xs-12 col-md-4 col-lg-4">
<pre>
=== Getting Started ===
#!/usr/bin/awk -f
BEGIN {
    FS="\t+"
    months="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
}


function monthdigit(mymonth) {
'''[[Funtoo Linux Installation|Install Funtoo Linux]]''' and get involved in our user community. Get to know fellow users on our '''[http://forums.funtoo.org forums]'''. Funtoo Linux has a very active [http://en.wikipedia.org/wiki/IRC IRC] community on [http://freenode.net Freenode] (in the <code>#funtoo</code> channel) and you are encouraged to hang out with us.
    return (index(months,mymonth)+3)/4
}
</pre>
Adding the first "#!..." line to any awk script will allow it to be directly executed from the shell, provided that you "chmod +x myscript" first. The remaining lines define our BEGIN block, which gets executed before awk starts processing our checkbook file. We set FS (the field separator) to "\t+", which tells awk that the fields will be separated by one or more tabs. In addition, we define a string called months that's used by our monthdigit() function, which appears next.


The last three lines show you how to define your own awk function. The format is simple -- type "function", then the function name, and then the parameters separated by commas, inside parentheses. After this, a "{ }" code block contains the code that you'd like this function to execute. All functions can access global variables (like our months variable). In addition, awk provides a "return" statement that allows the function to return a value, and operates similarly to the "return" found in C, Python, and other languages. This particular function converts a month name in a 3-letter string format into its numeric equivalent. For example, this:
'''[[Reporting Bugs|We welcome bug reports and suggestions]]'''. Please report bugs to our '''[http://bugs.funtoo.org bug tracker]'''. We take all bugs seriously, and all work performed is tracked on our bug tracker, for purposes of transparency.
<pre>
print monthdigit("Mar")
</pre>
....will print this:
<pre>
3
</pre>
Now, let's move on to some more functions.


=== Financial functions ===
'''{{CreateAccount}}''', which allows you to log in to the wiki, [http://forums.funtoo.org forums] and [https://bugs.funtoo.org bug tracker]. See the [[Funtoo Authentication FAQ|Auth FAQ]] for more info about account creation.
Here are three more functions that perform the bookkeeping for us. Our main code block, which we'll see soon, will process each line of the checkbook file sequentially, calling one of these functions so that the appropriate transactions are recorded in an awk array. There are three basic kinds of transactions, credit (doincome), debit (doexpense) and transfer (dotransfer). You'll notice that all three functions accept one argument, called mybalance. mybalance is a placeholder for a two-dimensional array, which we'll pass in as an argument. Up until now, we haven't dealt with two-dimensional arrays; however, as you can see below, the syntax is quite simple. Just separate each dimension with a comma, and you're in business.


We'll record information into "mybalance" as follows. The first dimension of the array ranges from 0 to 12, and specifies the month, or zero for the entire year. Our second dimension is a four-letter category, like "food" or "inco"; this is the actual category we're dealing with. So, to find the entire year's balance for the food category, you'd look in mybalance[0,"food"]. To find June's income, you'd look in mybalance[6,"inco"].
'''See our [[Funtoo Linux FAQ|FAQ]] for answers to common questions.'''
<pre>       
function doincome(mybalance) {
    mybalance[curmonth,$3] += amount
    mybalance[0,$3] += amount       
}


function doexpense(mybalance) {
Other resources include [http://larrythecow.org larrythecow.org], the Gentoo blog aggregator, [http://kernel-seeds.org kernel-seeds.org], and [http://git.funtoo.org git.funtoo.org], our cgit repository browser.
    mybalance[curmonth,$2] -= amount
</div></div></div>
    mybalance[0,$2] -= amount       
}


function dotransfer(mybalance) {
__NOTITLE__
    mybalance[0,$2] -= amount
__NOEDITSECTION__
    mybalance[curmonth,$2] -= amount
{{#subobject:|slideIndex=0|slideCaption=
    mybalance[0,$3] += amount
<h4>h3nnn4n</h4>
    mybalance[curmonth,$3] += amount
}
</pre>
When doincome() or any of the other functions are called, we record the transaction in two places -- mybalance[0,category] and mybalance[curmonth, category], the entire year's category balance and the current month's category balance, respectively. This allows us to easily generate either an annual or monthly breakdown of income/expenditures later on.


If you look at these functions, you'll notice that the array referenced by mybalance is passed in by reference. In addition, we also refer to several global variables: curmonth, which holds the numeric value of the month of the current record, $2 (the expense category), $3 (the income category), and amount ($7, the dollar amount). When doincome() and friends are called, all these variables have already been set correctly for the current record (line) being processed.
Awesome WM / Conky / screenfetch
|slideImage=File:H3nnn4n.jpg}}
{{#subobject:|slideIndex=1|slideCaption=
<h4>Help us document the Gentoo Ecosystem!</h4>
From Enoch to Gentoo to Funtoo to ChromeOS, and beyond...
|slideImage=File:Ecosystem-snapshot.jpg|slideLink=Gentoo Ecosystem}}
{{#subobject:|slideIndex=2|slideCaption=
<h4>brushdemon</h4>


=== The main block ===
OpenBox / screenfetch
Here's the main code block that contains the code that parses each line of input data. Remember, because we have set FS correctly, we can refer to the first field as $1, the second field as $2, etc. When doincome() and friends are called, the functions can access the current values of curmonth, $2, $3 and amount from inside the function. Take a look at the code and meet me on the other side for an explanation.
|slideImage=File:brushdemon.jpg}}
<pre>
{{#subobject:|slideIndex=3|slideCaption=
{
<h4>drobbins</h4>
    curmonth=monthdigit(substr($1,4,3))
    amount=$7
     
    #record all the categories encountered
    if ( $2 != "-" )
        globcat[$2]="yes"
    if ( $3 != "-" )
        globcat[$3]="yes"


    #tally up the transaction properly
[[GNOME First Steps|GNOME 3.14]]  / [[Funtoo_Linux_FAQ#Do_you_support_systemd.3F|without systemd]] / Badgers optional
    if ( $2 == "-" ) {
|slideImage=File:gnome3122.jpg|slideLink=GNOME First Steps}}
        if ( $3 == "-" ) {
            print "Error: inc and exp fields are both blank!"
            exit 1
        } else {
            #this is income
            doincome(balance)
            if ( $5 == "Y" )
                doincome(balance2)
        }
    } else if ( $3 == "-" ) {
        #this is an expense
        doexpense(balance)
        if ( $5 == "Y" )
            doexpense(balance2)
    } else {
        #this is a transfer
        dotransfer(balance)
        if ( $5 == "Y" )
            dotransfer(balance2)
    }                       
}
</pre>
In the main block, the first two lines set curmonth to an integer between 1 and 12, and set amount to field 7 (to make the code easier to understand). Then, we have four interesting lines, where we write values into an array called globcat. globcat, or the global categories array, is used to record all those categories encountered in the file -- "inco", "misc", "food", "util", etc. For example, if $2 == "inco", we set globcat["inco"] to "yes". Later on, we can iterate through our list of categories with a simple "for (x in globcat)" loop.


On the next twenty or so lines, we analyze fields $2 and $3, and record the transaction appropriately. If $2=="-" and $3!="-", we have some income, so we call doincome(). If the situation is reversed, we call doexpense(); and if both $2 and $3 contain categories, we call dotransfer(). Each time, we pass the "balance" array to these functions so that the appropriate data is recorded there.
{{#subobject:|slideIndex=4|slideCaption=
<h4>spectromas</h4>


You'll also notice several lines that say "if ( $5 == "Y" ), record that same transaction in balance2". What exactly are we doing here? You'll recall that $5 contains either a "Y" or a "N", and records whether the transaction has been posted to the account. Because we record the transaction to balance2 only if the transaction has been posted, balance2 will contain the actual account balance, while "balance" will contain all transactions, whether they have been posted or not. You can use balance2 to verify your data entry (since it should match with your current account balance according to your bank), and use "balance" to make sure that you don't overdraw your account (since it will take into account any checks you have written that have not yet been cashed).
[[Package:Awesome_(Window_Manager)|Awesome WM]]
|slideImage=File:awesome.jpg|slideLink=Package:Awesome (Window Manager)}}


=== Generating the report ===
{{#seo:
After the main block repeatedly processes each input record, we now have a fairly comprehensive record of debits and credits broken down by category and by month. Now, all we need to do is define an END block that will generate a report, in this case a modest one:
|title=Funtoo Linux
<pre>
|keywords=funtoo,linux,gentoo,Daniel Robbins
END {
|description=Funtoo Linux is a Gentoo-based OS that uses a git-based Portage tree. Run by Daniel Robbins, creator of Gentoo.
    bal=0
}}
    bal2=0       
    for (x in globcat) {
        bal=bal+balance[0,x]
        bal2=bal2+balance2[0,x]   
    }
    printf("Your available funds: %10.2f\n", bal)
    printf("Your account balance: %10.2f\n", bal2)       
}
</pre>
This report prints out a summary that looks something like this:
<pre>
Your available funds:    1174.22
Your account balance:    2399.33
</pre>
In our END block, we used the "for (x in globcat)" construct to iterate through every category, tallying up a master balance based on all the transactions recorded. We actually tally up two balances, one for available funds, and another for the account balance. To execute the program and process your own financial goodies that you've entered into a file called '''mycheckbook.txt''', put all the above code into a text file called '''balance''' and do <span style="color:green;">"chmod +x balance"</span>, and then type <span style="color:green;">"./balance mycheckbook.txt"</span>. The balance script will then add up all your transactions and print out a two-line balance summary for you.
 
=== Upgrades ===
I use a more advanced version of this program to manage my personal and business finances. My version (which I couldn't include here due to space limitations) prints out a monthly breakdown of income and expenses, including annual totals, net income and a bunch of other stuff. Even better, it outputs the data in HTML format, so that I can view it in a Web browser :) If you find this program useful, I encourage you to add these features to this script. You won't need to configure it to record any additional information; all the information you need is already in balance and balance2. Just upgrade the END block, and you're in business!
 
I hope you've enjoyed this series. For more information on awk, check out the resources listed below.
 
== Resources ==
* Read Daniel's other awk articles on Funtoo: Awk By Example, [[Awk by example, Part1|Part 1]] and [[Awk by example, Part2|Part 2]].
* If you'd like a good old-fashioned book, [http://www.oreilly.com/catalog/sed2/ O'Reilly's sed & awk, 2nd Edition] is a wonderful choice.
* Be sure to check out the [http://www.faqs.org/faqs/computer-lang/awk/faq/ comp.lang.awk FAQ]. It also contains lots of additional awk links.
* Patrick Hartigan's [http://sparky.rice.edu/~hartigan/awk.html awk tutorial] is packed with handy awk scripts.
* [http://www.tasoft.com/tawk.html Thompson's TAWK Compiler] compiles awk scripts into fast binary executables. Versions are available for Windows, OS/2, DOS, and UNIX.
* [http://www.gnu.org/software/gawk/manual/gawk.html The GNU Awk User's Guide] is available for online reference.
 
[[ Category:Linux Core Concepts ]]
[[Category:Articles]]
{{ArticleFooter}}

Revision as of 04:54, January 2, 2015

Funtoo Linux is a Linux-based operating system that is a variant of Gentoo Linux, led by Daniel Robbins (the creator and former Chief Architect of Gentoo) who serves as benevolent dictator for life (BDFL) of the project. Funtoo Linux is optimized for the best possible performance, supporting Intel Core i7, AMD FX Processors, and others. See what we support. See Distinctives, below, for more information about what makes us special.

Other Funtoo Projects include:


Ebuild pages recently updated: {{#ask: | order=descending | sort=Modification date | format=list | limit=10 | searchlabel= }} more...

Want to submit a screenshot? See here.

   {{{title}}}
{{{body}}}

News

Ego-2.2.0 Released

User:Drobbins
2017-10-18 by
Drobbins

Latest Innovations

This news item documents the latest innovations now available under Funtoo Linux.
2017-09-07 by Drobbins
More... View More News...

Expand the wiki!

The How to 'wiki' will help get you started on wiki editing. Have a look at Requested-Documents and pages that need to be updated.

See Ebuilds for a list of all ebuild pages, and Adding an Ebuild to the Wiki for information on how to add one.

Distinctives

Funtoo Linux is a meta-distribution, which means it is built (fully automatically) with the functionality and optimizations that you want, not what some distro maintainer thought was best for you. Packages are installed directly from source code, thanks to the Portage ports system, inspired by the FreeBSD ports system, written in Python and with full advanced package management functionality.

Benefits for desktops: leaner, optimized, faster system. Additional benefits for servers: enable only what you actually need to reduce attack surface, thus improving security.

We use Git for all our development, and we also use Git to deliver our ports tree to you.

In contrast to Gentoo Linux, we offer a number of innovations, including our extensive use of git, our profile system, boot-update boot management tool, our incredibly flexible template-based networking scripts, Metro distribution build system, support of Debian, RHEL and other kernels, enhanced Python support, Portage mini-manifests, user-centric distribution model, and a large number of community infrastructure improvements.

Getting Started

Install Funtoo Linux and get involved in our user community. Get to know fellow users on our forums. Funtoo Linux has a very active IRC community on Freenode (in the #funtoo channel) and you are encouraged to hang out with us.

We welcome bug reports and suggestions. Please report bugs to our bug tracker. We take all bugs seriously, and all work performed is tracked on our bug tracker, for purposes of transparency.

Create a Funtoo account, which allows you to log in to the wiki, forums and bug tracker. See the Auth FAQ for more info about account creation.

See our FAQ for answers to common questions.

Other resources include larrythecow.org, the Gentoo blog aggregator, kernel-seeds.org, and git.funtoo.org, our cgit repository browser.


{{#subobject:|slideIndex=0|slideCaption=

h3nnn4n

Awesome WM / Conky / screenfetch |slideImage=File:H3nnn4n.jpg}} {{#subobject:|slideIndex=1|slideCaption=

Help us document the Gentoo Ecosystem!

From Enoch to Gentoo to Funtoo to ChromeOS, and beyond... |slideImage=File:Ecosystem-snapshot.jpg|slideLink=Gentoo Ecosystem}} {{#subobject:|slideIndex=2|slideCaption=

brushdemon

OpenBox / screenfetch |slideImage=File:brushdemon.jpg}} {{#subobject:|slideIndex=3|slideCaption=

drobbins

GNOME 3.14 / without systemd / Badgers optional |slideImage=File:gnome3122.jpg|slideLink=GNOME First Steps}}

{{#subobject:|slideIndex=4|slideCaption=

spectromas

Awesome WM |slideImage=File:awesome.jpg|slideLink=Package:Awesome (Window Manager)}}

{{#seo: |title=Funtoo Linux |keywords=funtoo,linux,gentoo,Daniel Robbins |description=Funtoo Linux is a Gentoo-based OS that uses a git-based Portage tree. Run by Daniel Robbins, creator of Gentoo. }}