## What is a Console..?

A "console" in UNIX speak (UNIX..? think Linux - best to confuse one concept at a time!) is the text-based interface, as opposed to the graphical interface (the "desktop" in people speak). The console is sometimes referred to as a "tty" (short for teletype, which is graybeard speak - the kind of people who refer to a monitor as a "glass teletype") You can change between consoles and the graphical environment by holding the keys Ctrl + Alt + Fn (eg. Ctrl + Alt + F1 will change to tty1 - the first console). Exactly how many consoles are available, and where the graphical environment is located, depends greatly on which version of UNIX you are running, and how it is configured. More on that later, but feel free to experiment! A console (technically a virtual console) is not the same as a terminal emulator, such as XTerm, which is a program you can run within a graphical environment. Neither is it a shell by the way, a shell like bash for instance runs inside a terminal emulator/virtual console. Confusion reigns supreme however since terminal emulators and virtual consoles are often just called "terminals", "consoles" or "shells" interchangeably (btw, all of them are "cli's" - command line interfaces).

If you feel confused at this point, the following analogy might help: Think of a "shell" as a language, such as English. A "console" as an oldschool office from the 50's, with only basic essentials like a typewriter and a filing cabinet. And a "desktop" as a modern office of plexiglas and shiny chrome, complete with air conditioning, a coffee machine, fancy artwork on the walls, soft ambient background music and what not. It even has some pencils and papers laying around somewhere if people get in a productive mood... Although the office environments are certainly different, and reflect different time periods, in practice the occupants often work on the same things, and of course they all use the same language.

## A Console Desktop? Seriously?

Yes. The text-based environment in UNIX is incredibly versatile and powerful, programmers and system administrators who log into a UNIX server remotely will typically work exclusively in the console, working on a remote desktop (similar to TeamViewer in Windows) is just too inefficient. But can a console really function as an everyday desktop? That is what this article will try to explore, and I think you will be pleasantly surprised at just how useful a text-based environment can be!

Useful you say? Isn't a text based environment like... boring?!? That depends. Learning to use the console certainly requires effort, just as it does to learn any language. But once mastered, you don't think much about it as either boring or fun, instead you focus on the task at hand. An article you read might peak your interest or not, but you wouldn't consider the English language itself as boring would you? Once a language is learned you don't think much about it.

PS: Don't let the term language here scare you. Learning another human language is a huge task, since it consists of tens of thousands of words and painfully convoluted grammar. In contrast if you have learned only a hundred "words" (ie. commands), you are a fluent UNIX speaker, even knowing just a dozen or so is usually enough to get by. Grammar, if at all applicable, is very simple.

Since our goal here is to illustrate day-to-day "desktop" usage, we will not go too much into system administration and programming (although we will have to dip our toes into such matters a little bit). The internet is brimming with articles on these matters, so just Google around if you need some help ;^) The article assumes you are already familiar with basic UNIX commands, and many solutions are provided as shell scripts. If you don't have the skill to read such programs, the following books may be useful additions to your bookshelf:

• The UNIX Programming Environment by Kernighan and Pike
• The AWK Programming Language by Aho, Kernighan and Weinberger
• UNIX Power Tools from O'Reilly
• The Handbook from the FreeBSD project
• The Linux Bible from Wiley
• The Linux Command Line and Shell Scripting Bible from Wiley

Despite not delving deeply into administration and programming however, we will cover much ground and therefore I try to give brief instructions. You are encouraged to read the manpages and relevant documentation yourself to get the finer details. I will start off by discussing how to configure and use the console, and introduce some basic topics. Although necessary, this first section is mindnumbingly boring, so you might want to skip ahead to the fun parts. Before we do any of that though, lets settle some ugly disputes first.

## Holy Wars

WARNING: The following section contains strong language and gratuitous violence to truth, taste and civility. Do not let children or lawyers, nor any people with weak constitution or humor read it. Feel free to send me a complaint if you feel unflamed after reading this section.

You would be surprised how often, given any topic on UNIX, the discussion is derailed at the onset by some newb asking: By the way, what distro should I use? I have heard of this thing called BSD, is that better or worse then Linux? While we are at it, what text editor would you recommend? What browser? What desktop? What programming language? And so forth... Thankfully, we are more or less avoiding that entire GUI angle in this article, so many of these questions can be safely ignored. But the first two will no doubt be asked, so I suppose we'll have to answer them.

### UNIX Wars

Originally, there were two kinds of UNIX, the one created by hippies at the University of California at Berkeley, called BSD (Berkeley Software Distribution), and the one created by evil monsters at AT&T headquarters, called SysV (UNIX System 5). Our distant forefathers from the 80's fought valiantly in the UNIX wars, and many brave men and women lost their arguments in Usenet battles, as the two giants fought for supremacy. Today however, AT&T UNIX is dead. Rumor has it that some remnant babies of this corporate monster still exist in the wild, in the form of AIX, HP-UX, and Solaris, but like I said, it's just a rumor. For all intents and purposes BSD is the only candidate that remains standing, and thus wins by default (apparently some kid in Finland has created his own clone of SysV, but I can't see that going anywhere). Confusingly though, there exists several versions of BSD today. So which is the best? Well... that is a tricky question. But I suppose if we have to pick one, and assuming you aren't into merchandising or fanaticism, the popular choice would be NetBSD. It can run on all the popular platforms, such as i386, and with pkgsrc you can even compile nethack on NetBSD via the net, what more could you want?

But what if you wanted to take this new Finnish hack for a spin, there's about a thousand Linux distros out there, so which one is the right one for you? Well, using logic we can narrow it down to two candidates: If you are one of those people who hate a multitude of distros, then Slackware is clearly the right choice, I mean all the other ones are just upstarts and spinoffs, exactly the kind of thing that you hate, right? On the other hand, if you are one of those people who love a multitude of distros, then LFS is the one for you, that way you can make as many distros as you like. You see, it doesn't have to be so hard if we just put our minds to it.

PS: Realistically BSD is the only candidate here as a day to day driver, but it's fun non the less to fire up a VM and play with Linux every so often. I mean, young folks do have good ideas on occasion.

### Editor Wars

Another source of inflammatory infighting in UNIX, is the choice of text editor. There are too many popular fad editors out there to mention, and they all have nifty little features that lure unsuspecting newbies into their fold. Now, I'm not here to judge. Some people cannot read a book without pictures, and some developers cannot write code without syntax highlighting, I get it. But for the true UNIX hacker there is only one editor, only one that adheres to the UNIX principals, the official one; ed. Like all true UNIX programs ed can take its input arbitrarily from the keyboard, a file or a pipe, and behave consistently in all cases. It can work in a true textual environment, meaning on paper. Try using vi with a lineprinter as your interface! Real programmers do not need visual aids, like some invalid, they see their code in their minds! To learn how to use ed, read the manpage. "It really is that simple", to quote Steve Jobs. If you need more hand holding however, I suggest reading Appendix 1 in The UNIX Programming Environment (1984) by Kernighan and Pike, or read Ed Mastery (2018) by Michael W. Lucas. Once you've got it all down, install bsdgames and run quiz function ed-command for a nice lesson in humility.

Even though the ed manual is an easy read, there are illiterate users, some by necessity, some by choice. Fear not, nano is for you! Start nano. See the ^X Exit at the bottom? It means: Hit Ctrl-X to Exit, I'm sure you can work out the rest yourself.

PS: The BSD editor ee (easy editor) is better, since it's twice as easy to type.

Even though ed is the standard UNIX editor, vi is the popular editor for the masses. No doubt because of it's renowned user-friendliness. It has spawned many forks, the most popular one being vim (vi improved). As the name suggests, vi is a visual editor, so you can actually see what's going on. And the keybindings are mnemonic enough to closely resemble spoken English. The only thing you really need to learn in order to become a vi user, are modes. It works like this: When you start vi it opens the file in normal mode. In this mode you can move around, and do basic bulk editing on the text. Things like d3w (delete three words), yy (yank, just yank - the line) and p (paste) it somewhere. To input text, just a (append) it. To escape input mode you hit Escape of course. See, it's dead simple. Finally, vi lets you run commands that effect the whole file, things like saving and quitting or search and replace. To run one of these commands, type colon in normal mode, and issue your orders. For example, :wq (write'n quit), :q! (quit dammit!), or :%s/good/bad/g (100% of file, substitute good for bad, globally). Using vi is simply a matter of understanding what the keys mean. Small wonder it's so ubiquitous, you just can't beat the simplicity. Here is a cheat sheet to get you started.

PS: The BSD editor nvi (new vi) is better, since it's bug-for-bug compatible with vi(1).

Emacs is best summarized in the following statement: Emacs is an operating system that only lacks a good text editor. There are several forks of Emacs around, but the most popular one by far is GNU Emacs. Essentially Emacs makes this entire article redundant, anything you can to in the console, you can do in Emacs. For example, you can type M-x shell-command (that is Alt-x, then type shell-command) to run any command, like ifconfig or firefox or what have you. To run a full shell session type M-x shell (if you need to run fancy ncurses programs use M-x ansi-term).

Time does not permit me to discuss the eww web browser, gnus news and mail client (or one of the several superior candidates), erc irc client, dired file manager, calendar, ses spreadsheets, calculator, tetris, snake, dunnet text adventure, the psychoanalyzer doctor and other tools and toys that ship with the editor by default. Not to mention the thousands of 3rd party apps that can be installed with its package manager. Such as the emms multimedia system, slime for serious Lisp hacking, and org-mode for serious text hacking. Naturally any kind of file, including PDF's and images can just be opened directly.

All of the above major modes can be started with M-x modename. To open up a file you can type C-x C-f (that is Ctrl-x then Ctrl-f). These modes and files are called "buffers" in Emacs jargon, to open up a non-current buffer type C-x b. Tab-autocomplete works everywhere, so use that for what it's worth. Delete a buffer with C-x k. To quit Emacs, type C-x C-c, and to cancel an action type C-g. Emacs is also a window manager. To split the window vertically in two type C-x 2, to split it horizontally type C-x 3 (these can be arbitrarily split again and again). To close a window type C-x 0, to make a window fullscreen type C-x 1, to switch to another window type C-x o (for "other").

You can even use Emacs as a text editor. It's true! You can start the tutorial with C-h t, to learn how, but I wouldn't recommend it. The one thing Emacs does not come with by default is a decent text editor. Luckily though, you can emulate vi in Emacs. You could use viper mode in vanilla Emacs, but a better solution might be to install the 3rd party package evil. You can do so using the above mentioned package manager, or you can use one of the many user-friendly Emacs distros out there, such as Prelude, Graphene, Emacs starter kit, Spacemacs or DoomEmacs. Wait... package manager... Lisp machine... distros?!? You though I was kidding when I called Emacs an operating system didn't you? (Honestly though, Emacs is an ungainly pile of pants, but it does have one saving grace (Lisp (the ultimate language (for programming)))))))))). Btw, here is a cheat sheet to get you started.

PS: The BSD editor mg (micro gnu emacs) is better, since it's written in a higher level language.

## Basics

### Switching Consoles

As mentioned you normally have multiple virtual consoles available. So if you're waiting for a job to finish in tty1, you can hit Ctrl + Alt + F2 to jump over to tty2. When you want to go back to the first console again, just hit Ctrl + Alt + F1. Most systems will also allow you to scroll back the text with Shift + PgUp and Shift + PgDown, this enables you to go back and read previous output. In the following sections I will talk about how to configure fonts, colors, keyboard layouts and the consoles in general. The method of doing this varies greatly from system to system, so you don't need to read all of the subsections, just the ones that are relevant for you.

### Nvidia

This hardware vendor deserves special mention. Now I know that many a Windows gamer out there loves his Nvidia card like his favorite pet monkey. And sure enough the Nvidia engineers can produce stunning specs, and provide hours of gaming fun like none other, but they cannot write quality software if their life depended on it! Their driver is a bad joke, and an affront to the finer feelings of system administrators everywhere. It is clear that the Nvidia developers have the Windows mindset, where it is perfectly fine, nay expected, to write binary blobs that bloat the system and boldly crash it in ways no one have crashed it before!

If you are using their proprietary driver on any version of UNIX (especially anything besides Linux), then you will likely not be able to switch back and forth between the console and your graphical environment. In fact you often cannot run multiple graphical environments simultaneously either, something that is unheard of in the Windows world, but is a given on UNIX systems. Don't be surprised either if your system suddenly freezes or crashes for no apparent reason whatsoever, it's to be expected. The only way to work around these issues is to use either the reverse engineered open source Nvidia driver, or configure X to use the generic VESA driver. In both cases you will usually have very shabby resolution, both on your desktop and on your console. Using the console with an Nvidia card may cause serious headache, but take a look at the Putting a Console on the Desktop section below for a simple workaround.

As a side note: The OpenBSD developers have embargoed Nvidia on their system. If more operating systems would follow their example, instead of showing their finger in frustration (looking at you Linus Torvalds), Nvidia might just take a hint and clean up their act.

To be fair, other vendors like Intel, have also shown a shocking lack of concern for the quality of their own product. Of course Intel's specialty is multi-processing and virtualization, not graphics, so it's in those areas that they bury their bodies. As far as graphics are concerned, Intel should not give you any problems on the console.

To be extra fair, some have objected to my objections about Nvidia. I find such criticism of my criticism surprising. Not because I might be wrong, but because people have cared enough about my blog to criticize it. I am humbled. Let me stress that I am talking about *console* issues with proprietary Nvidia drivers. Desktop graphics usually work fine. And I am sure many Linux distros handle even these proprietary drivers gracefully on the console. The fact that I have issues does not mean that you have issues. Naturally, anything you read on my blog, or the web, can be obsolete, opinionated and/or dim. Beware.

### Getting to the Desktop again

If you have a graphical desktop already running, getting to it from the console is simply a question of finding out where it is located. If you are unsure just hit Ctrl + Alt + F1, then Ctrl + Alt + F2, and so on all the way up to F12 until you hit it (it is often at F5 or F7, but it varies). Note that while some systems allow you to use the shorthand Alt + Fn, when switching consoles, you need to use the full keybinding sequence Ctrl + Alt + Fn, when switching back and forth between the graphical environment and the text consoles.

You can also start a graphical environment from a console. If no graphical environment is running, just type startx. This will launch the systems default graphical environment, which is often twm, a horribly antiquated window manager (many who see this for the first time do not realize they are running a desktop, they just assume that the computer got broken somehow). You can configure startx to run something else by adding instructions in ~/.xinitrc (that is .xinitrc in your home directory). Here is a short example that sets the keyboard layout to Italian and launches Xfce:

setxkbmap it
exec dbus-launch --exit-with-session startxfce4


PS: Getting the launch instructions right for a modern desktop, such as KDE or GNOME, can be tricky (the above Xfce instructions can also vary from system to system). If you're having problems starting them I suggest you try with a simple window manager first, such as exec openbox, to check that the actual graphical environment (normally the X Window System, sometimes referred to as X11, X.Org, or just "X") is working. If it is, you have probably misconfigured the KDE/GNOME/Xfce launch instructions, and you'll know what to Google for.

If a graphical environment is already running you need to launch your new desktop in a different virtual screen. You can do so like this: startx -- :2, the number here is arbitrary, what matters is that the screen ID number must be unique.

### Configuring the Console on various Systems

#### Multiple Monitors

Multi-Monitor setups is not possible on any UNIX console. That is to say, you can have as many monitors as you like, but they will all show the same screen. Multitasking however is possible, for one, you can configure a number of virtual consoles and switch between them (see also the tmux section below). Secondly, you can have a multi-monitor setup in X, and run a "console-like" desktop, such as dwm.

#### Linux: Generic Instructions

Linux will usually configure a number of consoles by default, 6 consoles and the graphical environment on the seventh seems to be a popular configuration. You can configure an arbitrary number of consoles on Linux, see the next sections for further details. You can also use the short hand Alt + Fn and Alt + Arrow-Key to change consoles.

You can set keyboard layout with loadkeys, such as loadkeys dvorak.map. The keyboard maps are often located in /usr/share/keymaps or /usr/share/kbd/keymaps (PS: This approach should also work on systemd distros, but did not work for me on Debian. You could try dpkg-reconfigure keyboard-configuration instead (naturally that will only work on Debian-like distros)). You can change fonts with setfont, such as setfont -v Uni3-Terminus12x6, the console fonts are usually located in /usr/share/consolefonts or /usr/share/kbd/consolefonts.

The Linux console supports multiple colors and you can use echo to send control sequences to manipulate the console color settings. Adding this to the end of ~/.profile will make your console use the Solarized color theme:

# solarize the tty
if [ "$TERM" = "linux" ]; then echo -en "\e]P0073642" #black echo -en "\e]P1dc322f" #darkgray echo -en "\e]P2859900" #darkred echo -en "\e]P3b58900" #red echo -en "\e]P4268bd2" #darkgreen echo -en "\e]P5d33682" #green echo -en "\e]P62aa198" #brown echo -en "\e]P7eee8d5" #yellow echo -en "\e]P8002b36" #darkblue echo -en "\e]P9cb4b16" #blue echo -en "\e]PA586e75" #darkmagenta echo -en "\e]PB657b83" #magenta echo -en "\e]PC839496" #darkcyan echo -en "\e]PD6c71c4" #cyan echo -en "\e]PE93a1a1" #lightgray echo -en "\e]PFfdf6e3" #white clear #for background artifacting fi  #### Linux Framebuffer Not only can the Linux console display any number of colors, but it is also capable of displaying real graphics. It can do so using the framebuffer device. In order to use it you must first make sure your user has permission to access /dev/fb0 and the files under /dev/input. This usually means you need to add your user to the groups video and input, you can do so by running this command: usermod -a -G video,input <myuser>. You also need to install the fbdev driver, if it isn't already included. The method of doing so varies from distro to distro. For instance on Slackware you can install it like so: installpkg /mnt/cdrom/extra/xf86-video/*.txz, and on Debian: apt install xserver-xorg-video-fbdev fbset gpm. Look up your distros documentation. Two examples of programs you can use on the Linux framebuffer is fbterm and fbi. The fbterm terminal can use any fonts available under the graphical environment, which easily enables you to have support for exotic languages like Arabic or Chinese. In combination with the image viewer fbi, you can also set a terminal wallpaper (Ps: You cannot launch another framebuffer program from within fbterm, you need to do that from a regular text console). #!/bin/sh # fbtermbg - start fbterm with wallpaper # usage: fbtermbg wallpaper # depend: fbi (sleep 1; cat /dev/fb0 > /tmp/wallpaper.fbimg) & fbi -t 2 -1 --noverbose -a$1
export FBTERM_BACKGROUND_IMAGE=1
cat /tmp/wallpaper.fbimg > /dev/fb0
fbterm


Some framebuffer programs will hijack your screen, so that you cannot switch to other consoles or the graphical environment. Don't panic! Everything should return to normal once you have quit the program (Ps: If your console is all garbled after you have quit a framebuffer program, the reset command should fix it).

#### Non-Systemd Linux

Legacy Linux systems, and a few modern exceptions, such as Slackware, Gentoo and CRUX, do not use systemd.

You can change virtual console settings in /etc/inittab. To add an eighth tty in Slackware, add this line to /etc/inittab:

c8:12345:respawn:/sbin/agetty 38400 tty8 linux


This takes effect after a reboot. In non-systemd Linux you can also switch to tty13-24 with AltGr + Fn.

Slackware boots in a text based environment by default, to change this to a graphical login, change the line: id:3:initdefault to id:4:initdefault in /etc/inittab. On non-systemd Linux runlevel 3 is text mode login, whereas runlevel 4 is graphical login. The process described here should be fairly similar to any Linux distribution that doesn't use systemd.

#### Systemd Linux

Most modern Linux systems, including Debian, Red Hat, SUSE, Arch, and quite a few others, use the systemd meta system daemon.

To change the number of consoles, to say 12, in Debian, uncomment NAutoVTs in /etc/systemd/logind.conf and set it to NAutoVTs=12. This will take effect after a reboot. On Linux systems with systemd, you can switch between the tty13-24 with Shift + Alt + Fn.

To configure Debian to boot into text mode instead of a graphical login, do this: systemctl set-default multi-user.target, to switch back to graphical login: systemctl set-default graphical.target. The process described in this section should be fairly similar to any Linux distribution that uses systemd.

#### Non-Linux Systems: A Reminder

Linux users often take a lot for granted, they tend to get horrified when discovering that a different UNIX system doesn't have some functionality they have gotten used to, or even if they just do things differently (they may even shout "this isn't UNIX!!!" without realizing the irony - it's usually Linux that's doing things in a non-UNIX'y fashion). So if you're planning to use a BSD system or some other UNIX variety, and have a Linux background, keep an open mind and be prepared to adjust your expectations!

When it comes to the console, non-Linux systems will not support graphics on the framebuffer, nor support exotic UTF-8 characters (ei. English only), and color and font support is often very limited. In fact many ncurses applications may not work well on non-Linux consoles. Some systems also restrict how many consoles you are allowed to have. If you think this all sounds horribly limiting, you probably haven't spent your youth writing PDP-11 assembly in V6 using ed. (all of these restrictions can be easily overcome though by simply running terminal emulators in a graphical desktop). Lastly, keybindings might be a little different, although Ctrl + Alt + Fn will always work.

Despite these restrictions, you can still do neat things on any UNIX console with a little know-how. The above mentioned trick to make a Solarized console theme in Linux will not work on most UNIX consoles since they don't support 256 colors, but virtually all of them have 8 color ANSI support, so you can do some basic color tweaking. Here is a simple and portable script that can set a few basic tty color schemes (unlike the Linux trick though, the themes are not preserved if you run a terminal application with colors, such as vim or less, so a better solution is to configure your system to use the colors you want - more on that later):

#!/bin/sh
# ttycolor - choose tty colors
# usage: ttycolor theme
# bugs:  not persistent across colorful tty apps
#
# explanation:
# printf '\e[1m'  - turn on boldface (or "light" color)
# printf '\e[0m'  - turn off boldface (or "dark" color)
# printf '\e[4nm' - specify background color ("boldface" has no effect)
# printf '\e[3nm' - specify foreground color, where n is:
# 0 = black 2 = green   4 = blue    6 = cyan
# 1 = red   3 = yellow  5 = magenta 7 = white

usage(){
echo 'Usage: ttycolor (geek|tron|minoca|sun|obsd|nuke|default)' >&2
exit 1
}
if [ ! $# = 1 ]; then usage fi # set tty colors case$1 in
geek)    printf '\e[0m\e[32m\e[40m' ;;    # green on black
tron)    printf '\e[1m\e[36m\e[40m' ;;    # cyan on black
minoca)  printf '\e[1m\e[33m\e[42m' ;;    # yellow on green
sun)     printf '\e[0m\e[30m\e[47m' ;;    # black on white
obsd)    printf '\e[1m\e[37m\e[44m' ;;    # white on blue
nuke)    printf '\e[1m\e[33m\e[41m' ;;    # yellow on red
default) printf '\e[0m\e[37m\e[40m' ;;    # white on black
*)       usage ;;
esac
clear


#### FreeBSD and DragonFly BSD

FreeBSD has 8 virtual consoles configured and the graphical interface on the ninth by default. Modern versions of FreeBSD use the vt(4) console driver. It allows you to configure up to 16 consoles, and switch to tty13-16 with Shift + Alt + F1 ... F4. You can also use the Alt + Fn shortcut, but not the arrow keys. To scroll backwards and read previous output hit Scroll Lock, and then use Page Up and Page Down, hit Scroll Lock again when you are done. To configure more than 8 consoles edit /etc/ttys, for instance this line: ttyv9 "/usr/libexec/getty Pc" xterm on secure will enable a ninth console. To enable all 16 consoles use ttyva ... ttyvf, not ttyv10 ... ttyv15. You can tweak other console settings by adding options to /etc/rc.conf. For instance, these lines:

moused_enable="YES"
allscreens_flags="-f 8x8 /usr/share/vt/fonts/terminus-b32.fnt green"
keymap="us.dvorak.kbd"
kld_list="i915kms"


will enable the console mouse, use large green terminus fonts and the dvorak keyboard layout. Lastly it will load the Intel graphics firmware, you need to have the drm-kmod package installed for this to work (if you are using Nvidia or Radeon you need to change this line accordingly). You can interactively select a console font with vidfont, or use the vidcontrol command to adjust all of the above settings.

Even with 16 ttys configured in /etc/ttys, FreeBSD limits you to a maximum of 12 consoles by default, to add up to 16, you need to tweak the kernel a bit:

# cd /usr/src/sys/$(uname -m)/conf # cp GENERIC MYKERN # sed -i '' 's/GENERIC/MYKERN/' MYKERN # echo options VT_MAXWINDOWS=16 >> MYKERN # cd /usr/src # make buildkernel KERNCONF=MYKERN # make installkernel KERNCONF=MYKERN # shutdown -r now  DragonFly BSD uses the old sc(4) console driver from FreeBSD, but otherwise the setup is exactly the same. By the way, you don't need to tweak the kernel in order to enable all 16 consoles, like you do in FreeBSD (PS: the sc driver might have problems switching between the graphical environment and consoles). PS: BSD systems write kernel messages to the first console. This can be quite annoying if you happen to be working on other things there, so work on any console except the first one to avoid much consternation. #### OpenBSD OpenBSD uses the wscons(4) console driver. It requires you to switch between consoles using Ctrl + Alt + Fn, you cannot use the shorthand Alt + Fn. This is a design choice, made to avoid keybinding conflicts. Also there is no way to physically switch beyond 12 consoles. In OpenBSD you have four consoles enabled by default, with the fifth tty being reserved for the graphical environment. Adding more consoles is done in /etc/ttys: ttyC7 "/usr/libexec/getty std.9600" pccon0 on secure  Oh, by the way, once your editing /etc/ttys, change the vt220 option for your active consoles to pccon0. vt220 is a ultra-conservative safe choice, but pccon0 has more modern capabilities, such as unicode, colors and curses. The 11th and 12th console must be ttyCa/ttyCb, not ttyC10/ttyC11. Rebooting will not activate your new consoles however, you need to "create" them first. Doing so manually is a bit tedious, instead we can recompile the kernel with some new settings: # cd /usr/src/sys/arch/$(uname -m)/conf
# cp GENERIC.MP CUSTOM


(Assuming you are running a multi-processor kernel, if not copy GENERIC) Now open up CUSTOM in an editor and add the following lines:

option WS_KERNEL_FG=WSCOL_WHITE
option WS_KERNEL_BG=WSCOL_BLACK
option WS_DEFAULT_FG=WSCOL_GREEN
option WS_DEFAULT_BG=WSCOL_BLACK
option FONT_BOLD8x16


These settings will result in kernel messages being written in a white font, and normal text in green. We also changed the font to a smaller type, fitting more text onto our screen (you'll find a list of available fonts in /usr/src/sys/dev/wsfont/wsfont.c, if you have installed sources). Finally change the WSDISPLAY_DEFAULTSCREEN=6 to WSDISPLAY_DEFAULTSCREEN=12 in GENERIC (regardless of whether you are running a multi-processing kernel or not). Now that the customization's are done, we can recompile the kernel:

# config CUSTOM
# cd ../compile/CUSTOM
# make clean
# make
# make install
# shutdown -r now


PS: X is big, bloated and old, it is a mayor security risk! The OpenBSD developers are somewhat conscientious about security. They have therefore reconfigured X to run in user mode, denying it any direct access to the system. This is great for security, but a consequence of doing so is that you cannot run more than one graphical environment at a time. You can use Xephyr or Xnest to nest X instances inside each other though (eg. (Xephyr :2 -screen 1920x1080 &); sleep 1; DISPLAY=:2 openbox). Also the normal way of starting X in OpenBSD from the console is not with startx, but rather doas xenodm, which starts the xdm-like login manager. Finally, as mentioned OpenBSD does not support Nvidia cards. Graphics may still "work" on such cards, but you will only get generic VESA output with poor resolution.

PS: OpenBSD, like all BSD systems, write kernel messages to the first console. So it's a good idea to work on a different console to avoid interruptions.

#### NetBSD

NetBSD also uses the wscons(4) console driver, like OpenBSD. It requires you to switch between consoles using Ctrl + Alt + Fn, you cannot use the shorthand Alt + Fn. There is no way to physically switch beyond 12 consoles.

Configuring the NetBSD console is fairly similar to OpenBSD. Add new consoles to /etc/ttys, for instance:

ttyE7 "/usr/libexec/getty Pc" wsvt25 on secure


NetBSD also has four consoles by default and uses the fifth as the graphical interface, We can change some of the kernel defaults and recompile like so:

# cd /usr/src/sys/arch/$(uname -m)/conf # cp GENERIC CUSTOM # vi CUSTOM  Now change WS_KERNEL_FG=WSCOL_GREEN to WS_KERNEL_FG=WHITE, and add WS_DEFAULT_FG=WSCOL_GREEN. Uncomment WSDISPLAY_DEFAULTSCREENS=4 and change it to WSDISPLAY_DEFAULTSCREENS=8, and add FONT_DEJAVU_SANS_MONO12x22 (you'll find a list of available fonts in /usr/src/sys/dev/wsfont/wsfont.c, if you have installed sources). Then recompile the kernel with these changes: # config CUSTOM # cd ../compile/CUSTOM # make depend # make # mv /netbsd /netbsd.old # mv netbsd / # shutdown -r now  By default the NetBSD kernel only allows you to have a maximum of 8 consoles. Enabling more than that would require some serious kernel hacking, I recommend using tmux instead. PS: NetBSD, like all BSD systems, write kernel messages to the first console. So it's a good idea to work on a different console to avoid interruptions. #### Solaris and Illumos Oddly enough virtual consoles have traditionally not been available in Solaris, and it does not come enabled by default in newer versions, such as OpenIndiana,* either. To add six consoles in OpenIndiana for instance, you need to run: # svcadm enable vtdaemon # for i in 2 3 4 5 6; do > svcadm enable console-login:vt$i
> done
# svccfg -s vtdaemon setprop options/secure=false
# svccfg -s vtdaemon setprop options/hotkeys=true


By default you are only allowed to activate a maximum of 6 consoles. Like Linux you can change between consoles using the Alt + Fn for ttys 1-12, and AltGr + Fn for ttys 13-24, or you can use the Alt + Arrow-Key shortcuts. To get back to the desktop hit Ctrl + Alt + F7. Not all graphical drivers will allow you to switch between console and desktop however. On one of my test machines I had to disable the graphical environment with svcadm disable lightdm and do a cold reboot. From the console I could then enable the desktop again with svcadm enable lightdm, but to get to the console again I would have to do another disable and reboot.

I was able to work around these problems by configuring X to use the generic VESA driver, but naturally this meant that I had a very poor screen resolution. Hopefully your graphic driver will be more cooperative. If not it might be better to ignore the tty consoles altogether and use terminal emulators in a graphical desktop instead. But if you really want to use the VESA graphics driver you can do so by adding this file in /etc/X11/xorg.conf.d/vesa.conf:

Section "Device"
Identifier "Card0"
Driver "vesa"
EndSection


The only way I have managed to add more then 6 consoles in OpenIndiana is the following hackish method: edit /lib/svc/manifest/system/console-login.xml as root, find the <instance name='vt6' enabled='false'> line and copy this until the trailing </instance>. Edit the copy so that it reads vt8 and /dev/vt/8, instead of vt6 and /dev/vt/6, in the three places that these values are mentioned. You can now repeat this process for vt's 9-15. Reboot and run the above svcadm commands for vt's 9-15 and you now have 14 consoles (vt7 is still reserved for the desktop). If you want more then 14 consoles you need to make more device files in /dev/vt first.

Setting the console keyboard layout, to say French, is done with kbd -s French. To choose a language interactively just type kbd -s. In theory, running this command as root should change the default console keyboard layout permanently, but due to a bug in the version of OpenIndiana I tested this on, it got reset to US qwerty on every reboot. I have yet to figure out how to adjust fonts and default colors in the Solaris console, or use the mouse and scrollback buffer (I suspect this doesn't work on all hardware).

It's somewhat of a digression, but another painful issue with Solaris systems is the lack of software. For virtually all Linux and BSD variants, most of the software mentioned in this article can just be installed with the package manager, but Solaris and Illumos repositories are much thinner. Besides manually compiling the things you need by hand (it's worse then it sounds), a nice workaround here is to install the NetBSD ports collection, called pkgsrc. It is designed to work across multiple operating systems, including Solaris. Of course, not everything will work out of the box, but it does help:

# get and bootstrap pkgsrc
$cd /usr$ wget ftp://ftp.NetBSD.org/pub/pkgsrc/pkgsrc-2021Q2/pkgsrc.tar.gz
$tar xzf pkgsrc.tar.gz$ cd pkgsrc/bootstrap
$env CFLAGS=-O2 CC=/usr/bin/gcc ./bootstrap$ export PATH=/usr/pkg/bin:$PATH # install a game and have some fun$ echo 'ACCEPTABLE_LICENSES+= nethack-license' >> /usr/pkg/etc/mk.conf'
$cd ../games/nethack$ bmake install clean    # outside of NetBSD pkgsrc uses "bmake"
$nethack  The procedure is much the same for whatever OS you want to use pkgsrc on. You can find some specific Solaris pointers here, although these instructions are for Solaris 9 and 10, and thus do not reflect Illumos systems perfectly. ### Getting Organized The process, nay the art, of getting organized is a complex and abstract topic. We will not even try to present a self-help-book-like theory of how to do this! (there are plenty of those on Amazon if you are into that sort of thing) What we will do is show you the tools you need, and leave it as an exercise for you, dear reader, to figure out what to do with them (one of the "benefits" of using the console is that you actually have to get organized). You are probably familiar with basic tools such as ls, cd, mkdir, rm, ln, pwd and so on. The problem with organizing yourself on the command line though, is that your files are largely out of view. Out of sight, out of mind, as they say. You can quickly check what the filesystem looks like with the tree command (if there is to much output try tree -L 1 or -L 2). Another fantastic tool to quickly get an overview of your files, including their contents, is the file manager ranger (alternatively mc). On the other hand, if you just need to figure out what's taking so much space on your harddrive try ncdu, or simply du -hs * | sort -h. Sometimes though you don't need to get a general overview, but find a specific file that you have lost. The quickest way to do this is locate myfile. But the locate command has a weakness, it relies on a database that needs to be updated manually (read the man page for the specifics). If the database is out of date, it may not contain the file your looking for (tip: update the locate database periodically with a cron job). Worse, you may not remember the exact name, only certain details, such as general filesize and when you last worked on it. find is your friend! This command can do some impressive file searching, here are some examples: Search for a directory named exactly MyDiR somewhere under /some/path: $ find /some/path -type d -name MyDiR


Search for a PDF file somewhere under the current directory that is more then 10 Megabytes in size but less then 100:

$find . -iname *.pdf -size +10M -size -100M  Case insensitive search for a file called myfile somewhere under the current directory, modified within the last 10 days and belonging to the www group: $ find . -type f -iname myfile -group www -mtime -10


Last but not least, don't forget the invaluable grep command. With it you can recursively search for any file containing a certain text, eg:

$grep -R "UNIX is awesome" /some/path  ### Multitasking: Jobs A terminal can run multiple programs at once. You have probably launched programs in the background before with command &. What you may not realize is that you can easily switch programs from the background to the foreground arbitrarily. To demonstrate: Type sleep 60 & and hit Enter, three times, now run jobs, and you will see these three background processes listed. Put job number 2 to the foreground with fg 2. Your console is now unresponsive; it is busy sleeping. Hit Ctrl + z and you will suspend the process to the background again. Run jobs and notice that job nr 2 doesn't have a & sign, it is currently paused. You can continue the process in the background with bg 2. Of course, managing multiple jobs in this way is tedious. Some times however you might find that you need to freeze the program you are currently running, and do something real quick. Well that's easy, hit Ctrl + z, do your thing, and run fg when your done. Presto! Your program resumes like nothing happened. ### Multitasking: Tmux For serious multitasking on the console you need terminal multiplexers. Think of a multiplexer as a window manager for the terminal. There are many alternatives, but we will focus on tmux (The classic multiplexer screen has similar capabilities, while dvtm focuses more on window tiling). To quickly demonstrate some of it's abilities do the following: Fire up tmux and hit Ctrl + b and then c. At the bottom line you will now see 0:bash- 1:bash*. This means that there are two bash programs running, you are now seeing the program with an asterix, 1:bash*. You can change back to 0:bash by hitting Ctrl + b and then 0, and then back to 1:bash again with Ctrl + b and then 1. But tmux can do more... Hit Ctrl + b and then %, and you will see the screen split vertically. Hit Ctrl + b and then ", and it will split horizontally. You can navigate between these window frames by hitting Ctrl + b and then one of the Arrow keys. To resize the frames, do the same, but keep holding down Ctrl as you use the Arrow keys. If you hit Ctrl + b and then d, tmux will quit. But you haven't just exited the program, tmux is detached. If you run ps -ely | grep tmux, you will see that it is still running. You can connect to this tmux session again by running the command tmux attach. This functionality is invaluable when working remotely on a server. If the internet connection is broken when you had tmux running, just log in again and run tmux attach, and you can continue where you left off. Naturally you can have many tmux sessions running in the background, use tmux ls to list them. There is an absurd amount of things you can do with this program. Check the tmux manpage for the gory details. You can also check the available key-bindings with Ctrl + b and then ? (the notation here can be a bit confusing though: bind-key is usually set to Ctrl + b, so bind-key -T prefix d detach-client just means "hit Ctrl + b and then d to detach-client"). PS: depending on your system, tmux is often smart enough to understand mouse gestures, such as clicking on the window you want, or click and drag to resize it, after hitting the initial Ctrl + b key combo. ### Copy Pasting: The Console Mouse The console mouse in Linux is gpm. Many distros will have this daemon enabled by default, or at least will enable it if you install gpm. In Slackware you can start the console mouse with: chmod +x /etc/rc.d/rc.gpm and then /etc/rc.d/rc.gpm start. On systemd distros you can enable it with systemctl gpm.service start. When gpm is running you should be able to see a square jump across the screen when you move your mouse, this is the mouse "pointer." Copy pasting with gpm is straight forward. Left click and drag to mark text, any marked text is automatically copied to the gpm clipboard. You can paste it by middle clicking (if you don't have a middle mouse button click both buttons simultaneously). Why the middle mouse button?!? Actually this is the standard UNIX behavior, go ahead and try it on your desktop! The inefficient, left click + copy + left click + paste method, stems from Windows. Pasting text straight to the command prompt is not that practical however, and opening up a text editor will clear the clipboard! So how do we copy something and save it to a file? Simple: run cat << eof > myfile and hit Enter. Now copy paste what you want, when you're finished write eof and hit Enter. The text is now saved in myfile. If you find this solution confusing, I recommend reading up on shell redirection. Ps: BSD systems use moused as their console mouse, but it works just the same as gpm (Solaris systems don't have a console mouse AFAIK). ### Copy Pasting: tmux tmux also works great for copy pasting text, especially since you can run windows side by side and copy paste between them. But learning the keybindings will take a bit of practice. First hit Ctrl + b and then [ (ei. open bracket) to enter copy mode, in this mode you can move the cursor around freely. Navigate to the start of the text you want to copy and hit Ctrl + Space, then navigate to the end of the text (the section you want should now be highlighted) and hit Alt + w. The text is now copied to the tmux clipboard. You can paste it any time with Ctrl + b and then ] (ei. close bracket). You can manipulate the clipboard in many useful ways, read the documentation for further details. If the above keybindings seemed weird, you're probably not too familiar with emacs. By default tmux uses the emacs style keybindings in copy mode. You can use vi style instead if you want, just add set-option -g mode-keys vi to ~/.tmux.conf. You can now copy-paste by hitting Ctrl + b and then [ to enter copy mode. Start marked text with Space, end it with Enter. Finally paste it with Ctrl + b and then ]. ### Sysadmin Now, I know I promised that I wouldn't talk much about system administration. But if you are going to use the console as a desktop, you still need to know how do do some basic things, like shutting down the system and so on. In the following paragraphs we will therefore consider some basic sysadmin topics. There sections are quite verbose since we are dealing with multiple operating systems, but again, you only need to read whatever is relevant for your setup. ### Shutting Down There are various ways to shut down a computer, many systems have halt and reboot for instance. These commands are often just aliases for the shutdown command, which is extremely ubiquitous (even Windows has it for crying out loud!). But it seems like every incarnation of this command behaves a little differently: Shutting down (now!) on various systems: • Linux: shutdown -h now • FreeBSD and DragonFly: shutdown -p now • OpenBSD and NetBSD: shutdown -hp now • Solaris and Illumos: shutdown -y -g 0 -i 5 • Windows and DOS: shutdown /s /t 0 Restarting (now!) on various system: • Linux and BSD's: shutdown -r now • Solaris and Illumos: shutdown -y -g 0 -i 6 • Windows and DOS: shutdown /r /t 0 ### Monitoring One of the popular command line thrills, is to watch colorful streaming text, of presumably important information. The granddaddy monitoring application, is of course top. Which is the closest thing you will come to a taskmanager for the terminal (there is also the slightly more hip variant, htop). This ubiquitous tool can also run in batch mode, which is useful if you need a free command on non-Linux systems: top -b | grep Mem. The BSD's ship with a very nice system monitoring app in addition, called systat. There are many other monitoring apps available, glances is one example, but feel free to search your repository for "top" or "mon" to discover more. Personally I don't find these programs all that useful, but they are handy when you want to make a cool screenshot of your terminal, or if you need to pretend that you are doing something important at work ;^) ### Disk Management To check overall disk usage run the df -h command. You can also check how much space a directory uses with du -hs mydir, or recursively check how much space each file in this directory uses with du -ha mydir. You can quickly check what disks are mounted on your system with mount | column -t, or by checking the systems disk configuration file /etc/fstab. Note that disks are handled very differently on UNIX then on Windows. In Windows each disk is its own top level directory beginning with its drive letter, such as C:\. In UNIX a disk is represented as a file in /dev and is usually called something like sda, and in contrast to Windows it can be mounted anywhere on the filesystem. For example a common configuration is to put the root filesystem, /, on a fast but small SSD harddisk, and have the home partition, /home, on a slower but bigger harddisk. Or to have partitions that change files rapidly, like /tmp or /var, on faster harddisks. Another very useful configuration is to place /tmp directly in memory, we will talk more about that later. The point is that you can arrange the disks anywhere you want in the filetree, and with new filesystems like ZFS, UNIX systems allow for even greater flexibility! We cannot go into the finer details of every UNIX filesystem, but as an example, lets repartition and reformat a USB memory stick with the ultra archaic and portable DOS filesystem, and mount it: #### Linux After attaching the USB stick to your computer, you can run the dmesg | tail command to see if your system has detected it. You should be able to see something similar to this line towards the end: [ 4198.053323] sd 8:0:0:0: [sdd] Attached SCSI removable disk  Don't worry to much about the details here, what's important is that the kernel detected a removable disk and called it sdd. Armed with this knowledge we can now reformat our disk: # fdisk /dev/sdd > p # Print a list of partitions that are on the disk > d # Delete the partition(s) > n # Create a new partition (just go with the defaults) > t # Change the partition type to b - W95 FAT32 > p # List partitions and verify that everything looks correct > w # Write changes to disk > q # Quit fdisk  There are more user friendly alternatives to fdisk such as cfdisk, but the classic fdisk command is easy enough once you have used it a couple of times. Even though we have now created a new partition table on our memory stick, we haven't actually created a filesystem on it yet. Assuming the memory stick has only one partition, we can create a fat filesystem like so: mkfs.vfat /dev/sdd1 Now that our memory stick has a freshly reformatted filesystem, how do we use it? Well we need to mount it somewhere on the filesystem. For instance if you run the command mount /dev/sdd1 /home/myuser/Documents, you can access the memory stick from this directory. Of course that's a rather daft place to put it since you then cannot access your documents. So lets place it somewhere else (don't worry, your documents will pop back once we unmount the memory stick): # umount /home/myuser/Documents # mkdir -p /mnt/usb # mount /dev/sdd1 /mnt/usb  And safely remove it by: # umount /mnt/usb && eject /dev/sdd1  #### BSD You can check what the usb stick is called with the dmesg | tail command, or just by logging into tty1 and see what the kernel has written there. On FreeBSD/DragonFly the device will be called something like da0 and the first partition is da0s1. On OpenBSD and NetBSD the device will be called something like sd0, and you can check what the partitions are called with disklabel sd0. The fdisk command is slightly different on all the BSD versions, so read the man page before using it. On FreeBSD/DragonFly and NetBSD you can run fdisk -u <diskname>, and an interactive process will guide you through the partitioning (make sure you choose file type 11 on your FAT partition). In OpenBSD run fdisk -e <diskname> to edit the partition, use file type 0b for your FAT partition. When all that is done you can use newfs_msdos <diskpart> to create a new FAT 32 filesystem on it (on FreeBSD/DragonFly <diskpart> might be da0s1, on OpenBSD/NetBSD it might be sd0i - check with disklabel). On FreeBSD/DragonFly mount and safely remove it like so: # mkdir -p /mnt/usb # mount -t msdosfs /dev/da0s1 /mnt/usb # umount /mnt/usb # sync  On OpenBSD/NetBSD mount and safely remove it like so: # mkdir -p /mnt/usb # mount /dev/sd0i /mnt/usb # umount /mnt/usb # eject /dev/sd0i  #### Solaris and Illumos After you have inserted the USB stick, you can look for its device name with the rmformat command. It should produce an output similar to this: Looking for devices... 1. Logical Node: /dev/rdsk/c0t0d0p0 ... Connected Device: USB DISK 2.0 1219 ...  You can now edit the partition table of the disk with fdisk /dev/rdsk/c0t0d0p0. The Illumos/Solaris fdisk program is similar to cfdisk on Linux and is straight forward to use. Just make sure you create a D partition type and specify its size as 100 (assuming you want a single FAT 32 partition on the usb stick). Finally create a FAT 32 filesystem on this partition with: mkfs -F pcfs -o fat=32 /dev/rdsk/c0t0d0p0:c. The memory stick should automatically be mounted under /media, but you can manually mount it to a different location if you want: # umount /media/<usbname> # mkdir -p /mnt/usb # mount -F pcfs /dev/dsk/c0t0d0p0:c /mnt/usb  And safely remove it by: # umount /mnt/usb && eject /dev/dsk/c0t0d0p0  PS: The raw disk devices in Illumos/Solaris is under /dev/rdsk. It's this device you use when formatting a disk. When mounting a disk however you use the block device under /dev/dsk. #### Alternatives to FAT The archaic FAT filesystem from MS-DOS is awkward to use under the best of circumstances. It cannot store any files larger than 4 Gb, and even worse it has no concept of UNIX file permissions, these vital security settings will be wiped when you copy them over to a FAT memory stick. You can work around the permission problem by bundling your files into a tar archive, but it's a bit awkward. So why are people still using this rusty old filesystem, aren't there any better alternatives?!? Well, yes and no. A popular choice is the newer Windows filesystem NTFS since it can store files larger than 4 Gb. Of course it too has no concept of UNIX file permissions, so for UNIX users this isn't a good alternative (And even though Linux can use this filesystem, there is considerably less support in the UNIX world for NTFS then FAT). Why not just use a native UNIX filesystem on the memory stick? You can, and in many ways, it is much simpler. Tools such as mount and newfs for instance will assume a native filesystem by default. And of course you can store large files on it, and keep your permission settings. But there is a catch! Native UNIX filesystems have virtually no support on other operating systems, including different versions of UNIX! If you happen to use only FreeBSD machines at home and at work, then by all means, put UFS on your memory sticks! But don't be surprised when Solaris refuses to mount them, even though it too uses "UFS". The most portable UNIX'y filesystem is probably old versions of the Linux EXT filesystem, such as EXT2 or EXT3. For better or worse, DOS was a very simple and hugely popular operating system, so support for its filesystem is ubiquitous. There may not be many good alternatives to FAT, but there are good alternatives to memory sticks, such as sftp, scp or sshfs, which are all part of the ssh suit of programs. Another excellent tool for syncing files across the network is of course rsync. You can also set up permanent network file shares with NFS or Samba. And of course ZFS filesystems allow you to easily share files across the network with other ZFS filesystems. #### Memory filesystems UNIX systems can use filesystems that reside entirely, or partially, in memory rather then on disk. There are many ways you can use this, but we will only briefly look at how to configure your /etc/fstab to mount /tmp in memory. Bizarrely some UNIX systems don't do this by default, but assuming you have this thing called "RAM", there isn't any reason not to. For one, your /tmp directory will be much faster, and it is convenient for security too. So without further adieu, simply take the line below suited to your system, adapt it to your local needs. • Linux: tmpfs /tmp tmpfs defaults,noatime,nosuid,nodev,noexec,mode=1777,size=1G 0 0 • FreeBSD/DragonFly: tmpfs /tmp tmpfs rw,mode=1777,size=1G 0 0 • OpenBSD: swap /tmp mfs rw,async,nodev,nosuid,-s=1g 0 0 • NetBSD: tmpfs /tmp tmpfs rw,-m=1777,-s=ram%25 • Solaris: swap - /tmp tmpfs - yes - Of course, these are merely suggestions. You may want to use a different size then 1 Gb, and you may want to add or drop some of the mount options here. Btw, DragonFly, NetBSD, Solaris, and a few Linux distros, I am sure, will use a tmpfs /tmp partition by default. PS: edit /etc/vfstab, not /etc/fstab, on Solaris systems. If you are having permission issues after creating this memory filesystem, try the following commands (if they don't help, make a valiant quest for a Guru on the top of a network stack, and plead politely for his wisdom): # umount /tmp # chmod 1777 /tmp # mount /tmp  ### Power Management On Linux you can use the acpi command to check your battery status and the powertop command to check which nasty little interactive programs are sucking your battery dry. You can suspend and hibernate systemd distros with systemctl suspend and systemctl hibernate. For non-systemd distros you can probably use the pm-suspend and pm-hibernate commands from the pm-utils package. #### FreeBSD You can check how much battery life you have left with acpiconf -i 0 | grep 'Remaining capacity' (your battery may have a different numerical ID then 0). If you enable apm services, by adding apm_enable="YES" and apmd_enable="YES" to /etc/rc.conf, you can: • acpiconf -s 1, put the machine in standby mode • acpiconf -s 3, suspend the machine • acpiconf -s 3, hibernate the machine #### OpenBSD If you enable the apmd(8) daemon by adding apmd_flags="" to /etc/rc.conf.local, you can: • apm -m, list how many minutes of battery life are left • apm -S, put the machine in standby mode • apm -z or zzz, suspend the machine • apm -Z or ZZZ, hibernate the machine You can still check your battery status even if you don't have apm, by using sysctl. Usually something like this will work: sysctl hw.sensors.acpibat0. Figuring out exactly how much time you have left on your battery require a bit of arithmetic, for example: #!/bin/sh # battery - print how much battery life is left # usage: battery remaining=$( sysctl hw.sensors.acpibat0 |
sed 's/.*=//' | awk '/remaining/ { print $1 }') chargerate=$(sysctl hw.sensors.acpibat0 |
sed 's/.*=//' | awk '/rate/      { print $1 }') left=$(echo "scale=2; ($remaining /$chargerate) * 60" | bc)


### Security

#### Users and Groups

The core security concept in UNIX is managing user and group permissions to files. By setting file permissions you can include or exclude users from collaborating on common projects, from tweaking system configurations, and from running certain programs. Consider the following example:

$ls -ld$HOME
drwxr-xr-x 81 dan dan 2560 May 26 15:38 /home/dan
$ls -l /bin/sh -r-xr-xr-x 3 root bin 617544 Apr 19 18:16 /bin/sh$ chmod +w /bin/sh
chmod: /bin/sh: Operation not permitted
$cp /bin/sh$HOME/sh
$chmod +w$HOME/sh
$ls -l$HOME/sh
-rwxr-xr-x 1 dan dan 617544 May 26 15:39 /home/dan/sh


The information we are interested in here is the first string of characters after the ls -l commands. Ignoring the very first character, they show us whether or not the file has read, write or execute permissions for the owner, the group and everyone else. /home/dan has owner dan and group dan, with permission rwxr-xr-x. That is, the owner dan has permission to read, write and execute, rwx. The group dan has permission to read and execute, r-x. And so does everyone else, the last r-x. So no one except the file owner in this case can edit this directory. But everyone can look at the files, and indeed make a copy of the files to their directory and freely edit the copies. This last point is illustrated above, where we first tried to give write permissions to /bin/sh (a rather daft thing to do!). This was denied because only the file owner, root, is allowed to do so. Hence we made a private copy of it, and then made the necessary adjustments (naturally the owner of a copy is whoever made the copy). Note the security implications here: Anyone who can read a file, can make a copy of it, and subsequently modify and execute the copy!

UNIX has always been an open share and share alike environment, business practices of AT&T not withstanding, and the default file permissions reflect this ideology somewhat. If we don't want to allow everyone access to snoop and copy our private files, we can simply run this command chmod 750 $HOME. With this set, our files are safe from prying eyes (well, not really - more on that later). If we want to grant other users the exclusive rights to read and copy our files, to work on some common project for instance, we can add them to the dan group. We could also have written the above command like so: chmod o-wx$HOME. This later form is perhaps easier to understand, it reads: for others (ei. everyone else) remove write and execute permissions. If we wrote ug+r, it would mean, for user (ei. the owner) and group give read permission. Often you will see the octal chmod form however, which can be tricky to understand, but you only need to know a handful of common values to get by:

• 755 owner has rwx, group and others have r-x
• 644 same as the above, but nobody has execute permissions
• 750 owner has rwx, group has r-x, everyone else have no access
• 640 same as the above, but owner and group cannot execute file
• 600 only the owner can read or write this file

Now running the command chmod 750 $HOME will indeed prevent (almost) anyone from tampering with our home directory, but what about all of the files within this directory? Actually, a 750 permission in$HOME is quite sufficient. But there are situations where it might be desirable to recursively set file permissions throughout a file tree. So lets assume that we want to set a 750 permission for all files and directories under $HOME, we could do so with the following command: chmod -R 750$HOME. But this is a very sloppy thing to do! The problem is that we don't really want execute permissions for ordinary files, except of course our custom shell scripts and assorted programs in ~/bin, we want a 640 permission on plain files, and only a 750 permission for directories (directories NEED execute permission!). Setting unnecessary execute permissions on plain files will not mean the end of humanity, but it is an uncouth move, and it will earn you newb points! The correct solution would be something more akin to this:

$find$HOME $$-path "*/bin/*" -prune$$ -o \
$$\( -type d -a -exec chmod 750 {} \;$$ -o \
$$-type f -a -exec chmod 640 {} \;$$ \)


It's OK to admit that the above command scares you. We could simplify this operation by doing it in stages, and actually, it's fine if you just lazily type chmod -R in the privacy of your own home. I will not tell on you. Sloppiness isn't really a major issue unless you are working professionally as a sysadmin. If that is the case, the above command is nothing less then job security. Just make sure you run this whenever your boss is looking over your shoulder.

To illustrate user and group management, we create a new user, bob, a new group, manhat, assign Bob to this group, set the new user and group as owners for some files in /var/manhattan, and lastly make these files secret for anyone outside of the Manhattan project:

#### Linux

# adduser bob
# usermod -a -G manhat bob
# chown -R bob:manhat /var/manhattan
# chmod 770 /var/manhattan


#### FreeBSD

# adduser bob
# pw usermod bob -G awk -F: '/bob/ { printf $1 "," }' /etc/groupmanhat # chown -R bob:manhat /var/manhattan # chmod 770 /var/manhattan  #### OpenBSD # adduser bob # groupadd manhat # usermod -G manhat bob # chown -R bob:manhat /var/manhattan # chmod 770 /var/manhattan  #### NetBSD # usermod -m bob # groupadd manhat # usermod -G manhat bob # chown -R bob:manhat /var/manhattan # chmod 770 /var/manhattan  #### Solaris and Illumos # usermod -m bob # groupadd manhat # usermod -G$(awk -F: '/bob/ { printf $1 "," }' /etc/group)manhat bob # chown -R bob:manhat /var/manhattan # chmod 770 /var/manhattan  As you can see, there is a disturbing amount of variation in user management across UNIX systems (chown and chmod however work the same). And these differences are somewhat incompatible. For instance usermod -G manhat bob is fine in OpenBSD and NetBSD, but that command will nuke Bob's membership in any group besides manhat in Linux and Solaris, whereas FreeBSD will, "thankfully", only give you a not found error. The limitations, and subsequent workarounds, in the FreeBSD and Solaris usermod examples, are as painful as they are embarrassing. It would also have been nice if we could call our group manhattan, but surprisingly enough, some UNIX's (eg. Solaris) cannot handle long group names. But I suppose our little Manhattan project illustrate that system administration, often involves a level of surprise, pain, embarrassment, and occasional atrocities. Beware that there are other, more subtle, peculiarities between these systems as well. BSD's have the unique concept of login classes, and Solaris has a thing about "profiles", for instance. As always, the sysadmins primary task is to read the manpages carefully! PS: It is possible to adjust user and group settings by hacking the files in /etc/passwd and /etc/group as root, and in the heyday of AT&T UNIX this was in fact the only way to add new users to the system. But this kind of Wild West approach is considered bad practice today, however inconsistent and ugly, its still better to use dedicated sysadmin tools for such tasks. #### To Be or Not to Be Root? It turns out that our top secret Manhattan project above isn't quite as secure as we may think. You see, UNIX systems have an all-powerful user called root. The root user can do anything, no restrictions whatsoever (of course the root user can set restrictions on himself, but he can also rescind them). This concept is a lot more powerful then a "system administrator", that you will see on some non-UNIX'y systems. The root user is not only able to configure the system any way he wants, but he can engage in deep brain surgery and wanton destruction as he pleases. If fact, anytime you see root in a UNIX context, replace it with the LORD, and you will get the right idea. Beyond file encryption it is impossible to hide anything from root. Windows users may find this disconcerting, but in actuality they have the exact same issue, it's just that their "root" user is an unknown, plausibly evil, corporate entity called Microsoft (MacOS and Android (and Ubuntu for that matter), being UNIX after all, have a real root account - but like Microsoft, they try very hard to hide this fact from their users). You can switch to the root user by typing the command su (or su - to simulate a full login), followed by the root password. By the way, you can use this command to switch to any user you have the password for, eg. su bob. It goes without saying that your user passwords should be a well guarded secret. But the root password is something you do not share even with your closest confidant! To quote Micah 7:5: «Trust ye not in a friend, put ye not confidence in a guide: keep the doors of thy mouth from her that lieth in thy bosom.» With careful group management, it is quite possible to delegate system administration tasks to users without giving them root access. Users working on a web server may be part of the www group, in order to work on files in /var/www for instance. If these users also need to run some database, or other web server maintenance program, the sysadmin can just run chgrp www on these programs, and set permissions to 550, in order to allow www users to run them, but no one else. But root is so powerful, that the system administrator himself should not use it, if it can be avoided. To illustrate the danger, suppose you meant to type rm -rf$HOME/* but mistyped it: rm -rf $HIME/*. Congratulations! You have now deleted all files on your computer. Another, more subtle example: Suppose you are working in /var/www/mysite, and decide to delete the whole mess in an act of righteous indignation: rm -rf ../* Permission denied! Oh really, you think smugly to yourself, and type: su -, and then rm -rf ../*. Congratulations! You have now deleted all files on your computer (do you see why?). The point? Don't use root! This is where sudo comes into play. In it's simplest form, you can edit /etc/sudoers, and uncomment the line that says #%wheel ALL=(ALL) ALL, that is, remove the # sign. Then make sure that your user is a part of the wheel group, eg. usermod -a -G wheel myuser in Linux (some distros use sudo instead of wheel here). PS: Whenever you need to run some dangerous command, it's a good idea to check first with echo. For instance, the two disastrous file munching commands mentioned above, could have easily been averted with a simple sanity check: echo rm -rf ... With this in place, you can run sudo command, to execute this one command "as root". That still makes you disturbingly powerful of course, but it is marginally better then monkeying about blindly as the Almighty root, at the very least it makes you open up the briefcase before you hit the big red button. sudo also logs any commands executed by it. So assuming the computer survives the attempt, you will know who to blame when the dust settles. The true beauty of sudo however, is that it allows you do define very fine grained privileges. The above line could have been bob 192.168.0.12 = (operator) /bin/kill, /usr/bin/lprm, for instance. Meaning that the user bob can run the commands kill and lprm on the machine 192.168.0.12, but only as the operator user (eg. sudo -u operator kill). You can define aliases for users and commands and such, in order to administrate things further. If we defined Host_Alias CSNETS = 192.168.0.12, 128.138.204.0/24, 128.138.242.0 for example, we could have written CSNETS instead of 192.168.0.12, to allow bob access to this list of machines. PS: Not all variants of UNIX come with sudo by default, and some have their own sudo'y kind of commands (eg. pfexec in Solaris and doas in OpenBSD). But all UNIX systems have sudo in their repositories at least. #### Remote Connections About a thousand years ago, when Vikings roamed the sea and pillaged unsuspecting monasteries, people used telnet to login to their remote UNIX machines. It was truly a barbaric time when "security" was a largely unknown concept. Today of course we use ssh to connect safely, and civilly, to our remote boxes. But simply having ssh will not magically make the world around you safe. You need to use this tool correctly. In a word, this means: disable password authentication. By default, an ssh server will accept a password login from anyone who has an account on the machine. Naturally this has to be the default, it would be impossible to set up a remote server otherwise. But the very first thing you should do on your shiny new server, is to set up public key authentication and then DISABLE password authentication! Passwords are a good way to protect your laptop from benevolent coworkers, it is NOT a safe way to protect your server out there on the hostile internet. There exists a network of bots on the web, dubbed the "Hail Mary Cloud", that will systematically probe any ssh server it can find. This cloud will try to login to your server a few times from one IP address, then try again with another IP, and so on and so on... If you allow password authentication on your remote ssh server, it will get compromised, not if, when. The answer to this problem is public keys. To understand why, we can use a simple analogy: Suppose you have set up a secret Pirate club in downtown New York, with a big flashy neon sign that says "Secret Password Required Upon Entry!" Well, daily you'll be pestered with kids trying to guess the password, and eventually one of them will get it right, before long your top secret Pirate den is full to the brim with script kiddies. The point? Use keys. Anyone who now wants to sneak into your club, must first accost a Pirate and steal his key. That can still happen, but you are likely safe from kids at least. Naturally, the bouncer should still ask for a secret password, for added security against such an event. To create an ssh key on your laptop run ssh-keygen. Once this is done, copy your key over to the server with: cat ~/.ssh/id_rsa.pub | ssh myserver 'cat >>~/.ssh/authorized_keys'. When you now log on to your server with ssh, it should say: Enter passphrase for key.... When you have verified in this way that your key is working, go ahead and disable password authentication on your ssh server. Edit /etc/ssh/sshd_config, and change these options: ChallengeResponseAuthentication no PasswordAuthentication no PubkeyAuthentication yes  From the server you can copy your authorized_keys file to other ssh servers with: ssh-copy-id, to allow your laptop to access these remote machines using the same key. However, you want to create unique keys for each physical laptop/workstation that you are using. It is possible to use one key for multiple machines, just as it is possible to use one physical key for many houses, but it is dumb thing to do! It is also possible to set up your ssh key without requiring a passphrase. This is actually more secure than using password authentication, but it is nevertheless bad practice. The passphrase isn't used to authenticate against the server, the key is used for that, rather, the passphrase is used to decrypt a key locally. The reason for this security measure is to protect your key in case it is stolen. If your laptop is compromised, and they are easily compromised, the intruder can use unencrypted keys to access your remote servers. If your keys are encrypted with a passphrase however, the keys are of no use to the intruder (just as a stolen Pirate key is of no use to a rug rat unless he can also manage to guess the secret password). Once you have enabled key authentication, you can simplify things a bit further by using an ssh agent. On the console, you can type ssh-agent sh (or use whatever shell you prefer), and then ssh-add. You will be asked to type in your passphrase. Once done, the decrypted ssh keys will be saved in memory, and subsequently used whenever you run an ssh command. So in effect, you type the passphrase once, and use ssh throughout the day without typing in any passwords. This convenient approach is not safe if you share your computer with multiple users. Before taking a break at work, type ssh-add -D to flush the keys, then retype ssh-add when you get back from lunch (and obviously - shut down the computer before you leave for the day). PS: Unfortunately the method of starting an ssh agent varies considerably between desktop environments and login managers, not to mention Windows. So consult your operating systems/desktops documentation, if you want to set up an ssh agent outside of the text console (also, the ssh-agent command must be executed on each virtual console you wish to use it on). To be clear: it's not very hard to set up, but it's hard for me to document, since it varies so. You can do a lot of stuff with ssh. You can use it to secure network traffic that isn't otherwise encrypted. You can do remote desktop work with it. You can set up your own private VPN, and you can mangle the network in all kinds of other interesting ways. These topics are well outside the scope of this article, if you are interested, check out SSH Mastery by Michael W. Lucas. Lucas has a wide array of other high quality books that security minded UNIX sysadmins will likely find both beneficial and humorous. Some suggestions are: Sudo Mastery, PAM Mastery, PGP & GPG and many others. Check out his website if you are interested. #### Passwords Like SSH, things are not magically secure just because you have a password. You need to use passwords correctly. There are two steps involved. First, you want long passwords that isn't easy to break. A good way is to find some obscure text that is very unique to you, an old Christmas card from a long gone relative, a really obscure magazine from the attic of your grandfather, or just some random sentence that only you can understand. Do not use short passwords, however obfuscated, nor anything from pop culture. "He's dead Jim" or "p455w0rd" are not safe passwords! "Høyesterettsjustitiariussjefsassistenten e en bondeknølbavianbajas fra Hålogalandbispedømmes ytterste gudsførlatte feskevær!!!"* is a reasonably safe password (and easily remembered if you happen to be Northern-Norwegian). Seriously though, use obscure sentences for good password protection! Secondly, and most importantly, use different passwords for different things. Do NOT use the same password over and over again (and for the love of MikeOS - do NOT write down your passwords on post-it notes!). But I can't remember my passwords! you may think. Of course you can't, nobody can. If you are trying to remember your passwords, you are doing it wrong! Use a password manager. A password manager is like a secure post-it note. It requires a password to open, and once opened, you can freely read and edit a list of your passwords. So in effect, you use one password to rule them all, and in the encryption bind them. If you are working on a graphical desktop, I recommend that you use KeePass, or one of it's variants (eg. KeePassXC). If you are working on the console, you can easily make your own password manager. ### Making Things Interactive Another problem with using the console as a desktop is that things aren't interactive, there's no menu for finding applications or clickable icons for launching your favorite programs, even just a flippin progress bar for your cp would be nice! Settle down, there are solutions for all of this and more... #### Creating Shortcuts Although you cannot create graphical icons for launching a program in the console, you certainly can create shortcuts. For example, you can add this to your ~/.profile (or ~/.bashrc if you plan to use them from the desktop): alias web=links alias edit=nano alias files=mc alias play=mplayer alias picture=fbi alias game=myman  You can now edit files by typing edit, play video and music with play, view your files with files, and so on. If you are having trouble remembering your own aliases, just run the command alias to see a list of them. If you are having trouble remembering that, write it down in ~/help, and make this alias: alias help='cat ~/help'  Aliases are also useful for running a command with a default set of flags, for example I usually set alias lynx='lynx -accept_all_cookies -assume_charset=utf8 -tagsoup', which makes the console browser lynx behave nicer. Aliases are nice for oneliners, but for serious automation you need shell scripts. A good tip is to place this in your ~/.profile (or other appropriate place): export PATH=$HOME/bin:$PATH. This line adds$HOME/bin to your list of default program paths, you can now write your own private shell scripts in the bin directory of your home folder, and launch them from anywhere. Note that we placed $HOME/bin first, this will let us easily overwrite system defaults. (which may or may not be a good idea depending on your skill) Serious powerusers do not use menus, like an efficient dictator in a banana republic, he simply states his will in clear unmistakable language and watches it unfold, he does not ask to see the menu first! But suppose you are a sysadmin in a company, and the above set of aliases are just too hard for your colleagues to remember, and the help alias too boring. The only way to get these poor fellows to launch an application is to provide a menu. Can we accommodate them? Certainly, if all you need is a static menu, then select might do the trick (PS: not all UNIX versions of sh support select - and not all versions of select behave in the same manner). We'll call our application launching menu apps: #!/bin/sh # apps - launch applications # usage: apps selectfile(){ echo -n "File: " read file if [ ! -f "$file" ]; then
echo "Error: file doesn't exist!"
exit
else
exec "$1" "$file"
fi
}

select prog in Web Edit Files Play Picture Game; do
case $prog in Web) echo -n "URL: " read url exec links$url
;;
Edit)   selectfile nano ;;
Files)  exec mc ;;
Play)   selectfile mplayer ;;
Pict*)  selectfile cacaview ;;
Game)   exec vitetris ;;
*)      echo "Please choose a number!"
esac
done


Even if your work colleagues are reluctant to type help, you can force them to read instructions in various ways. You can write a welcome message that all users will see as they login to the system, by putting the text in /etc/motd (motd: "message of the day"). If a user needs specific instructions, the sysadmin can add something like this to his ~/.profile (or ~/.bashrc), when the account is initially created: cat /path/to/some/instructions, or even just: echo type apps to launch applications

If you want a more "GUI-like" experience though, dialog is your friend. This program can create a large set of standard GUI widgets with ncurses graphics, such as radiolists, progressbars, file and calendar selections, etc... You can even play Microsoft and create a whole chain of "are you sure", "are you REALLY sure" yes-or-no boxes to make that professional vibe and annoy your users to no end. The select menu example in dialog would be:

#!/bin/sh
# thing - launch applications, using ncurses
# usage: thing

while true; do
dialog --menu "Startup Menu" 0 0 0 1 "Web" 2 "Edit" 3 \
"Files" 4 "Play" 5 "Picture" 6 "Game" 2> $tmp if [$? = 1 ]; then
exit
fi
selectfile(){
dialog --title "Files" --fselect $HOME/ 0 0 2>$tmp
if [ $? = 0 ]; then file=$(cat $tmp) exec "$1" "$file" fi } prog=$(cat $tmp) case$prog in
1)  dialog --title "URL" --inputbox \
"Enter website address:" 0 0 2> $tmp if [$? = 0 ]; then
url=$(cat$tmp)
exec links $url fi ;; 2) selectfile nano ;; 3) exec mc ;; 4) selectfile mplayer ;; 5) selectfile cacaview ;; 6) exec vitetris ;; esac done  #### Progressbars and Interactive Pipes Most UNIX console programs follow "the rule of silence". This rule states that the users time and concentration is valuable, so do your work silently and only report back if something went horribly wrong, don't pester him with trivia. To be frank, this concept is very hard for a casual desktop user to grasp. You assume that my time is valuable, what kind of lame excuse is that, how dare you give me the silent treatment?!? Imagine shouting at a respectful butler for delivering your letters like you asked him to, without calling every other second to report how many steps he had taken towards the mailbox! Truthfully, modern computer systems have become little more then narcissistic training boxes. Experienced UNIX users actually enjoy a system that doesn't constantly second guess them or bother them with irrelevant information. The tranquility and peace of mind that the rule of silence provides is in fact one of the main benefits of using UNIX. Sometimes however you need to know how a command is progressing, is there a progressbar or something for the console? Yes. First though, if you are lucky enough to use FreeBSD, you can hit Ctrl + t at any time, to see how a program is progressing. GNU (read Linux) utilities does not have this feature, but there is a program, appropriately named progress, which will tell you the progress of GNU coreutils, such as cp or mv. Of course, if you just need to verify that a lengthy dd job is actually doing something to the disk, iostat and other monitoring apps should suffice. You can also create your own progressbar with pv (pipe viewer), it functions like cat, but reports its progress. So pv bigfile > bigcopy, will copy the file with a progressbar. You can also stick pv in the middle of a pipeline and see how it's progressing, eg. cat file | pv -s$(du file | awk '{ print $1 }') | nc -w 1 somewhere.com 3000. In this example we need to tell pv how large the file is with -s$(du file | awk '{ print $1 }'). Without this pv will still report write speed, but it will not know when the job is nearing it's completion. Pipelines can be interactively manipulated in other ways too. For example the percol program (Linux only) will let you interactively select elements from the pipe input and send it down the line, eg. ls | percol | du -h. A somewhat similar program from the moreutils package, vipe, which is also available on non-Linux systems, will let you edit the input with vi, once you exit the editor, the modifications will be sent down the pipe. #### Autocompletion You must know how to read and write in order to use the console, but contrary to popular belief, you don't need to write much. Use the Tab key to auto-complete filenames. So don't type cd /really-long-AND-obscure_path/to_my_file-SomeWhErE, just type cd /r then hit Tab, if it doesn't complete fully, hit Tab again to get a list of alternative matching files, type one or two letters more and hit a final Tab. You should also learn to use some basic regex; Instead of typing the tedious command rm "Aqua/I'm A Barbie Girl.mp3" "Aqua/Doctor Jones.mp3", just run rm Aqua/*.mp3. The bash-completion package will let your bash shell auto-complete more then just filenames. But for serious auto-completion power I recommend switching your default shell to zsh. (and for your grandma I recommend fish ;^) #### Having Fun Alright, you're thinking, so you can do quite a lot of functional things with the console, but to be honest: The reason I still want to use the desktop, is because it's fun! I want to goof around with wallpapers, screensavers, games, 3D desktop cubes, watch youtube videos, and you know what, I really enjoy constantly resizing my windows. Seriously, I get a kick out of it. You just can't do that in the console! Oh really? Check out the links. If on the other hand, you just want to go on the web, keep reading. ## The Web ### Connecting to the Internet Running ifconfig is a quick way to check your network settings, pay particular attention to your network card names. In Linux the wired network card is often called eth0, and the wireless card wlan0, but not always. Other UNIX operating systems use different names. Pinging a website (eg. ping www.wikipedia.org) is a quick way to check that you're online, but remember that this usually doesn't work from a virtual machine. Connecting to the web over a wired network is often done with dhclient eth0 or dhcpcd eth0. You may be using a version of Linux that doesn't have ifconfig, in which case you need to use ip instead. Here is a quick ip to ifconfig cheat sheet: ifconfig ip a ifconfig eth0 up ip link set eth0 up ifconfig eth0 down ip link set eth0 down ifconfig eth0 add 10.0.0.1/24 ip a add 10.0.0.1/24 dev eth0 ifconfig eth0 del 10.0.0.1/24 ip a del 10.0.0.1/24 dev eth0  How about connecting to a wireless network? On Linux the easiest way to do this is usually with nmcli, a command line front-end to NetworkManager, which should be available by default. You can list available networks: nmcli dev wifi list, or connect to a network: nmcli dev wifi con mynetwork password mypassword, and do other network managy things with it. #### Wifi without NetworkManager If you aren't using Linux, or your version of Linux doesn't have NetworkManager (or you don't want to use it), you can use wpa_supplicant to connect to your wifi. First write a default configuration file in /etc/wpa_supplicant.conf: network={ ssid="my home network" scan_ssid=1 key_mgmt=WPA-PSK psk="mypassword" }  With this in place we can make our connection. First make sure your wifi card is activated: sudo ifconfig wlan0 up. Then start wpa_supplicant: sudo wpa_supplicant -B -c/etc/wpa_supplicant.conf -iwlan0. And finally request an IP address form the wireless router: dhclient wlan0. You should now be connected! If you only plan on ever connecting to a single wireless network, then this is enough (actually in such a case you should probably invest in an ethernet cable). But if you need to connect to wireless networks arbitrarily, manually editing the wpa_supplicant.conf file every time is tedious. You can write the following wifi script to handle things automatically: #!/bin/sh # wifi - connect to a wifi network # usage: wifi network password wlan=${wlan:-wlan0}
sed -i -e "s/ssid=.*/ssid=$1/" -e "s/psk=.*/psk=$2/" /etc/wpa_supplicant.conf
ifconfig $wlan up wpa_supplicant -B -c/etc/wpa_supplicant.conf -i$wlan
dhclient $wlan  You can now run the script: sudo wifi 'my home network' password (or wlan=wlan1 sudo wifi 'my home network' password if your device isn't wlan0). There are a few problems with this script though: It does not check for errors, such as badly written arguments. Running sudo wifi my home network password would fail without giving you any obvious error messages (do you see why?). It doesn't list available wifi networks, for that you probably need iwlist. And it stores your password as plain text, you should probably use wpa_passphrase to encrypt it. Finally, you may also need to use dhcpcd instead of dhclient. All of these issues can be addressed, but I leave that as an exercise for you. As a side note, you should never configure your wireless router to accept connections without a password, or to use WEP encryption, which is more or less the same thing. If you do need to connect to a WEP router, use iwconfig not wpa_supplicant. Update: Actually it turn out that you shouldn't use wpa/wpa2 either... hm... Maybe IP over carrier pigeons is the safe option? Of course that method has security implications too, such as cats. You can use a password manager to store network passwords, and use a simple script to automatically search this encrypted database and connect to your network, as discussed in the password manager section below. #### FreeBSD and DragonFly BSD With the exception of OpenBSD, all the BSD's use wpa_supplicant to connect to wireless networks, as described above. Although the mechanism is basically the same, some of the particulars vary. The first issue in FreeBSD is simply enabling the wireless network card in the first place. You can run sysctl net.wlan.devices to get the name of your card, it might be something like iwm0. You can get more information by analyzing the output of pciconf -lv, or just by running dmesg | grep Wireless. This last command might return something like this: iwm0: <Intel(R) Dual Band Wireless AC 8265> mem 0xec000000-0xec001fff irq ...  Now that we know we are using an Intel iwm 8265 wireless network card, we can go ahead and configure FreeBSD to load up the correct firmware and other necessities during boot, by adding these values to /boot/loader.conf: if_iwm_load="YES" iwm8265fw_load="YES" legal.intel.ipw.license_ack=1 legal.intel.iwm.license_ack=1 legal.intel.iwi.license_ack=1 wlan_wep_load="YES" wlan_ccmp_load="YES" wlan_tkip_load="YES"  Boy, that was a lot of work! From here on things get easier. The next step is to write a /etc/wpa_supplicant.conf file for your wireless network, it might look something like this: network={ ssid="mynetwork" psk="mypassword" }  Finally, we can configure the system to start wpa_supplicant at boot: # echo wlans_iwm0="wlan0" >> /etc/rc.conf # echo ifconfig_wlan0="WPA DHCPSYNC" >> /etc/rc.conf # service netif restart  You should now be connected to the wireless network! You can switch to another wireless network manually by editing /etc/wpa_supplicant.conf, and then run service netif restart again. But we can also make a short script to automate this: #!/bin/sh # wifi - connect to a wifi network (FreeBSD edition) # usage: wifi network password sed -i '' -e "s/ssid=.*/ssid=$1/" -e "s/psk=.*/psk=$2/" /etc/wpa_supplicant.conf service netif restart  PS: The process of connecting to a wireless network in DragonFly BSD is exactly the same, with one exception: The DragonFly kernel is preconfigured to use any wireless devices currently supported, so just write your /etc/wpa_supplicant.conf and add a few values in /etc/rc.conf, and you are good to go! #### NetBSD Setting up a wireless network in NetBSD is easy-peasy, compared to FreeBSD at least ;^) First write a configuration file for your wireless network in /etc/wpa_supplicant.conf, it might look something like this: ctl_interface=/var/run/wpa_supplicant ctl_interface_group=wheel network={ ssid="mynetwork" psk="mypassword" }  Now add the following values to /etc/rc.conf (this example assumes your network card is called "iwn0", it may be called something else): wpa_supplicant_flags="-i iwn0 -c /etc/wpa_supplicant.conf" dhcpcd=YES  Now reload network settings with /etc/rc.d/wpa_supplicant reload, and you should be connected. To change to a different wireless network, you can edit /etc/wpa_supplicant.conf, and run /etc/rc.d/wpa_supplicant reload again. Naturally you can automate this, here is a NetBSD version of the above wifi script: #!/bin/sh # wifi - connect to a wifi network (NetBSD edition) # usage: wifi network password sed -i -e "s/ssid=.*/ssid=$1/" -e "s/psk=.*/psk=$2/" /etc/wpa_supplicant.conf /etc/rc.d/wpa_supplicant reload  #### OpenBSD If you feel confused after reading the above sections, you should be! It is worth mentioning that OpenBSD is the only operating system in the UNIX world that connects to a wireless network in a sensible way: ifconfig iwn0 nwid 'my home network' wpakey mypassword followed by dhclient iwn0. And how do you scan for wireless networks? ifconfig iwn0 scan. This last command also works for the other BSD's (iwn0 is a typical wireless card name in OpenBSD, and em0 is a typical ethernet card name, but your devices may have different names). Other operating system developers could learn a lot from the OpenBSD weirdos :^) Update: As of OpenBSD 7.0 you can also add something like this to /etc/hostname.iwn0, and it will just autoconnect to those networks whenever you are around them: join workwifi wpakey allworkandnoplaymakesjackadullboy join homewifi wpakey 12345 join cafewifi wpakey doubledecafnonfatsugarfreevanillalatte inet autoconf inet6 autoconf  #### Solaris and Illumos As for Illumos it has it's own "NetworkManager" called NWAM, which if running will try to connect you to any known wifi or ethernet links automatically. You can also scan for wireless networks with dladm scan-wifi and connect to one like so: dladm connect-wifi -e 'my home network' wpi0 (wpi0 is a typical wireless card name in Solaris, and e1000g0 is a typical ethernet card name, but your devices may have different names). It is possible to disable NWAM and use ifconfig manually. For instance, these commands will disable NWAM and manually request an IP address from your DHCP server (to switch back to NWAM, disable "default" and enable "nwam"): svcadm disable network/physical:nwam svcadm enable network/physical:default # you may need to run these commands first (only once): ipadm create-if wpi0 cp /etc/nsswitch.dns /etc/nsswitch.conf # now connect with DHCP: ifconfig wpi0 dhcp  ### Browsing The modern web browser is a beast, and not in a good way. In fact Firefox has about 25 million lines of code, and is bigger then the Linux kernel and the entire KDE4 suit of applications combined (as of 2019, as time goes by these statistics will only grow worse)! Expecting something like this to work in the text-based UNIX console is hopelessly unrealistic. Sadly this is one area where the console does not, and cannot, impress. Having that said there are a number of basic HTML browsers available for the console. The classic choice is lynx, it's a bit like vi in that you need to learn a whole set of key-bindings before it becomes useful. But like vi it is very fast and efficient once learned. You can check these key bindings by starting lynx and typing ?. A more user-friendly alternative is links. It has a nice drop down menu accessible with Esc. PS: none of these browsers support anything like javascript or flash! For a more graphical experience (Linux only) you can run links -g, if the framebuffer has been configured. w3m is also capable of rendering images in the framebuffer (in Debian you want the links2 and w3m-image packages). Perhaps the most impressive framebuffer browser is NetSurf, it even has some rudimentary javascript support (in Debian install netsurf-fb). In many distros this package has a serious bug: you can work around it by copying some font files: cp /usr/share/fonts/truetype/dejavu/* /usr/share/netsurf A graphical browser in a Linux console sure looks impressive, but don't expect them to replace Firefox or Chrome anytime soon. ### Web Apps Do not be too quick to dismiss lynx though, even if many sites will not work and you find the whole experience boring! The big graphical browsers out there are buggy, bloated and more often then not, boneheaded! lynx on the other hand is an invaluable tool for debugging your web server. It often helps to see what your website looks like in pure HTML, blind people using screen readers, for instance, will often see you site exactly as lynx presents it (shame on the web developers who discriminate blind folk and UNIX nerds alike!). This venerable old tool also does a supreme job of rendering sites as pure text. So if you want to print out a hard copy of the Wikipedia article about Slackware for instance, you could run the command: lynx -dump https://en.wikipedia.org/wiki/Slackware | lpr #### Example 1: A Weather App - using Lynx Still not convinced? Here is a short demonstration of a simple web app printing today's weather: $ lynx -dump http://weather.yahoo.com/united-states/illinois/chicago-2379574/
...
Current conditions as of 1:54 pm EDT
Mostly Cloudy

Feels Like:
32 °F

Barometer:

30.13 in and rising
...
$cat sedcond /IL, United States/{ n p }$ cat sedtemp
/Feels Like/{
p
}
$cat weather #!/bin/bash # weather - extract the current weather for Chicago, IL # usage: weather URL="http://weather.yahoo.com/united-states/illinois/chicago-2379574/" LYNX=$(which lynx)
TMPFILE=$(mktemp tmpXXXXXX)$LYNX -dump $URL >$TMPFILE
conditions=$(cat$TMPFILE | sed -n -f sedcond)
temp=$(cat$TMPFILE | sed -n -f sedtemp | awk '{print $4}') rm -f$TMPFILE
echo "Current conditions: $conditions" echo The current temp outside is:$temp
$./weather Current conditions: Mostly Cloudy The current temp outside is: 32 °F  Of course Yahoo might change their website and break our script. The point here is to understand the potential of lynx. Once you convert a webpage to pure text, you can feed it to the standard UNIX tools such as sed, awk, bc, etc... #### Example 2: Daily Motivational's - using wget Let's explore another example. This Web App prints daily quotations from quotationspage.com. It checks if the URL is valid or not, and writes a download log in /tmp/quote.log. You can run this script as a daily cron job, and configure your shell to print the daily quote, if you want: #!/bin/sh # dquote - download daily quote to /tmp/daily_quote.txt # usage: dquote quote_url=www.quotationspage.com/qotd.html check_url=$(wget -nv --spider $quote_url 2>1&) if (echo$check_url | grep -s '*error404*'); then
echo "$quote_url invalid" echo "Exiting script..." exit fi wget -o /tmp/quote.log -O /tmp/quote.html$quote_url

sed 's/<[^>]*//g' /tmp/quote.html |
grep "$(date +%B' '%-d,' '%Y)" -A2 | sed 's/>//g' | sed '/ /{n ; d}' | sed 's/ //g' | tee /tmp/daily_quote.txt > /dev/null exit  Much of the details here has to do with cleaning up the HTML code, and printing only the text we want. If your having trouble following the logic here, I suggest you do the steps manually, one by one, and analyze how it transforms the output. #### Example 3: Sending SMS - using curl wget is great for retrieving data from the web, but it's cousin curl can also send data. In this example we use curl to send an SMS (ei. text) message to our phone (PS: This will only work within the US): #!/bin/sh # sms - send an sms # usage: sms number message... phone=$1
shift
SMSrelay_url=http://textbelt.com/text

curl -s $SMSrelay_url -d \ number=$phone \
$echo 'text/html; w3m -I %{charset} -T text/html; copiousoutput;' >> ~/.mailcap  You can now read your GMail account from the console, we have even configured mutt to use the w3m console web browser for reading HTML emails. ### News There are a few rss/atom news client's available for the console, such as newsbeuter (aka. newsboat) and rssowl. Some UNIX systems also have the ancient news command available, this command reads any new text files added to /news or a similar place. If your system doesn't have a news command, you can easily create one. You can then either manually download news items and save them to the news directory, or you can write a script that automatically syncs this directory with some online news service and add it to your crontab. Here is the script: #!/bin/sh # news - read latest from /news # usage: news for i in$(ls -t /news/* $HOME/.news_time 2>&1); do case$i in
*' No such file') ;;
*/.news_time) break ;;
*) set X$(ls -l$i)
echo "
$i: ($3) $6$7 $8 " cat$i
esac
done


#### NetBSD

NetBSD also has it's own alsamixer-like command called aiomixer, and like OpenBSD, it too has a mixerctl command that works much the same way. The command will not list the mixer settings if you run it without any flags though, instead you must run mixerctl -a. And to change settings you must use the -w flag: mixerctl -w outputs.master=195. Similarly to OpenBSD the NetBSD mixerctl specifies volume from 0 to 255, you can easily make the above mentioned OpenBSD volume command for NetBSD by tweaking the example a little.

#### Solaris and Illumos

You can change audio configuration with the audioctl command. For instance you should be able to set the volume to 50% by doing something like this: audioctl set-control volume 50. Exactly what controls are available may depend on your hardware, you can check with audioctl show-control (Read the full man page for further details).

As a side note: I had some hardware problems on my test machine. The first audio device /dev/sound/audiohd:0 did not work, but the second one /dev/sound/audiohd:1, did. Unfortunately the system choose the wrong card as the default! Well, no problem, this quick fix solved it: ln -sf /dev/dsp1 /dev/dsp. You can test your audio with audiotest.

### Video

If you have configured your framebuffer correctly in Linux, you can watch videos in the console with vlc -I ncurses movie.mpeg. You might get a garbled screen when the movie is finished playing, if so type reset. Another fine alternative here is mplayer. Like vi you need to learn a few key-bindings before you can truly appreciate this program. You can play a movie in the framebuffer like so: mplayer -vo fbdev2 -vf scale=1366:768 movie.mpeg. The resolution must match exactly the resolution of your framebuffer, this is usually the same as your maximum X resolution (you can check this in X with the command xrandr).

Some key-bindings to help you get started with mplayer: You can pause and unpause the movie with Space, change volume with 0 and 9, jump forward or backward with arrow keys or pageup or pagedown, and quit with q.

In theory you should be able to play movies on the console with mpv, but you probably need to recompile mpv with --enable-sdl and --enable-sdl2, and you may need to recompile sdl2 with --enable-video-directfb. I have not tested this myself.

There are a couple of ways you can watch youtube movies in the Linux console. One is to navigate to the video you want with a console browser, such as lynx. When you have found the right URL, hit G, now left click and mark the URL (assuming you have configured gpm). Hit Ctrl + c to quit lynx. Now either type youtube-dl and middle click to paste the URL and download the video, or type vlc (or mplayer) and paste the URL to watch the video directly (you can copy paste the URL with tmux also if you prefer).

Another program you could use is youtube-viewer. You can either run youtube-viewer -d to download the movies instead of watching them, and then later play them with vlc or mplayer. Or you can edit ~/.config/youtube-viewer/youtube-viewer.conf and set the appropriate mplayer or vlc flags to play the movies directly in the framebuffer.

### Music

Besides vlc or mplayer, there is a ton of music players available for the console! A very simple one which I really like is mocp ("music on console player"). Adjust volume with , (comma) and . (dot), display available key-bindings with ?. You can open a directory with i, and start playing music files here by selecting it and hitting Enter. Or you can add the song to your playlist with a, clear the playlist with C, when the playlist is populated correctly switch to it by Tab and hit Enter. Shuffle with S and repeat with R. cmus and mp3blaster are popular alternatives, and there are plenty of others. There are also several more basic audio players available. The sox package discussed below for instance, includes the play command, which is quite capable of playing any kind of audio file.

You can play internet streams with mplayer and other media players, but this requires you to find the correct URL streams. This is more tricky then you might think since streaming websites will usually not display these URL's directly. Often you need to snoop around in the website HTML code in order to find them. A good place to look for such streams is somafm.com. Here is a somewhat Apple-centric example list (yes I know - do feel free to change it!) to get you started. You can append these lines to your ~/.profile or ~/.bashrc, or you might want to create a more interactive radio command using select or dialog.

alias radio="mplayer -playlist"


You can also set up your own radio stream with mpd, and play it locally with mpc, ncmpcpp or another MPD client.

Here is an example setup, place it in /etc/mpd.conf for a system wide service, or ~/.config/mpd/mpd.conf if you plan to run it as a user process:

db_file             "~/.config/mpd/database"
log_file            "syslog"
music_directory     "~/music"
auto_update         "yes"
playlist_directory  "~/.config/mpd/playlists"
pid_file            "~/.config/mpd/pid"
state_file          "~/.config/mpd/state"
sticker_file        "~/.config/mpd/sticker.sql"


Run mkdir -p ~/.config/mpd/playlists if this directory does not exist. You're now all set, just run mpd, and then you can launch an MPD client, such as ncmpcpp to play your music.

### Spotify, LastFM and Podcasts

There are command line clients for these online services: despotify was a good Spotify client, but seems to have been abandoned, ncspot is another alternative. For LastFM and podcasts, you can use shell-fm and bash-podder (of course for podcasts you could just manually download them and use your favorite music player). These commands are rare to see outside Linux repositories, but they shouldn't be too hard to compile yourself.

You can also install Mopidy (Linux only), which can be configured to play music from Spotify and other providers as an MPD service, you can then listen to Spotify with one of the many MPD clients. For example, after mopidy and mopidy-spotify is installed, you can add this to /etc/mopidy/mopidy.conf (or ~/.config/mopidy/mopidy.conf if run as a user process):

[audio]
output = tee name=t ! queue ! autoaudiosink t. ! queue ! udpsink
port=5555

[spotify]
enabled = true
bitrate = 320


You can then configure the MPD client ncmpcpp to use this, by adding this to ~/.ncmpcpp/config:

visualizer_fifo_path = "/tmp/mpd.fifo"
visualizer_output_name = "my_fifo"
visualizer_sync_interval = "30"
visualizer_in_stereo = "yes"
visualizer_type = "spectrum"
visualizer_look = "+|"


$cp /mnt/hd/DCIM/100NIKON/* Pictures/vacation_2018  As you can see my camera organized its pictures in DCIM/100NIKON, but yours may do things differently. Once mounted just use ls and find out (PS: If you are having trouble you can always buy a cheap usb memory card reader on ebay, you can then mount your memory card like an ordinary usb memory stick). For scanners see the printers and scanners section. You can also edit photos from the console, using the ImageMagick collection of tools (a good alternative here is GraphicsMagick). Here are some of its utilities: • identify print information about an image • convert convert image format, or resize, blur, crop, flip, join etc... • mogrify much the same as convert, but alter the image directly don't make a copy • montage create a composite image out of several others • composite overlap one image over another These tools give you quite a lot of scripting power to manage your photos. It is well worth learning, even if you are only interested in using a desktop environment. You can find many good tutorials for this software suit online. ### PDF and Postscript The fbi (aka. fbida) package mentioned above usually include fbipdf (sometimes called fbpdf). This program can be used to view PDF's on the framebuffer like so: fbipdf document.pdf. Some old versions of fbi do not include fbipdf, in such cases you can usually use the inferior fbgs program. If you don't have a framebuffer available, you can convert a PDF to HTML or plain text with pdftohtml and pdftotext, both of which are a part of the poppler (aka. poppler-utils) package. You can also use pdfimages from the poppler tools to extract images in a PDF. To demonstrate: $ pdftohtml -s -i document.pdf
$lynx document-html.html$ pdftotext -layout document.pdf
$less document.txt  Exactly how well this works depends very much upon the PDF in question. If you are lucky, the conversion is merely bad, often though, it's unreadable. Some PDF's are simply a collection of JPEG's of text, the poppler tools cannot convert such documents. You can try with ocrmypdf or other OCR solutions (see discussion below). The poppler utils can do some basic editing as well, such as extracting pages from a PDF or merging pages into a single PDF, checking the metainfo and more. An alternative PDF editing tool is pdftk. Of course non of these tools are interactive, so they are mostly useful for basic batch editing and scripting. ### OCR Sadly OCR support, that is scanning a document and converting the image to plain text, is not well supported in the open source world. The only widely available tool is tesseract, here is a short demonstration of its usage: $ scanimage --mode grey --resolution 300 > scan.pnm
$unpaper -b 0.5 -w 0.8 -l single scan.pnm scan1.pnm$ convert scan1.pnm scan.tif
$tesseract scan.tif scan.txt  This example uses commands from the sane-backends, unpaper and ImageMagick packages. The results of this OCR depends much upon the quality of the scan, the higher the resolution the better, and it also requires you to have installed the correct language packages for tesseract (eg. tesseract-ocr-fra or similar if the document is French). ### ASCII art For the geeky console user, ASCII art can provide much fun. It's entirely frivolous of course, non-Linux consoles without video playback that could use a textual representation of graphics, either have no ASCII art support at all, or they don't have good enough font support to make it practical. If you install the libcaca (sometimes called caca-utils) package, you can view images with cacaview or convert them to text files with img2txt. The related libaa is used for black and white ASCII art, it includes the fun bb demo. You can even play videos in ASCII art with something like this: mplayer -vo caca myvideo.mkv, or vlc -V aa https://youtube.com/some_url. Speaking of video, hasciicam will let you play video output from your webcam in ASCII! PS: The quality of the ASCII art depends on what fonts you use. The smaller the font, the greater the resolution. So before playing a video, or displaying a picture in ASCII, set your console to use the smallest possible font you have available (see console configuration section on how to do this). Although your artistic painting skills may be limited on the console, you can freely draw ASCII art. There are a few programs designed specifically for this purpose, such as cadubi, but real pros do their ASCII painting in vi! (of course ed users scoff at such newbs) ### Retrofuturism The previously mentioned ASCII art section is strictly speaking a digression, since you really need fairly advanced consoles to use it well (either a Linux console or a terminal emulator running in X). But since we have already digressed, lets digress a bit further and briefly mention two retrofuturistic terminal projects that are truly amazing: The first is cool-retro-term. This is a terminal emulator running under X, similar in functionality to, say xterm. But it allows you to emulate the look of ancient computer screens, such as the Apple II or the IBM 3278, and you can manually tweak effects, such as scanning lines, flickering, screen curvature and more. If you want a cool retro terminal, look no further! You will find this package in most UNIX systems repositories (on Solaris you need to compile it yourself - good luck with that). The second project I'd like to mention, is notcurses. We have used curses, and the newer ncurses for a long time now to create pseudo-graphics in our terminals. Applications like mc, nethack and tmux are good examples of what I mean by "pseudo-graphics." But modern terminals can actually take things a lot further with color blending, adjusting transparency and allowing a full set of UTF-8 characters (including Braille characters and what not). The ncurses library cannot use such advanced features since it needs to be compatible with all kinds of ancient cruft. This is where notcurses comes into the picture. It's a library that pushes heavily on modern capabilities to produce surprisingly good graphics directly in the terminal. Check out the demo video and book from the developer. Even for non-programmers, this library can provide a lot of fun (it is available in the repos of several Linux distros and FreeBSD). The notcurses package includes the video player ncplayer, the neofetch-like ncneofetch, the ls command ncls which also renders pictures, and notcurses-demo that can display many different demos (eg. notcurses-demo x). For some truly ludicrous retrofuturism, you can run these applications in cool-retro-term, and thus make the really modern stuff look really old! ## Peripherals ### USB Memory Sticks See the disk management section for more details about formatting USB memory sticks, in this section we will only talk about mounting such devices. The device name used in the examples are typical for these operating systems, but yours may be different (it may be sdb1 not sdd1 for example). After attaching your memory stick you can run dmesg | tail to check what the system called the device, or to see if there were any errors. Finally, depending on your security setup, you may need to use sudo to run some of these commands. #### Linux $ mkdir -p /mnt/usb                 # make a directory to mount the usb device in
$mount /dev/sdd1 /mnt/usb$ cp -r /mnt/usb $HOME/Downloads # use the usb device like a regular directory$ umount /mnt/usb                   # safely unmount the device


#### FreeBSD/DragonFly BSD

$mount -t msdosfs /dev/da0s1 /mnt/usb$ umount /mnt/usb


#### OpenBSD/NetBSD

$disklabel sd0 # check the partition name$ mount /dev/sd0i /mnt/usb
$umount /mnt/usb  #### Solaris and Illumos $ rmformat                         # check the partition name
$mount -F pcfs /dev/dsk/c0t0d0p0:c /mnt/usb$ umount /mnt/usb  && eject /dev/dsk/c0t0d0p0


### CD's, DVD's and BlueRays

Ripping CD's and DVD's can be done with cdparanoia and vobcopy. Writing CD's and DVD's can be done with cdrecord (or dvd+rw-format) and growisofs, and making iso files can be done with mkisofs. OpenBSD has it's own program for ripping and writing CD's, cdio. We have already talked about playing music and videos in the Multimedia section above. But let's say a few words about finding and playing a DVD track. Unfortunately the way DVD's are organized vary greatly, and more often then not, defy conventional wisdom. lsdvd is a nice program that lists DVD tracks, and is helpful for sorting out this mess:

$lsdvd opening /dev/rcd0c for title Disc Title: STAR_TREK_TOS_D6 Title: 01, Length: 00:00:30:160 Chapters: 01, Cells: 01, Audio ... Title: 02, Length: 00:48:28:200 Chapters: 06, Cells: 06, Audio ... Title: 03, Length: 00:48:24:800 Chapters: 06, Cells: 06, Audio ... ...$ vlc dvd://2 # play the first episode on the dvd


Since the first track only had a 30 second length, we know that the first real episode is on the second track. We can use such logic to create a simple dvd script, that will automatically play the nth track from a DVD with a sizable length (~20 minutes or longer), using only mplayer:

#!/bin/sh
# dvd - play nth dvd track
# usage: dvd n

if [ ! $# = 1 ]; then echo Usage: dvd n 2>&1 && exit 1 fi track(){ mplayer -noconfig all -cache-min 0 -vo null -ao null -frames 0 \ -identify dvd:// | grep '[0-9]_LENGTH=[0-9][0-9][0-9][0-9]' | sed -n "$1p" | sed 's/.*_$$[0-9][0-9]*$$_.*/\1/'
}
mplayer dvd://$(track$1)


We can now play our first Star Trek episode with dvd 1. Of course our elegant mplayer script ignores some messy details; To play this in the console mplayer need some more flags, as mentioned in the Multimedia section. You may also want to detect if there is a VIDEO_TS directory around, and add -dvd-device ., to play DVD's you have ripped to your harddisk with vobcopy. Finally, as mentioned, DVD organization is disturbingly illogical at times, so our script will not always work as intended.

But enough about playing DVD's, lets talk about making them. The following examples show how to create and mount ISO files, and how to burn such data to a CD/DVD:

#### Linux

$mkisofs -o mydisk.iso /my/path # make a data ISO$ mkdir -p /mnt/cd
$mount /dev/cdrom0 /mnt/cd # mount CD$ mount /dev/dvd0 /mnt/cd          # mount DVD
$mount -o loop mydisk.iso /mnt/cd # mount ISO$ umount /mnt/cd                   # unmount CD/DVD/ISO
$cp -r /mnt/cd$HOME/Downloads    # rip ISO contents
$cdrecord -scanbus # check name of CD/DVD burner$ cdrecord mydisk.iso
$cdrecord -dao -useinfo *.wav # write an audio CD$ mkisofs -R -J -udf -iso-level 3 -o mydvd.iso /my/path # make a DVD ISO
$growisofs -dvd-compat -Z /dev/cd0=mydvd.iso # write a DVD  Much the same can be done for other UNIX systems, but the device names may be a little different. And they might require you to create a virtual device for the ISO file before you can mount it: #### FreeBSD/DragonFly BSD $ mdconfig -a -t vnode -f mydisk.iso -u 0       # make a dev for the ISO
$mount -t cd9600 /dev/md0 /mnt/cd # mount ISO$ mount /dev/cd0 /mnt/cd                        # mount a real CD/DVD


#### OpenBSD/NetBSD

$cdio play # play CD (cdio is OpenBSD only)$ cdio tao mydisk.iso              # write data CD/DVD
$cdio cdrip # rip audio CD$ cdio tao -a *.wav                # write audio CD
$vnconfig vnd0 mydisk.iso # make a dev for the ISO$ mount /dev/vnd9c /mnt/cd         # mount ISO
$mount /dev/cd0c /mnt/cd # mount a real CD/DVD$ growisofs -dvd-compat -Z /dev/rcd0c=mydvd.iso # write a DVD


#### Solaris and Illumos

CD's should be auto mounted in /media, you can double check with rmformat.

$mount -F hsfs mydisk.iso /mnt/cd # mount ISO  ### Printers and Scanners Practically all modern UNIX's use CUPS and SANE to manage printers and scanners. Installing a printer from the console is tricky if you don't know what you are doing. So for this one task it's probably better to use a graphical desktop and configure CUPS using a modern web browser, such as Firefox. Just go to http://localhost:631 and enter your root password. Many UNIX systems have large collections of printer drivers available by default, but if you can't find your model, head over to openprinting.org and search for a driver. If you cannot find your exact model try to find a driver for a similar device. For example, I could not find a driver for my HL-2035 Brother printer, but I did find one for the HL-2030 that worked just fine. Once the printer is set up, installing it on other UNIX machines using the console is easy. Just copy the printer configuration file /etc/cups/printers.conf, and optionally other configuration files that might be relevant, such as the drivers in /etc/cups/ppd. If you have configured your printer as the server default, you can use the following commands to print documents: $ lpr document.pdf document.ps document.txt
$enscript document.txt # print as postscript (looks nicer)$ lpq                            # list printing jobs
$lprm # remove a print job  PS: Some UNIX systems may already have a native lpr and related suite of applications. In OpenBSD for example, the native print command is /usr/bin/lpr, while the CUPS print command is in /usr/local/bin/lpr. In FreeBSD the CUPS command is called lpr-cups, to distinguish it from the native lpr command. Run which -a lpr to check if your system has more then one print command. Scanners are also easy to use from the console, using the SANE collection of tools, for instance: scanimage >image.pnm. Most scanners should be plug-and-play, but check the documentation or Google around if you're having problems. ## Gaming Don't expect the triple A games on your Steam account to work in the console! The console is not a popular gaming platform for obvious reasons, but there are a few simple games that will work. Some of my favorites are myman, sudoku and vitetris (or you can try basted if you like getting frustrated). There is also cpat for all kinds of solitaire fun, and the "racing" games moon-buggy and ztrack. ASCIIpOrtal is an amazingly cool game, even if it's quite obscure and unmaintained. You can find a lot more suggestions, and plenty of online TTY games here. The classic bsdgames and gnuchess (eg. type d2d4 then show board) might also provide some fun for meganerds. ### Strategy Games There are precious few strategy games for the console, but here are a couple of good ol' classics: starlanes is an economic conquest game, and is great fun to play hotseat with a couple of friends (you would have to have some pretty weird friends though). vms-empire (or just empire) is a lot more elaborate, it's sort of basic Civilization for the terminal. Its vi-like interface takes some getting used to though, and you will have to skim through the manual a few times. Here are some quick starting points: After typing a to enter "auto-mode" at the beginning of the game, and a again to produce armies in your city, type y to command your new unit to auto explore. To change a units orders type j to enter "edit-mode". From here you can cancel a units orders with k, or change a city's production with b, hit o to go out of "edit-mode". When you want to quit the game, hit o to go out of "auto-mode", and into "command-mode". This will take effect once you have completed your turn, so move any remaining units until the game finally asks you for a command. At this point you can type s to save, and q to quit. A final tip, you want to start this game with vms-empire -d0! Have Fun :^) ### Framebuffer Games If you are running Linux a few SDL games can actually run in the framebuffer. One example is dosbox, this DOS emulator can run pretty much any old game from the early 90's. If you're a retro gamer like me, dosbox opens up a world of gaming for the console! You need to tweak the ~/.dosbox/dosbox-*.conf setting a bit for programs to work well. These are the settings I use: fullscreen=true fulldouble=false fullresolution=1680x1050 windowresolution=1680x1050 output=overlay usescancodes=false keyboardlayout=us aspect=false scaler=none  Note that the resolutions must match your framebuffer resolution, which is usually the maximum resolution in X. And output must be overlay with no fancy scaler, otherwise fullscreen resolution will not work. Also be sure to disable userscancodes and set a keyboard layout manually, since userscancodes do not work in the framebuffer! scummvm might also works in the framebuffer (it did not in Debian), but getting the resolution right is not easy. You can try something like scummvm -g hq3x, hopefully this will work well enough. ### Roguelikes The big gaming genre on the UNIX console is of course roguelikes. Roguelikes are 2D dungeon exploration RPG games. The name comes from the game rogue, which was the first game in this genre, created way back in the 80's (in fact curses was originally developed for rogue). Sometimes the ancient rogue, hack or larn games are included in the bsdgames package, but players today usually prefer more modern alternatives. The arch typical roguelike of all time is nethack, which might very well be the greatest game ever created! It has been in continuous development for over 30 years (40 if you include the predecessors it is based on), and has surprising depth. You owe it to yourself to die at least once playing this murderously difficult dungeon crawler before you snuff it for good in RL. Other popular alternatives is the action focused crawl, the meta-world games of adom and angband, and the full blown strategy/survival games dwarffortress (Linux and FreeBSD only) and cataclysm (ps: to play dwarffortress in the console, set [PRINT_MODE:TEXT] in ~/.df/data/init/init.txt). There are a great many alternative roguelikes out there. Some of the more obscure ones are also the most interesting, my own personal favorite for instance is an abandoned scify spin of nethack called zapm. You can browse around in roguebasin for more options if you are curious. ### Interactive Fiction Way back in the 70's the legendary game developer Infocom produces a host of interactive fiction games. These games are all text, like an interactive novel. Now, I know what you are thinking: "What?!? No graphics? That cannot be fun!" Well, that's a bit like saying that a book without pictures cannot be fun. It's OK to say that if you're 4, not if you're 40. To quote one of the Infocom developers from the Get Lamp (2010) documentary: «It's all good with high resolution graphics and surround sound, but it is still far away from reality. So what if you make a virtual reality game with 3D glasses? That's a lot better, but you don't feel anything. So how about emerging your body into a sensory simulation capsule. Now we are getting somewhere! But it might not feel like the real thing. So what if we make a direct neural connector to our brain, feeding it our simulation directly? Now we can really live out our fantasy! Of course our imagination could have replaced this high tech solution all along.» Or, to quote Sheldon Couper from The Big Bang Theory; interactive fiction games runs on the most powerful graphic chip known to man, your imagination! These old games can be played in the command line with frotz (getting the Infocom games legally might be a problem though). Interactive fiction games are still being created today, surprising I know, and most of the newer titles can be obtained for free. There are even yearly IF competitions! ### MUD'S As fun as interactive fiction is, it's an introspective and solitary kind of joy, much like enjoying a good novel. Multi User Dungeons, or MUD's, on the other hand, are multiplayer interactive fiction that has been around since the 80's. Many of these MUD's are still around, in fact some are huge virtual realms that will take years to explore, with decades of political history - in real time! Beware: MUD's are insanely addictive! One suggestion is Discworld MUD, this MUD recreates Terry Pratchets world in startling detail (check out the Ankh-Morpork city map - each dot here is a playable location! - and this is just one of the cities in the game). You can play the game from the command line with: telnet discworld.starturtle.net. If you want to have even more enjoyment out of this game, you can buy any of the 41 Discworld novels on Amazon. Other MUDS are available on mudconnect.com ### Edutainment There isn't much edutainment software for the console, but there are some. The bsdgames collection contains a few, such as arithmetic and hangman, which are fairly self explanatory. Another example is quiz, which asks you questions and evaluates your responses. By default quiz contains questions for various topics, such as European capital or Presidential terms. You can either run quiz European capital to get the European nations and guess their capitals, or quiz capital European to get the capitals and guess their European nations. All quizzes can be reversed in this way. The default questions however are usually very dated, even using geography names from the Cold-War era, but you can easily supply your own quiz files, and this radically increases the programs usefulness as a learning tool! Say you wanted to write a quiz to memorize the console commands used in this howto, you could add this line to /usr/share/games/quiz/index (it might be located in a different place on your system - check with locate quiz): /usr/share/games/quiz/console:console_task:command  Now in the /usr/share/games/quiz/console file add these entries: Watch a video:vlc|mplayer Play some music:play|mocp Browse the web:lynx|w3m|links Read your e-mail:mutt|mail Read a PDF file:fbi?pdf View some images:fbi ...  You can now brush up on your console skills with quiz console_task command. Notice that the quiz database allows regex, so the answer to "Browse the web" is either lynx, w3m or links, and the answer to "Read a PDF file" is either fbipdf or fbpdf. You may of course write other more useful quizzes, such as vocabulary trainers when learning another language, or quizzes that help you prepare for an exam. Beyond bsdgames, edutainment software for the console is rare, but one fine exception is typespeed, which is kind of a touch typing game. And i suppose the most useful kind of edutainment is simply reading, a great source of free online books can be found at gutenberg.org. You can read these online with lynx or download them and read them in less. Of course if you really want to challenge your brain, learn to program, and write some edutainment software yourself :^) ### Misc Fun You can have much geeky fun in the console beyond pure gaming. fortune is a classic command from the bsdgames collection that produces random quotations and humorous snippets. It's quite popular to add this program to /etc/motd or your shell configuration file, so that you are always greeted with a random welcome message when you log in. You can also pipe this output (or other text) to various fun filters such as: • cowsay draws an ASCII cartoon around the text • figlet (or toilet), or banner from the bsdgames collection, converts the text to ASCII art banners • lolcat adds spectacular colors to the text • one of the filter from textfilters (aka. filters) such as pirate that converts the text to Pirate slang • rot13 or pig from the bsdgames collection, obfuscate the text If you want to produce a random quote with a random cow (cowsay has many different "cows" to choose from), you can do so with this script: #!/bin/sh # cowfortune - fortune with random cow # usage: cowfortune COWDIR=/usr/share/cowsay/cows COWFILE=$(ls -1 $COWDIR | shuf | head -n 1) fortune | cowsay -f$COWFILE


PS: Beware that some systems include offensive ASCII art with sexual content, whereas others have censored out these cows from the collection. So printing a random "cow" may not be what you want. Of course, you can always manually delete any of the cow files that you find offensive.

You could also do something like this: fortune | pirate | cowsay -f $(ls -l /usr/share/cowsay/cows | shuf | head -n 1) | lolcat Have fun :^) If you're into ASCII art you will probably enjoy the "screensavers" cmatrix and asciiquarium. The bsdgames collection also has a few that you can try out, such as worms -t -d 50 or rain -d 150. Another fun command is sl, which animates an ASCII art steam locomotive traveling across your screen. The joke is that ls is probably the command you type the most, it's easy to mistype it as sl, and when you do the steam locomotive will grieve you for several seconds. FreeBSD has a nice program in its repo called coffeebreak. It's just a shell script that runs a bunch of important looking sysadmin commands that does nothing. The idea is to run coffeebreak at work whenever you need a break, it looks like you are just waiting for something important to finish. Other operating systems do not have this program, but seasoned sysadmins can easily create such a script themselves. Here is one simple way to do it: Install and run ttyrec. Now compile a bunch of stuff, and type exit when you are done. You can then, mv ttyrecord ~/.coffeebreak, and add this to ~/.profile (or ~/.bashrc): alias coffeebreak='while true; do ttyplay ~/.coffeebreak'; done You now have your very own coffeebreak script! To quit the playback, hit Ctrl + c. There are also various Easter eggs in Linux land. A popular example is to add Defaults Insults in /etc/sudoers, which will make sudo rather obnoxious if you mistype your password. Naturally you can make your own internal dad jokes too, I often have the following in my ~/.bashrc: # quirky humor alias playdead=halt alias lazarus=reboot alias woman=man alias dog=cat ...  Judging from various terminal screenshots on the web, many people seem to like neofetch and tty_clock (OpenBSD has its own version of this called grdc). It is easy enough to write scripts with similar functionality yourself though. You could for instance just create an ASCII art logo, possibly with the aid of the aforementioned figlet. You can then colorize it with lolcat. As for the digital clock you can add the command cliclock, which does much the same as tty_clock, and topclock, which will add a digital clock to the upper right corner for your terminal (you can still use your terminal normally), by adding the following aliases to your shell configuration (eg. ~/.profile or ~/.bashrc): alias cliclock='while sleep 1; do clear; date "+%H:%M:%S" | figlet -f smslant; done' alias topclock='while sleep 1; do tput sc; tput cup 0$(($(tput cols)-8)); date "+%H:%M:%S"; tput rc; done &'  You can do a whole lot of fun with telnet too, even in 2018! Here are some suggestions: • telnet towel.blinkenlights.nl: watch Star Wars IV in ASCII • telnet telehack.com, then eliza: talk with a psychotherapist • telnet freechess.org: play chess • telnet rainmaker.wunderground.com: display weather forecast • ssh sshtron.zachlatter.com: multiplayer racing game ## Office ### Reading Documents The arch typical program for reading documents on the command line is less, and for many UNIX users it is a well known tool for text reading. What may come as a surprise though is that less can read a lot more than plain text files. This is due to the fact that less allow a user to specify a preprocessor with the LESSOPEN environment variable. Thus, any file that can be converted to text by some other program, can be viewed automatically in less with the right configuration in place. On most UNIX systems this preprocessor is set to /usr/local/bin/lesspipe.sh or a similar script, which allows less to do a few fancy things like read the contents of a tar archive. You can manually expand the lesspipe.sh script, or even wholesale replace it, to suit your viewing needs. A nice github project that exploits this is here. When you run the provided ./configure script, it checks to see if you have tools such as: antiword to read Microsoft Word documents, xlhtml to read MS Excel documents, pdftotext (from poppler-utils) to read PDF documents, and more. When it has figured out what tools you have available, it builds a corresponding lesspipe.sh script and a few helper scripts. You can then install them simply by running sudo cp lesspipe.sh sxw2txt code2color tarcolor /usr/local/bin, or other suitable location (make sure your LESSOPEN variable points to the correct script. eg. add export LESSOPEN="|/usr/local/bin/lesspipe.sh %s" to your ~/.profile or ~/.bashrc). With this in place you should be able to read quite a few documents with less. But be aware that the quality of document to text rendering varies. There is excellent support for old Microsoft office documents for instance, but not for new ones. The rendering of PDF's will vary depending on the file in question, but it's usually not very good. If you have a framebuffer device available, your best bet is probably to convert your office documents to PDF and read them directly with a PDF reader such as fbipdf. #### LibreOffice The above script has one flaw, it is rather dated. Worse, the tools needed to convert Microsoft Office documents are even less maintained. Luckily LibreOffice has excellent support for converting different document formats, and you can use it without the pesky GUI. Here are some examples: $ soffice --headless --convert-to pdf mydoc.docx ; fbipdf mydoc.pdf
$soffice --headless --convert-to html mydoc.docx ; lynx mydoc.html$ soffice --headless --convert-to odt mydoc.docx ; odt2txt mydoc.odt


#### E-Books

Epubs are actually just zipped HTML files, so in theory you can unzip the file and read the results with lynx or another browser. In practice though it can be quite a mess to figure out which files correspond to the chapters you want. Here is a script I made that tries to sort this out automatically. It's crude, but works quite well in many cases. You are welcome to try it (and improve it).

Other ebook formats may not be that easy to read manually. If you have installed calibre, it comes with the ebook-convert command line tool, which you can use to convert the ebook file into other formats. Some examples:

$ebook-convert mydoc.mobi mydoc.pdf ; fbipdf mydoc.pdf$ ebook-convert mydoc.mobi mydoc.html ; lynx mydoc.html
$ebook-convert mydoc.mobi mydoc.txt ; less mydoc.txt  #### CBR Comic Books CBR comic books are just images archived with rar, you can read them in the console by unrar'ing the file and then view the images with fbi if you have a framebuffer device available (CBZ files are zipped images, so use unzip on them). ### Writing Text and Spell Checking As already mentioned in the Editor Wars section, the classic text editors in UNIX are nano, vi and Emacs, or one of their many variants. There are many other excellent editors besides, far too many to mention. If you just need a quick place to start however, nano has your back. But for serious coding, I recommend learning either vi or Emacs. Both of these editors will require some effort to learn, but they are extremely useful when mastered. You can spell check your files interactively with aspell -c myfile, or aspell -l lang -c myfile, for languages other then English. Not all UNIX's come with aspell (or ispell/hunspell/etc...) by default, but virtually all come with the classic spell checker spell. spell is a very simple program. It checks if your words are found in the systems plain text dictionary (usually in /usr/share/dict/words, you might need to install such a dictionary if it isn't already included, eg. apt install wamerican), if not it just prints the presumably misspelled word. By the way you can manually check for words in this dictionary with the look command. Using spell may at first seem to be very inefficient, since it just hands you a long list of words that you need to manually check and correct yourself. But for precisely that reason it is actually very efficient at teaching you correct spelling. By the way both vim (vi improved) and Emacs have internal spell checkers you can use, :set spell for vim, and Alt + x ispell-buffer for Emacs. But it's just as easy to use aspell from within vi/vim by running :!aspell -c myfile (the Emacs ispell command actually uses aspell as its backend). ### Dictionaries WordNet is a very good English dictionary, you can lookup a word from the command line like so: wn flabbergasted -over (over means "overview"). Sadly there aren't many such alternatives for languages other then English, but you may be able to find a free online dictionary, and if you are very lucky it might even work in lynx. Way back in the 80's UNIX came with the Writer's Workbench suit of tools. Today much of this functionality has been continued with the GNU tools diction and style (both will be included if you install the diction package). diction does basic sanity checks of your documents, such as checking if two identical words are written right next to each other. And style analysis your prose. Of course the tools cannot actually make you a good writer, but they are handy utilities nonetheless (they only support English and German). And like all the classic UNIX tools, it pays great dividends to split your work into many small files (eg. cat chap* > book), otherwise the output from these commands will be overwhelming. ### Writing Documents The closest console equivalent to a typical "word processor" is wordgrinder. It is basically Word Pad for the terminal, so it lets you add a few basic extras to your text documents, such as underlined text, chapter headers or bullet points. Just hit Esc to bring up the main menu. It uses it's own file format by default, but you can export this to other formats, such as ODT, LaTeX or HTML. The problem with word processors though, as with food processors, is that it takes delicious looking input, and returns a messy goo as its output. It may technically be edible, but it ain't pretty! A cleaner, more tasteful, way to write documentation is to use a markup language, and then convert that to a document format, such as PDF or HTML. You can write sloppy HTML quickly with Markdown, Pearlpod, and an assortment of other "shortcut" languages, but, generally, I don't recommend it. Firstly, these tools tend to produce exactly the kind of messy goo that we are trying to avoid. Secondly, writing Troff is just as easy. Tex or HTML requires more effort, but give you more power. And once you go beyond the very basics, these quick and dirty tools tend to have subtle edge cases, requiring just as much knowledge and effort to work around, as it would to write the HTML in the first place. My advice is this: If you want to write in a markup language, learn a real markup language, otherwise, use a word processor. PS: If you have to write Markdown, there are many alternative interpreters, python3-markdown is one of them (the executable may be called markdown_py, or something else, it can vary from system to system). Another famous alternative, on the console at least, is pandoc. This last Markdown interpreter extends the language quite a bit, and tries to be compatible with all document formats known to man. The idea is to quickly write a Markdown document, that you can then convert to PDF, HTML, LaTeX, DocBook, DOCX, ODT or what have you. It sounds nice, put in practice it isn't all that brilliant. But sure, if you love Markdown, it is a quick and dirty way to get things done. #### Troff Troff is the markup language used to write man pages in UNIX, and as such it isn't very impressive. The man pages are just plain text with little formatting finesse. This however is not because troff is primitive, but rather, because the terminal is. By default troff writes output as postscript for printing. If you read the postscript edition of a manpage, you will see that it actually looks like a professional document: $ cp /usr/man/man1/ls.1.gz /tmp && cd /tmp
$gunzip ls.1.gz$ groff -man -T pdf ls.1 > ls.pdf
$dvipdf mydoc.dvi  (PS: Tex is very particular about its syntax, latex will fail to compile the document for instance if you leave out the \end{document} line at the end, or make some such easy mistake). It will look like this: The Tex equivalents to the above mentioned ms macros are: • \par Paragraph, normally you just separate paragraphs with empty lines though. • \noindent Suppress line indentation, or force it with \indent • \section{} Section header, suppress automatic numbering with \section*{} • \date Write todays date • \begin{verbatim} Start literal text block, white space printed as is • \end{verbatim} End literal text block • \footnote{} Add a footnote • \textbf{} Text in bold font • \emph{} Emphasized, or italicized, font • \texttt{} Typewriter, or constant width, font • \linebreak Force a linebreak You can probably find a useful Tex tutorial with a quick Google search (although "latex" might give you some unwarranted results), and there are several useful books on the subject available on Amazon. #### DocBook The other serious competitor to Tex (in terms of popularity at least), is DocBook. It is basically HTML for books. As such, it is only slightly more horrible then plain HTML, if such a thing were possible.* ** *** Here is an example of how you could write the above letter: <!DOCTYPE article PUBLIC "-//OASIS/DTD DocBook XML V4.5//EN" "/usr/share/xml/docbook/xml-dtd-4.5/docbookx.dtd"> <article> <section> <para> <literallayout> To: Archduke Poggle of Geonosis 23 Insectoid Str. Hive 103133 GEONOSIS </literallayout> </para> </section> <section> <para> <literallayout> From: Emperor Palpatine Imperial Palace P0 000001 Senate District CORUSCANT </literallayout> </para> </section> <section> <title>Dear Archduke/title> <para> The so called <emphasis>undefeatable</emphasis> Death Star was blown to bits by a bunch of teenagers yesterday. I must say I am disappointed! We need to construct a new planet killer ASAP, and this time lets try to avoid an <emphasis role="bold">Achilles heel</emphasis> in our design shall we? I have some other ideas for further improvements. First of all we need a menacing throne room with a view... </para> </section> </article>  We can now convert this source document into HTML or other formats, for example assuming you saved this letter as letter.xml you can do this: $ STYLEST=/usr/share/xml/docbook/xsl-stylesheets-1.78.1/html/docbook.xsl
$xsltproc -o letter.html$STYLEST letter.xml


The result will look similar (browser dependent) to this:

There is a bewildering plethora of different DocBook tools available, and the method used to produce DocBook documents can vary greatly. This is just an example. Also note that the docbookx.dtd and docbook.xsl files used here can be located in different places on different systems, check with locate docbookx.dtd docbook.xsl (You might need to install a package or two to get them).

The DocBook equivalents to the above mentioned Tex commands (as with HTML, DocBook tags such as <para> must end with a closing tag, in this case </para>):

• <para> Paragraph, note that this must be within a <section> tag, within a <article> tag (assuming you are writing an article)
• <title> Section Header, must be within a <section> tag.
• <?dbtimestamp format="Y-m-d"?> Print current date.
• <literallayout> Read paragraph literally, preserving spacing and linebreaks.
• <emphasis role="bold"> Text in bold font
• <emphasis> Emphasized, or italicized (usually), font
• <computeroutput> Constant Width fonts (usually).

Writing left-aligned paragraphs, numbered paragraphs, footnotes or linebreaks, can be done with various clever hacks, that is anything but intuitive. Buy a book an Amazon or search the web for tutorials to get the gory details, or better yet, choose a different markup language to write your documents in.

sc is quite a decent spreadsheet for the console. It has its own way of doing things though, so initially you will want to hit ? and spend some time learning the ropes. sc uses its own file format by default, but it can export to LaTeX or tbl (ei. troff) too. Of course sc is a poor substitute for Excel, but then again, Excel is a poor substitute for a database. And there are many professional databases available for UNIX, such as MariaDB and PostgreSQL. For private use though SQLite is probably sufficient:

#### SQLite

Let's apply a popular spreadsheet pass time to our SQL database, making a budget and doing our accounting:

$sqlite3 account.db sqlite> CREATE TABLE account ( id INTEGER PRIMARY KEY, date TEXT DEFAULT CURRENT_DATE, ...> category TEXT DEFAULT 'food', price INTEGER NOT NULL, desc TEXT ); sqlite> INSERT INTO account ( category, price, desc ) ...> VALUES ( 'sweets', 1.25, 'coca cola' ); sqlite> INSERT INTO account ( category, price, desc ) ...> VALUES ( 'sweets', 2.95, 'candy bar' ); sqlite> INSERT INTO account ( date, price ) VALUES ( '2018-04-25', 20.65 ); sqlite> .headers on sqlite> .mode column sqlite> SELECT * FROM account ORDER BY date;  It will produce this output:  id date category price desc ---------------- ---------------- ---------------- ---------------- ---------------- 3 2018-04-25 food 0.65 chewing gum 1 2018-04-26 sweets 1.25 coca cola 2 2018-04-26 sweets 2.95 candy bar  With this database in place you can list particular types of expenses: SELECT * FROM account WHERE category = 'sweets';, or summarize them: SELECT sum(price) AS total FROM account WHERE category = 'sweets';. Type .help for more instructions, and .quit to exit SQLite. Using SQL databases from a shell script is also quite trivial. Here is a simple example: #!/bin/sh # sqlaccount - manage an sql account # usage: sqlaccount [-d date] [-c category] [-s category] [amount comments...] database=$HOME/account.db
if [ ! -f $database ]; then echo "CREATE TABLE account ( id INTEGER PRIMARY KEY, date \ TEXT DEFAULT CURRENT_DATE, category TEXT DEFAULT 'food', price \ INTEGER NOT NULL, desc TEXT );" | sqlite3$database
fi

if [ $# = 0 ]; then echo "SELECT * FROM account ORDER BY date;" | sqlite3 -column$database
exit
fi

date=$(date "+%Y-%m-%d") category=food for args in "$@"; do
case "$args" in -d) date=$2 ; shift 2 ;;
-c) category=$2 ; shift 2 ;; -s) if [$# = 1 ]; then
echo "SELECT sum(price) AS total FROM account;" |
sqlite3 -column $database else echo "SELECT sum(price) AS total FROM account WHERE \ category = '$2';" | sqlite3 -column $database fi exit ;; esac done price=$1
shift

echo "INSERT INTO account ( date, category, price, desc ) VALUES \
( '$date', '$category', $price, '$@');" | sqlite3 $database  You can now do something like this: $ sqlaccount -c sweets 1.25 coca cola
$sqlaccount -c sweets 2.95 candy bar$ sqlaccount -d 2018-04-25 20.65
$sqlaccount 3 2018-04-25 food 20.65 1 2018-04-26 sweets 1.25 coca cola 2 2018-04-26 sweets 2.95 candy bar$ sqlaccount -s
24.85
$sqlaccount -s sweets 4.2  There is a whole heck of a lot you can do with an SQL database, we have only scratched at the very surface here. There are many fine books on this subject on Amazon, and I am sure you can find a useful tutorial if you Google for it. It does require some effort to learn SQL, but once you have done so, you will never need a spreadsheet again! #### AWK You may feel that the above example was far too complicated, and you are absolutely right. In fact if you ever see anyone doing their personal accounting in an SQL database, slap them! (one exaggeration deserves another) It is in fact quite simple to just type in your account information in a plain text editor, and summarize them or query the accounts with sed or awk. Consider this example: 2018-04-25 food 20.65 2018-04-26 sweets 1.25 coca cola 2018-04-26 sweets 2.95 candy bar  You can list all account records for April 2018 by: sed -n '/^2018-04/p' account.txt, or summarize the March expenses by: awk '/^2018-04/ { sum+=$3 } END { print sum }' account.txt. Or if you only want to summarize your candy expenditures for April: awk '/^2018-04.* sweets/ { sum+=$3 } END { print sum }' account.txt. A more elaborate example of an accounting shell script can be found in the Accounting section. Do not be quick to dismiss awk, it can do much more then you think. In section 4.3 of the classic book The AWK Programming Language, for example (if you don't have this in your bookshelf - get it!), the authors demonstrate how a ~50 line awk script enables you to create a relational database spread across multiple files, using column name tags instead of numbers. awk is also fast, unless you are planning to develop a website with hundreds of requests per second, industry grade databases will not give you any significant speed improvements. Best of all, when you have mastered awk, you will find a million other uses for this versatile utility! ### Presentations It is odd that businessmen place so much emphasis on presentations, when they are really just a slideshow of pictures, lightly sprinkled with semi-irrelevant text. There are presentation specific software for the console, such as tpp, you can also create slides with tex or even troff. Another approach is to create a bunch of images with sequential names (eg. 001.jpg, 002.jpg, etc...), and view them with an image viewer like fbi (you can add text to the pictures with ImageMagick if you like). If you want to give tpp a go, read the instructions in /usr/share/doc/tpp/README (it might be located somewhere else on your system). It's fairly straight forwards. tpp uses its own file format, but it can also export to LaTeX. The above tpp screenshot was created with this tpp file: --bgcolor white --fgcolor magenta --newpage --heading A Short Demo of TPP --withborder --center Presentations are written as plain text, --center but you can manipulate the text in various ways. --center For example, you can change --boldon --color red --center font style and color --boldoff --## ulon means "underline on", this is a comment btw --ulon --color blue --center in various ways --uloff --color magenta --center and you can play around with --huge ----Figlet---- --center Thats about it --center Use the arrow keys or space to move around in the slide show. --newpage  ### Math and Graphs For mathematical tasks, bc is the goto tool. You can use it interactively or within your scripts. Just be aware that this calculator doesn't do floating point arithmetic by default, you can either use the -l flag to set the scale to 20 and enable some advanced mathematical functions (sine, cosine, arctangent, logarithms, etc.), or you could just set the scale to the accuracy you need. To demonstrate: $ bc -q
20.2 / 10
2
scale=2
20.2 / 10
2.02
quit
$echo pi =$(echo "4*a(1)" | bc -l)
pi = 3.14159265358979323844


Of course there are other mathematical tools available. For instance, dc is a reverse-polish desk calculator, if you happen to be a 100 years old and like that sort of thing.

As for graphs, the goto program is gnuplot. This program can do any imaginable thing relating to graphs, and then some. But just to get you started, let take a very simple example:

Suppose you have used the above mentioned sqlaccount script to check how much expenses you had from January to December in 2017, and you added these numbers to a text file like so:

01 2104
02 2260
03 1987
04 2053
05 2242
06 2321
07 2107
08 2134
09 2032
10 1934
11 2143
12 2355


You can then use gnuplot to make a graph out of this:

$gnuplot gnuplot> set term pngcairo # you may need to use pdfcairo gnuplot> set title 'Expenditures 2017' gnuplot> set out 'expenditures.png' gnuplot> unset key gnuplot> set grid gnuplot> plot [1:12] 'months.txt' with line gnuplot> quit  You can put these instructions in a file and call gnuplot with gnuplot -c mycommands to use this program non-interactively. If you want gnuplot to export a plain ASCII graph, use set term dumb instead of cairopng. You can see a full list of output formats by typing set term in the gnuplot prompt. The notation [1:12], tells gnuplot to begin drawing the graph at x coordinates 1 (January), and end at x coordinates 12 (December). Most of the other commands here control what the graph will look like. Feel free to experiment with these settings. There are many ways to incorporate gnuplot graphs into your documents. The simplest is just to export the graph as a picture, as we did in the above example, and include this picture in your document (exactly how will depend on what document type you want to create). You can do a lot with gnuplot, and most distributions also bundle some nice demos that you can play with. ### Mindmaps and Flowcharts You can make simple drawings with document markup languages, such as tex or troff (using pic). However, you might not be so interested in the presentation of mindmaps, as the functionality of them. Well, you could just use the filesystem: If you think about it, the hierarchical filesystem in UNIX is a mindmap of sorts. And tools such as ranger and tree can help you visualize it. See the getting organized section for ideas. ### PIM Personal Information Management, or PIM, is a modern buzz word which simply means "getting organized". What this entails in practice depends very much on your needs and tastes. For the minimalist vi is really all you need, but at the other end of the spectrum you have full-blown-command-line-PIM-suits, such as taskwarrior (aka. task, there is also a nice front-end for this, vit). Of course if all you need is a simple todo list, there are programs for that too, such as tdl and many others (org-mode for Emacs is a kind of todo list on steroids). The following sections demonstrate how to write your own simple PIM scripts. These are crude, the point here is to show you some tricks and perhaps inspire you to create your own variations to suit your needs. But even basic scripts can be powerful if you follow careful conventions and keep your files organized, many of these examples (or variations of them) are scripts that I use on a daily basis. #### 2do lists We'll start off by creating a simple 2do list: #!/bin/sh # 2do - a simple 2do list # usage: 2do [list [ id... | task... ]] # set some defaults dir=${dir:-$HOME/.2do} mkdir -p$dir
date=${date:-$(date +%Y-%m-%d)}

# parse arguments
if [ $# = 0 ]; then ls$dir && exit
elif [ $# = 1 ]; then grep -v '^#'$dir/$1 | sort -k 2 exit fi list=$1 ; shift
id=1    # id is either 1 or one more then the highest id
if [ -f $dir/$list ]; then
id=$(awk '{ if($1 > id) id=$1 } END { print id+1 }'$dir/$list) fi # id: remove task; task: add it if (echo "$@" | egrep -q '^[0-9\ ]+$'); then for id in "$@"; do
sed -i "/^$id /s/^/#/"$dir/$list done else echo$id $date "$@" >> $dir/$file
fi


And here is a short demonstration of its use:

$2do shop buy milk$ 2do shop get eggs
$2do shop NEED toilet paper ASAP!$ 2do work finish some project
$2do work start some project$ 2do
shop work
$2do shop 3 2018-06-22 NEED toilet paper ASAP! 2 2018-06-22 get eggs 1 2018-06-22 buy milk$ 2do work
1 2018-06-22 finish some project
2 2018-06-22 start some project
$2do shop 3 1$ 2do shop


This 2do script is very basic, it does not support priorities or tags for instance. You can only add one task at a time, and there is no mechanism for deleting a 2do list, but you can always do that manually: rm $HOME/.2do/mylist. Naturally, these 2do lists can also be opened in any plain text editor, eg. vi$HOME/.2do/mylist.

You can easily augment this script in various ways. You could add priorities and tags for instance, and then sort the lists by priority first, then by date. Since tasks aren't actually removed, but commented out, it is possible to print an ETA based on number of completed tasks since the list got started. Feel free to experiment with it. And once you have made all of these enhancements, and more, take a step back and compare your improved version to the original. Was the extra complexity worth it?

#### Queues

Here is a very simple script, that I find useful in various situations. It basically keeps track of a queue, a plain text list, where each line is a task:

#!/bin/sh
# que - a simple queue tracker
# usage: que [-cp] queue

# set some defaults
dir=${dir:-$HOME/.queues}
mark=${mark:-<--} # parse arguments if [$# = 0 ]; then
ls $dir && exit fi while getopts :cpf: opt; do case "$opt" in
c) clear=yes ;;
p) prcur=yes ;;
f) file=$OPTARG ;; '?') echo "Usage: que [-cp] queue" >&2 && exit 1 ;; esac done shift$(($OPTIND - 1)) file=${file:-$dir/$1}
if [ ! -f "$file" ]; then echo "Error: Queue$file does not exist" >&2 && exit 1
fi

# update the queue
if (grep -q $mark$file); then
task=$(grep -n$mark $file | sed 's/:.*//') else task=1 fi if [ "$prcur" = yes ]; then
if [ $task -gt 1 ]; then sed -n "$(($task - 1))p"$file
fi
exit
fi
sed -i "s/$mark//"$file
if [ "$clear" = yes ]; then exit fi sed -n "${task}p" $file sed -i "$(($task + 1))s/$/$mark/"$file


To use this script you must first write a queue file in $HOME/.queues. It could for instance be called "homework", and look like this: Math: Read chapter 3.12 Math: Do exercises 3.12.1 through 3.12.20 Math: Prep for exam English: Read the poem from Keats English: Write essay on Keats ...  If you now run que homework it will print Math: Read chapter 3.12, and the 2nd line of this text file will change to: Math: Do exercises 3.12.1 through 3.12.20<--. And the next time you run que homework, this line will be printed, and the arrow will be moved to the 3rd line, and so on. The concept here is similar to a 2do list, but useful in situations where you need to do tasks in a sequential order, such as reading chapters of a book. I find this script to be very useful if I want to automate such a task. For instance, are you following a number of TV shows? You could write a queue file for Star Trek for instance, and add this line to your ~/.profile (or ~/.bashrc): alias tos='mplayer$(que tos)'. So that the next time you want to watch Star Trek, just type tos, and it will automatically play the next episode for you.

#### Calendar

The cal command can print a calendar if you need it. To schedule appointments however, the classic UNIX choice is calendar. Practically every version of UNIX has this command, with just one notable exception: Linux. Just one of those little reminders that this operating system does not have deep roots in the UNIX world. Speaking of reminders, remind is a good alternative to calendar, and you can find it in most package repositories. remind also has a nice ncurses front-end, wyrd.

To use calendar (or remind) write your reminders in a plain text file in ~/calendar. Your appointments must start with a date, followed by a tab (not a space), and finally a description that must fit into exactly one line (it can be as long as you want though). For example:

Jan 03    Give borrowed towel back to neighbor
Apr 27    Dentist appointment - flee the country!
May 04    Star Wars marathon!!!


If you now run the command calendar, and it happens to be April the 26th, it will print Apr 27 Dentist appointment - flee the country!. Which will, at the very least, give you a days notice to buy plane tickets. The command will print appointments for today and tomorrow, or on a Friday, from Friday through Monday. Naturally, the trick to making this useful, is to set things up so that reminders are automatically printed whenever you log in to your machine, for example, by adding this command to ~/.profile or ~/.bashrc (the command remind -t1 $HOME/calendar will essentially do the same as the above mentioned calendar command). #### Marking The Calendar The classic calendar command is great in all its simplicity, but there is something gratifying about crossing out dates on a visual calendar in front of your eyes. Perhaps your working on developing a habit, like eating broccoli, and you just have to see all those dates crossed out to keep you motivated. cal will print a calendar, fine, but is there some way to mark it? A good ncurses calendar and 2do list program that can do this is calcurse. Besides being a nice looking curses app, it can export and import to ical formats, which means that you can use it to manage your Google Calendar. But surely we can just write a script ourselves that edits the output from cal? You would think that this is a simple task, but programming is always more complex then we expect (interactivity more so by orders of magnitude). But if you really want a script, here is one suggestion: #!/bin/sh # mcal - mark the calendar # usage: mcal [-f file] [-d month day] [ comments... ] # set some defaults file=$HOME/calendar
if [ "$1" = -f ]; then file=$2
shift 2
fi
year=$(date +%Y) month=$(date +%b | tr A-Z a-z)
day=$(date +%d | sed 's/^0//') if [ "$1" -d ]; then
month=$(echo$2 | tr A-Z a-z)
if (! echo $month | grep -q '^[jfmasond][aepuco][nbrynlgptvc]$'); then
echo Error: month must be a 3 letter english abbreviation (eg. Jan)
exit
fi
day=$3 if [$# = 2 ]; then
shift 2
else
shift 3
fi
fi
case $month in jan) mnr=1 ;; feb) mnr=2 ;; mar) mnr=3 ;; apr) mnr=4 ;; may) mnr=5 ;; jun) mnr=6 ;; jul) mnr=7 ;; aug) mnr=8 ;; sep) mnr=9 ;; oct) mnr=10 ;; nov) mnr=11 ;; dec) mnr=12 ;; esac # no args: print marked calendar if [$# = 0 ]; then
for day in $(awk '/^'$month'/ { print $2 }'$file); do
mark=-
if [ $day -gt 9 ]; then mark=' -' fi cat << eof >> /tmp/mcal-ed g/$day/ \\
s/^$day[^0-9]/ - /\\ s/[^0-9]$day[^0-9]/ $mark /\\ s/[^0-9]$day$/$mark /
eof
done
echo wq >> /tmp/mcal-ed
cal $mnr$year > /tmp/mcal-cal
ed -s /tmp/mcal-cal < /tmp/mcal-ed > /dev/null
cat /tmp/mcal-cal
rm /tmp/mcal*
exit
fi

# args: add entry to calendar
printf "%s %s\t" $month$day >> $file echo "$@" >> $file  Lets ignore the gruesome complexity of this script for now, and just focus on how to use it: The script is compatible with calendar(1) and cal(1). With no arguments mcal will print the cal and replace any dates in your ~/calendar with a single dash (so it "crosses out" the marked dates). If you run mcal with some text, it will add this as an entry in ~/calendar, using todays date by default. So for example, suppose we add this line to our ~/.bashrc: alias broccoli='mcal -f ~/.broccoli-log'. We can now: $ date
Mon Nov 19 14:02:39 CET 2018
$broccoli I ate a whole broccoli today, my will is made of steel!$ broccoli -d nov 18 ate my first vegetable today - I survived!
...
$date Tue Nov 20 13:22:04 CET 2018$ broccoli forced myself to swallow a bite, cant keep this up...
$broccoli November 2018 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 - - - 21 22 23 24 25 26 27 28 29 30$ broccoli -d Oct
October 2018
Su Mo Tu We Th Fr Sa
1  2  3  4  5  6
7  8  9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
$cat .broccoli-log nov 19 I ate a whole broccoli today, my will is made of steel! nov 18 ate my first vegetable today - I survived! nov 20 forced myself to swallow a bite, cant keep this up...  Why does such as easy task require such a complex script? Well, for one the dates needs to work between three programs, calendar, cal and awk. The easiest way to create such a compatibility is to force the convention "jan 1" for January the first. The script will automatically convert a user input, such as "Jan", to lower case. However, if you manually write dates in your ~/calendar file in a different format, they will not work with mcal. But even with this convention in place, some conversion is still required as cal only understands a month number (eg. "jan" must be "1"). Secondly, the process of converting a date, such as "1", to a dash, is surprisingly difficult. For example sed 's/1/-/', will convert this date to a dash, but it will also convert "21" to "2-", "11" to "-1", and so on. So we need to delimit our search: sed 's/[^0-9]1[^0-9]/-/', that is: only convert 1 to a dash if it is preceded and superseded by not-a-number. However, this will not mach our number if it is at the beginning or end of a line, since nothing precedes/supersedes it. So we need three regex searches to match all cases. In addition, the correct amount of whitespace needs to be added for the columns to line up neatly (in this script we use ed rather then sed, since it actually makes things simpler). Note that this script only works for a month at a time, and it only works for the current year. Expanding the script to work across multiple months or years is possible, but complex, and the script is horrible enough as it is. If you really wish to mark a yearly calendar, I suggest you do the following: cal 2018 > mycalendar, then edit it to your hearts content with your favorite editor, or go out and buy a paper calendar and a red pen. I suppose the most useful aspect of this script is that it illustrates how convoluted computer technology can make even trivial tasks. #### Password Manager There are a few password managing utilities out there for the console, but none are really ubiquitous (search your repository for "password"), and this is a very simple task to accomplish with a script anyway. Provided you have a tmpfs /tmp partition, you can safely edit a plain text database of passwords in /tmp, since this will only be written to memory, and then encrypt it to your disk using GnuPG (it might be called gpg or gpg2 on your system): #!/bin/sh # pass - a simple password manager # usage: pass [-e] [ keywords... ] # bugs: assumes a safe tmpfs on /tmp # depends: GnuPG (either gpg or gpg2), EDITOR # set some defaults gpg=$(which gpg 2>/dev/null) || gpg=$(which gpg2 2>/dev/null) || exit 1 file=${file:-$HOME/.passwords.gpg} temp=${temp:/tmp/.passwords}
edit=${EDITOR:-$(which vi 2>/dev/null} || exit 1

# no args: print password file
if [ $# = 0 ]; then$gpg --decrypt $file.gpg exit fi # -d decrypt; -e encrypt; keyword search... trap "rm -f$temp" 0 1 2 15
case $1 in -e)$gpg --decrypt $file >$temp
$edit$temp
$gpg --symmetric$temp
mv $temp.gpg$file ;;
*)  $gpg --decrypt$file.gpg | grep -i "$@" ;; esac  You can write your password database however you want. Personally, I write a tab separated database using these fields: Category Name Username Password Email Website Comments.... But that's just me, however you choose to write your passwords, do so in a single line, and try to be consistent with yourself. You can now search for passwords with pass searchterm. If you later need to add or edit the password database, run pass -e, your changes will automatically be reencrypted to disk when you are done. The script will exit silently if you don't have GnuPG or vi (or other EDITOR) on your system. PS: Make sure that your /tmp partition is a memory filesystem, since you will be editing your passwords in a plain text file. If /tmp is in memory, this isn't a big concern, since the passwords will only exist in memory while you are editing the database, and then safely removed afterwards. But beware of text editors making automatic backups! PPS: Shredding contents of files after writing them to disk is not safe! There is no way to guarantee that data is overwritten on modern harddisks. This simple script can be used to automatically authenticate other services, as an example the following script can be used to search the encrypted database for wireless networks and connect to it: #!/bin/sh # con - manage wifi connections # usage: con name # bugs: assumes a safe tmpfs on /tmp # depends: pass, wifi # set some defaults wlan=${wlan:-wlan0} # change to match your wifi device
temp=${temp:/tmp/$$-wifi} touch temp || exit 1 # query the database trap "rm -f temp" 0 1 2 15 pass "@" > temp matches=(cat temp | wc -l | sed 's/^[ ]*//') case matches in 0) echo Error, cannot find network! ;; 1) name=(awk -F\t '{ print 3 }' temp) pass=(awk -F\t '{ print 4 }' temp) sudo wifi name pass ;; *) awk -F\t '{ print 2, 3, 4 }' temp | column -t ;; esac  The script relies upon the conventions mentioned above, that you store the wifi passwords in a tab separated file encrypted by pass, and that the 3rd field is the network name, the 4th field the password, and so on. The script does not handle the details of actually connecting to a wireless network, since that greatly depends upon which system you are using. Instead it assumes you have a script called wifi, which knows how to do that given the network name and password as arguments. Se the wifi section above for clues on how to write such a script. #### Accounting You can use ledger to manage your accounts, and we already discussed how to make an accounting script yourself with sqlite. But lets explore how to do so with a simple shell script: #!/bin/sh # account - basic account manager # usage: account [-d YYYY-MM-DD][-c catg] [$$.CC [ comments... ]] # depends: budget # set some defaults account=${account:-$HOME/.account} budget=${budget:-$HOME/.budget} date=$(date +%Y-%m-%d)
catg=food
for arg in "$@"; do case "$arg" in
-d) date=$2 && shift 2 ;; -c) catg=$2 && shift 2 ;;
esac
done
if (! echo $date | grep -s '^[12][0-9][0-9][0-9]-[01][0-9]'); then echo Error: invalid date, use the form YYYY-MM-DD exit 1 fi month=$(echo $date | awk -F- '{ print$2 }')
year=$(echo$date | awk -F- '{ print $1 }') # no args, print monthly report if [$# = 0 ]; then
echo Report for $month,$year
grep "^$year-$month" $account | awk -f$budget
exit
fi

# with args, add record to account
amount=$1 if (! echo$amount | egrep '^[0-9]+(\.[0-9][0-9])?$')>/dev/null; then echo Error: invalid number, use the form 100 or 100.00 with no prefix exit 2 fi shift if [ !$catg = income ]; then
amount=-$amount fi echo$date $amount$catg $@ >>$account


This script simply stores account records. It has no understanding of currency, it just assumes all records are expenses and will convert them to negative integers, unless the category is income, in which case the number remains positive. The category defaults to food, since this is assumed to be your most frequently used expense. The date is set to your current date by default. Dates must follow the convention YYYY-MM-DD, but YYYY-MM will suffice if you just want a monthly budget report.

Monthly budget report you say? Ah yes, I haven't shown you how to do that yet. The account script calls an external awk script to produce a report of your expenses if you don't supply it with any arguments. Here is an example of what that script could look like:

BEGIN { printf("%-s\n", "------------------------------") }
/ income/ { income+=$2 } / rent/ { rent+=$2 }
/ food/   { food+=$2 } / car/ { car+=$2 }
{ sum+=$2 } END { printf("%-10s%10.2f %-10s\n", "income:", income, "of 2000") printf("%-10s%10.2f %-10s\n", "rent:", rent, "of -500") printf("%-10s%10.2f %-10s\n", "food:", food, "of -500") printf("%-10s%10.2f %-10s\n", "car:", car, "of -500") printf("%-10s%10.2f %-10s\n", "misc:", sum - (income + (rent + food + car)), "of -500") printf("%-s\n", "------------------------------") printf("%-10s%10.2f\n", "Balance:", sum) }  Of course I assume your own financial status is somewhat more complex then this, but the example given should be clear enough that you can expand and adapt it to your own needs. You could integrate this into the account script so that everything is neatly packed into a single file if you want, but if your budget changes or more than one person uses account, it might be better to keep these files separate (or you could write a smart piece of code that can interpret a simpler user supplied budget). Lets demonstrate how to use account: $ account -d 2018-08-25 -c rent 500
$account -d 2018-08-25 -c income 2000$ account -d 2018-08-26 5 starbucks
$account -c car 254.35$ account 14.50 groceries
$account -c cloths 20 jacket$ account
Report for 08, 2018
------------------------------
income:       2000.00 of 2000
rent:         -500.00 of -500
food:          -19.50 of -500
car:          -254.35 of -500
other:         -20.00 of -500
------------------------------
Balance:      1206.15
$cat .account 2018-08-25 -500 rent 2018-08-25 2000 income 2018-08-26 -5 food starbucks 2018-08-28 -254.35 car 2018-08-28 -14.50 food groceries 2018-08-28 -20 cloths jacket$ grep '^2018-0[6-8]' .account | awk '/cloths/ { cloths+=$2 } END { print cloths }' -20  The account script is very basic, it only supports a single account and has no tag support, but you can use comments for this and you can keep separate accounting files for different accounts. For example, a busy family provider could add this to his ~/.profile: alias work="account=$HOME/.workaccount budget=$HOME/.workbudget account" wife(){ account "$@" wife
}
kids(){
account "$@" kids } self(){ account "$@" beer
}


The last line of the previous demonstration also shows how to summarize all expenses used on cloths for June to August 2018, feel free to play around with awk and gnuplot to mine the database for more useful information. Since the account database is just plain text it is easy to convert and integrate it into other programs (such as SQL), for instance you could convert it to CSV and open it in LibreOffice: sed -e 's/ /,/' -e 's/ /,/' -e 's/ /,/' .account > account.csv ; localc account.csv

Again, this is stupefyingly easy to just do yourself (hint: nano and grep should suffice). If you really want a dedicated program for this abook is a good choice.

But lets elaborate. How would you sync an address book with the contact information in /etc/passwd? Suppose you have a private contact database in $HOME/.tel, which is just a plain text file with the entries "name, address, telephone (work,private), email" per line. You can create a tel command by putting this in$HOME/.bashrc:

tel(){
grep "$@"$HOME/.tel
}


You can now search this database with tel name (or you can search for a number or address or whatever). Now the following script will read all the user contact information in /etc/passwd, ignore any entries that do not contain email addresses (email's can be added by the sysadmin in the other (chfn -o) category) and update your local contact database:

#!/bin/sh
# updatetel - update tel db with /etc/passwd entries
# usage: updatetel

tel=${tel:-$HOME/.tel}
IFS='
'
for entry in $(awk -F: '/@/ { print$5 }' /etc/passwd |\
awk -F, '{ printf("%s\t%s\t%s,%s\t%s\n", $1,$2, $3,$4, $5) }'); do name=$(echo $entry | sed 's/ .*//') if (grep -q "^$name" $tel); then sed -i "s/^$name.*/$entry/"$tel
else
echo $entry >>$tel
fi
done


As long as the sysadmin, or the employees themselves, keep the contact information correct here, the user can run updatetel periodically (eg. once a week with cron), and all the company contacts should be up to date. At the same time the user is free to add whatever private contacts he wants to his own database. And since this database is just a plain text file, it can be easily synced to his home computer, or phone. And it would be trivial to convert the data to a spreadsheet or SQL database, or whatever poison consumers may demand nowadays.

#### Bookmarks

As we have seen, you can read text and PDF files, listen to music and watch video on the console. But this involves fiddling about finding the file first, and worse the program does not usually remember where you left of last time. Is there a way to bookmark PDF files and videos on the console, so that we can automatically continue from where we left of last time, like we expect from fancy desktop document readers and media players? Well, sort of, here is an example:

#!/bin/sh
# bm - bookmark manager
# usage: [ search... ][ -r file... ][ file page comments... ]

# set some defaults
bm=${bm:-$HOME/.bookmarks}
touch $bm # parse arguments if [ "$1" = -r ]; then
remove=yes && shift
fi
if [ $# = 0 ]; then cat$bm && exit
elif [ $# = 1 ]; then matches=$(grep "$1"$bm | wc -l)
if [ $matches = 0 ]; then echo No matches found for$1 && exit
elif [ $matches -gt 1 ]; then grep "$1" $bm && exit else if [ "$remove" = yes ]; then
file=$(echo$1 | sed 's/\//\\\//g')
sed -i "/$file/d"$bm; exit
fi
file=$(grep "$1" $bm | awk '{ print$1 }')
page=$(grep "$1" $bm | awk '{ print$2 }')
if (ps ax | grep X | grep -vq grep); then
# use these on the desktop
case $file in *.pdf) exec xpdf$file $page ;; *.ps) exec gv --page$page $file ;; *.?htm?) exec firefox "file://$file#$page" ;; (*.avi|*.mp*|*.ogg|*.wav) exec mplayer -ss$page $file ;; esac else # use these on the console case$file in
(*.pdf|*.ps) exec fbgs -fp $page$file ;;
*.?htm?) exec lynx "file://$file#$page" ;;
(*.mp3|*.ogg|*.wav) exec mplayer -ss $page$file ;;
# ps: Linux only, also adjust the resolution if necessary
(*.avi|*.mp*)
exec mplayer -vo fbdev2 -vf scale=1366:768 -ss $page$file ;;
esac
fi
# use these for both desktop and console
case $file in *.t?xt) exec vim +$page $file ;; (*.c|*.cpp|Makefile|*.pl|*.rb|*.py|*.php|*.sh) exec vim +$page $file ;; (*.el|*.cl|*.lisp|*.sbcl) exec emacs +$page $file ;; *) echo I don't know how to open$file && exit ;;
esac
fi
fi

# resolve relative/absolute path
if (echo $1 | grep -s '^/'); then file=$1
else
file=$(pwd)/$1
fi
page=$2 # ps: page number is required! shift 2 # update/add entry in bookmarks if (awk '{ print$1 }' $bm | grep -q$file); then
sed -i "s,^.*$file.*$,$file$page $@,"$bm
else
$file$page $@ >>$bm
fi


And a little demonstration of its use:

$bm Documents/p/plan9/fqa.pdf 177 I wonder if you can have Go in Plan9?$ bm Documents/a/articles/example.html some_tag something I ment to publish...
$bm Music/podcast/linuxvoice/lv_s05e17.ogg 1:02:02$ bm Music/podcast/linuxvoice/lv_s05e18.ogg 30:00
$bm /home/dan/Documents/p/plan9/fqa.pdf 177 I wonder if you can have Go in Plan9? /home/dan/Documents/a/articles/example.html some_tag something I ment to publish... /home/dan/Music/podcast/linuxvoice/lv_s05e17.ogg 1:02:02 /home/dan/Music/podcast/linuxvoice/lv_s05e18.ogg 30:00$ bm fqa       # open fqa.pdf on page 177 with xpdf
$bm publish # open example.html at tag "some_tag"$ bm linuxvoice
/home/dan/Music/podcast/linuxvoice/lv_s05e17.ogg 1:02:02
/home/dan/Music/podcast/linuxvoice/lv_s05e18.ogg 30:00
$bm lv_s05e18 # start playing lv_s05e18.ogg 30 minutes into the audio file$ bm Music/podcast/linuxvoice/lv_s05e18.ogg 45:00
$bm -r lv_s05e17$ bm -r example
$bm /home/dan/Documents/p/plan9/fqa.pdf 177 I wonder if you can have Go in Plan9? /home/dan/Music/podcast/linuxvoice/lv_s05e18.ogg 45:00  This script contains some Kong Fu ASCII puke, sed 's/\//\\\//g' is particularly jarring. And to be sure, it is a long and tedious script, but the logic is simple enough, and it should be fairly straight forward to edit the script and adjust your favorite application to their file types. PS: This example is not intended as a magic bullet, you really should edit it to suit your own workflow. Also note, that like a real bookmark, you actually need to place a bookmark in the file you want to save, by supplying a page number (if it's an audio/video file the "page" is the time you stopped playing). You will find that, just closing the book and staring madly at the bookmark for not jumping to the correct page, is of little benefit. If you only want to find a file, use locate or find instead. In theory you could add support for online bookmarking and other things, if you feel hackish (the provided HTML support assumes a local HTML file). Some modification tips: First of all only Linux can play video files in the framebuffer, but you probably need to adjust resolution flags and set things up (see the video section above). You may also wish to change some of the default programs, eg. vim to nano or less, both use the +linenr syntax (you might want to take a chance and just use vim or less if a file prefix wasn't recognized). You can also change both the PDF and Postscript viewer to okular --page or evince --page-index, or a different PDF reader, but be aware that not all viewers support this feature. Finally, you could use vlc --start-time instead of mplayer, but be aware that vlc only supports start time in seconds. You cannot type vlc --start-time 10:00, you must instead use --start-time 600. Of course you could always edit bm so that it converts minutes to seconds, but I leave that as an exercise for the reader. #### Keeping Track of Time You can easily check what the time is with date. Or if you prefer to keep a digital clock around, you can use tty_clock. And naturally tmux comes preconfigured with a digital clock in the lower right corner. If you need to schedule some task at a particular time, commands such as at, cron and anacron can help; if you need to run a one time command, run a server command regularly, or run a laptop command semi-regularly, respectively. The time command is primarily used to measure how much time a program uses before it exits. But you can use it to time yourself. Just type time read, and hit Ctrl + d (this key combo means "end of file") when done. time prints three numbers; system time, relevant for kernel hackers. user time, relevant for hackers. And real time, relevant for real people. Perhaps you need a more elaborate time keeping program though, to measure how much time you spend on various projects. Here is one solution: #!/bin/sh # track - keep track of time # usage: [[-r][-s][ start|stop ] project comments... ] dir=${dir:-$HOME/.track} mkdir -p$dir
output=${output:-60} # ei. output in minutes if [$# = 0 ]; then
for file in $(ls$dir | grep -v ongoing); do
if [ -f $dir/${file}_ongoing ]; then
echo $file '(ongoing)' else echo$file
fi
done
elif [ $# = 1 ]; then cat$dir/$1 elif [$1 = -r ]; then
# remove file
rm $dir/$2
elif [ $1 = -s ]; then # summarize time used on this project awk '{ sum+=$2 } END { print sum }' $dir/$2
elif [ $1 = start ]; then date "+%s" >$dir/${2}_ongoing elif [$1 = stop ]; then
file=$2 shift 2 start=$(cat $dir/${2}_ongoing)
rm $dir/${2}_ongoing
stop=$(date "+%s") time=$(echo "scale=2; ($stop -$start) / $output" | bc) echo$(date "+%Y-%m-%d") $time "$@" >> $dir/$file
fi


You can then use it like so:

$track start work$ track start solitaire
$track stop solitaire all work and no play makes jack a dull boy$ track
work (ongoing)
solitaire
$track solitaire 2018-04-26 5.02 all work and no play makes jack a dull boy$ track -s solitaire
5.02


Again, this script is fanatically simplistic. In particular it's perception of time is very naive. It reports time used in minutes with two decimal points, so 1 hour, 11 minutes and 12 seconds, will be reported as: "71.20." This stupidity is somewhat ironic since the purpose of this program is to help you keep an accurate track of time.

You can modify the output to show a more human readable time format with yet another script, for example:

$humantime(){ > seconds=${1#*.}
> seconds=$(echo "($seconds * 60) / 100" | bc)
> minutes=${1%.*} > hours=$(echo $minutes / 60 | bc) > minutes=$(echo "$minutes - ($hours * 60)" | bc)
> echo $hours hours,$minutes minutes and $seconds seconds > }$ humantime $(track -s solitaire) 0 hours, 5 minutes and 1 seconds  Why isn't this functionality included in the script? After careful consideration I choose not to add it for a couple of reasons: First of all the simplistic format makes it very easy to use the tracking data with external programs, such as drawing a graph with gnuplot. Or you can easily generate reports with it in awk, calculating percentages, and even merge or split tasks if you need to. Such tasks would be massively more complex if track reported time as "1 hour, 11 minutes and 12 seconds." Secondly, and most importantly, I wanted to write a simple example. Handling time correctly is anything but simple. Suppose you wanted to write it in the format "HH:MM:SS", how would you make sure the minutes are exactly two digits (eg. "02" not "2" minutes)? What about the hours? Suppose a project has taken 300 hours, should you split those into days? Of what length, should you use a literal 24 hour day or an 8 hour work day. If you use 8 hour work days, should you skip weekends and holidays? Do you begin to see the problem..? And thus, I lazily give you this crude script, and leave it as an exercise to you dear reader, to extend it to something that's actually useful ;^) ## Console and X Integration The purpose of this howto is explain how to use the console as a desktop, so why are we talking about the X Window System (the classic graphics backend in UNIX)? Well, realistically you may need to dip your toes into a graphical desktop once in a while. Don't be ashamed, even Stallman uses a desktop sometimes. Sadly though there is little convergence between the UNIX console and its desktop, the reason being that the desktop was created later, and without much thought to existing design philosophy. Is it possible then to integrate these two worlds, and thus create an effective working environment also on the desktop? ### Retrieving Console Data The easiest way to move data between the console and the desktop is simply to redirect output to files. For instance say you wanted to import the output of ps ax to LibreOffice, you could do this: $ ps ax | sed 's/^  *//' |
> sed -e 's/  */,/' -e 's/  */,/' -e 's/  */,/' -e 's/  */,/' > ps.csv
$localc ps.csv  This simple but cumbersome sed line converts the first four spaces to commas (there's two spaces in 's/ */,/'), this transforms the data into a comma separated file, which can be opened nicely in LibreOffice Calc (ei. localc). This example illustrates that it is sometimes necessary to transform the text a bit before you can feed it other programs, especially programs that don't follow normal UNIX conventions. Tools such as sed, tr, fmt, not to mention awk, are essential for such tasks. Redirecting text from a graphical program to a file can be more tricky though. The X desktop actually has two clipboards, the classic xclipboard works by first selecting text with left-click and drag, then middle click where you want to paste it. The marked text is automatically copied into the xclipboard, so you don't need to do a manual copy action. The command line tool xclip can be used to manipulate xclipboards. For instance you can find a nice Youtube video in Firefox, mark the URL (Ctrl-L), then type youtube-dl$(xclip -o) in a terminal to download it (of course you could also have typed youtube-dl and middle clicked).

The newer X selections, on the other hand, tries to mimic Microsoft Windows, where you first mark the text, then right-click and select "copy," then right-click and select "paste" (you can also use keyboard shortcuts for this). The command line tool for manipulating these X selections is xsel.

In addition tmux has quite advanced clipboard management that can be integrated with X in various ways. Look into it if your interested :^)

Sometimes you need to move a process, say from the console to a terminal running in the desktop (or vice versa). reptyr is your friend (Linux and FreeBSD only). Another example of its usefulness: Say its late at the office and you want to go home, but you started a long running process over SSH that cannot be interrupted, and you forgot to run tmux first. What do you do? Log in to the server again, run tmux, then use reptyr to move the process over to tmux, you can now kill the ssh session and head on home, the process will continue to run in the detached tmux session.

### Screen Capturing The Console

If you have framebuffer support (Linux only) you can use fbcat or fbgrab to take a screenshot of your console, and ffmpeg can be used to obtain a full video screencapture:

• ffmpeg -f fbdev -framerate 25 -i /dev/fb0 output.mp4, screencapture the raw console
• ffmpeg -f x11grab -y -r 30 -s 1920x1080 -i 0:0 -vcodec huffyuv out.avi, screencapture the desktop from console/terminal
• ffmpeg -video_size 1024x768 -framerate 25 -f x11grab -i :0.0+100,200 -f alsa -ac 2 -i hw:0 output.mkv, screencast with audio using alsa
• ffmpeg -video_size 1024x768 -framerate 25 -f x11grab -i :0.0+100,200 -f pulse -ac 2 -i default output.mkv, screencast with audio using pulseaudio

The last two examples are for desktop recording, but you should be able to tweak them in order to record the framebuffer console (hint use -f fbdev instead of -f x11grab). These last examples is very hardware demanding though, and will likely produce a bad result, a simple workaround is to capture a smaller resolution. Either set a smaller desktop resolution, or capturing a smaller nested X desktop (see Xephyr), or just record a corner of your desktop.

For recording plain text you can use ttyrec or the venerable script tool, note however that script will not work well with interactive applications, such as vi. If you need to record text editing, either use ed or record your vi sessions with ttyrec.

### Putting a Console on the Desktop

The reason working on the console is so efficient, is not because it lacks graphics per say, but rather that it's a text oriented, distraction free environment. Can you create such an environment in X?

Yes. Tiling window managers are the answer. These work essentially as tmux or screen on the console, and there are a great many to choose from. I would personally recommend dwm, its lightweight, easy to use and has all the features you will likely need (there are many other good alternatives). Just get it and read the manpage.

In addition you can replace some graphical applications, and desktop features, with alternatives that are keyboard friendly, and have minimal interfaces. Some suggestions:

• mplayer (or mpv) Video and Music player
• surf (or vimperator in firefox) Web browser
• feh Image viewer
• uxterm Terminal emulator
• xrandr Manage multiple screens and different resolutions
• keynav Do mouse actions with the keyboard (Linux only)
• xscreensaver Screensaver and locker
• scrot Take a screenshot

Naturally you can also use all the console applications mentioned here in an X terminal. Be sure to check out the ASCII art and Retrofuturism sections as well, for some cool tips on making your desktop look retrotastic!

### Putting a Desktop on the Console

We have now talked a bit about moving the console into your desktop, but is it possible to do it the other way around? There are at least two options available for Linux. twin is a simple stacking window manager for the console using ncurses graphics, you can create new terminal windows from its drop down menu, resize windows and move them about with your mouse. Not very useful in my humble opinion, but cool non the less.

Speaking of not-so-useful-but-cool, the libCACA team has created an experimental fork of screen called neercs (that is "screen" spelled backwards). It works much like screen, but has some ridiculous extended features, such as an ASCII 3D spinning desktop cube. You will probably not find it in the repo, but you can get it like so: git clone git://git.zoy.org/neercs.git (PS: This program is buggy, slow and unmaintained. Like Compiz, I would not recommend it for daily use, but its fun to keep around in case you want to knock the socks off some unsuspecting Windows user).

## Conclusion

Most Linux users are vaguely aware that the console exists, and many sysadmins use it daily to administrate their servers, but as we have seen in this article the console can work reasonably well as an everyday desktop. Tasks such as basic HTML browsing, email and chatting works very well in the console. As does playing music and text games. Lastly, office tasks such as writing documents, using spreadsheets and doing PIM related tasks is easy. On a Linux console with a graphical framebuffer enabled, you can even view pictures, PDF's, videos and play graphical games!

There are limitations though. Obviously graphic heavy tasks, such as triple A games and 3D movie production, is not well suited for the humble console. The most painful limitation of all is the lack of a modern web browser. Realistically this limitation cannot be solved, creating a text browser capable of rendering pages as well as Google Chrome, would literally require more effort then recreating the Linux operating system from scratch! Nevertheless, dipping your toes into the console, and learning how to use it efficiently, can greatly boost your productivity. These skills are absolutely useful to have, even on the desktop!

Most of all, it's great fun :^)