Docsity
Docsity

Prepare for your exams
Prepare for your exams

Study with the several resources on Docsity


Earn points to download
Earn points to download

Earn points by helping other students or get them with a premium plan


Guidelines and tips
Guidelines and tips

MCA Docs, MCA Docs, MCA Docs, MCA Docs, MCA Docs, MCA Docs, MCA Docs, MCA Docs, MCA Docs,, Study notes of Computer Science

Study Material & ebooks for MCA, Study Material & ebooks for MCA, Study Material & ebooks for MCA, Study Material & ebooks for MCA, Study Material & ebooks for MCA, Study Material & ebooks for MCA, Study Material & ebooks for MCA, Study Material & ebooks for MCA, Study Material & ebooks for MCA, Study Material & ebooks for MCA, Study Material & ebooks for MCA, Study Material & ebooks for MCA, Study Material & ebooks for MCA, Study Material & ebooks for MCA, Study Material & ebooks for MCA, Study

Typology: Study notes

2021/2022

Uploaded on 01/13/2023

akash-kumar-116
akash-kumar-116 🇮🇳

3 documents

Partial preview of the text

Download MCA Docs, MCA Docs, MCA Docs, MCA Docs, MCA Docs, MCA Docs, MCA Docs, MCA Docs, MCA Docs, and more Study notes Computer Science in PDF only on Docsity! Adventures with the Linux Command Line First Internet Edition William Shotts A LinuxCommand.org Book Copyright ©2014-2021, William Shotts This work is licensed under the Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License. To view a copy of this license, visit the link above or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042. Linux® is the registered trademark of Linus Torvalds. All other trademarks belong to their respective owners. This book is part of the LinuxCommand.org project, a site for Linux education and advocacy devoted to helping users of legacy operating systems migrate into the future. You may visit the LinuxCommand.org project at http s ://linuxcommand.org . Release History Version Date Description 21.10 October 1, 2021 First Internet Edition. Changing to Another Shell..........................................................................................152 Summing Up...............................................................................................................153 Further Reading...........................................................................................................153 10 Vim, with Vigor...................................................................................155 Let’s Get Started..........................................................................................................155 Getting Help................................................................................................................156 Starting a Script...........................................................................................................158 Using the Shell............................................................................................................159 Buffers.........................................................................................................................160 Tabs.............................................................................................................................160 Color Schemes............................................................................................................162 Marks and File Marks.................................................................................................163 Visual Mode................................................................................................................164 Indentation...................................................................................................................164 Power Moves...............................................................................................................167 Text Formatting...........................................................................................................169 Macros.........................................................................................................................172 Registers......................................................................................................................173 Insert Sub-Modes........................................................................................................174 Mapping......................................................................................................................175 Snippets.......................................................................................................................176 Finishing Our Script....................................................................................................177 Using External Commands.........................................................................................178 File System Management and Navigation..................................................................180 One Does Not Live by Code Alone.............................................................................182 More .vimrc Tricks......................................................................................................184 Summing Up...............................................................................................................185 Further Reading...........................................................................................................186 11 source.................................................................................................187 Configuration Files......................................................................................................187 Function Libraries.......................................................................................................188 Let’s Not Forget .bashrc..............................................................................................190 Security Considerations and Other Subtleties.............................................................193 Summing Up...............................................................................................................194 Further Reading...........................................................................................................194 12 Coding Standards Part 1: Our Own.................................................195 A Coding Standard of Our Own..................................................................................196 Summing Up...............................................................................................................208 Further Reading...........................................................................................................208 13 Coding Standards Part 2: new_script.............................................211 Installing new_script...................................................................................................211 Options and Arguments...............................................................................................211 iii Creating Our First Template........................................................................................212 Looking at the Template..............................................................................................214 Summing Up...............................................................................................................217 Further Reading...........................................................................................................218 14 SQL.....................................................................................................219 A Little Theory: Tables, Schemas, and Keys..............................................................219 Database Engines/Servers...........................................................................................221 sqlite3..........................................................................................................................221 Creating a Table and Inserting Our Data.....................................................................222 Creating and Deleting Tables......................................................................................224 Data Types...................................................................................................................224 Inserting Data..............................................................................................................225 Doing Some Queries...................................................................................................225 Controlling the Output................................................................................................226 Sorting Output.............................................................................................................228 Subqueries...................................................................................................................229 Updating Tables...........................................................................................................232 Deleting Rows.............................................................................................................234 Adding and Deleting Columns....................................................................................235 Joins.............................................................................................................................237 Views...........................................................................................................................238 Indexes........................................................................................................................238 Triggers and Stored Procedures..................................................................................240 Performing Backups....................................................................................................242 Generating Your Own Datasets...................................................................................242 Summing Up...............................................................................................................245 Further Reading...........................................................................................................245 Index........................................................................................................247 iv “Amaze your friends! Baffle your enemies!” And the story continues. A long time ago (shortly after I finished college in 1977) I got my first computer, a TRS- 80 model 1. In the early days of personal computing, many computer peripherals, such as printers and floppy disk drives, were very costly and as a result, my dad (an electrical engineer) and I would cruise electronic surplus stores looking for deals on devices we could attach to our new computer. One day, as we were searching a large warehouse near the University of Maryland, I came across a store display featuring a small, clear, plastic box containing a battery, a few computer chips, and several randomly blinking LEDs. While the little device served no useful purpose, it did have blinking lights. Above it hung a handwritten sign that read simply: Amaze Your Friends! Baffle Your Enemies! The excitement pervasive in the early days of personal computing is hard to explain to people today. The computers of that period seem so laughably primitive by today’s standards but it was a revolution nonetheless and there were many explorers mapping the new, uncharted territory of personal empowerment and technical innovation. People entering the computer field now are at a disadvantage compared to those of us who came up in the 1970s and 1980s. The early computers were very simple, slow, and had tiny memories. All the attributes you need if you really want to understand how computers work. Today, computers are so fast, and software so large and complex that you can’t see the computer underneath anymore and that’s a shame. You can’t see the beauty of what they do. However, we are now in the midst of another revolution, extremely low-cost computing. Devices like the Raspberry Pi single board computer offer the opportunity to work on systems more simple and basic compared to contemporary desktop and mobile devices. But make no mistake, these low-cost computers are powerful. In fact, a $35 Raspberry Pi compares favorably to the $30,000 Unix workstations I used in the early 1990s. What this book is about This volume is a sequel/supplement to my first book, The Linux Command Line (TLCL) and as such, we will be referring back to the first book frequently, so if you don’t already have a copy, please download one from LinuxCommand.org or, if you prefer, pickup a printed copy from your favorite bookseller or library. This time around we are going to v 1 Midnight Commander At the beginning of Chapter 4 in TLCL there is a discussion of GUI-based file managers versus the traditional command line tools for file manipulation such as cp, mv, and rm. While many common file manipulations are easily done with a graphical file manager, the command line tools provide additional power and flexibility. In this adventure we will look at Midnight Commander, a character-based directory browser and file manager that bridges the two worlds of the familiar graphical file manager and the common command line tools. The design of Midnight Commander is based on a common concept in file managers: dual directory panes where the listings of two directories are shown at the same time. The idea is that files are moved or copied from the directory shown in one pane to the directory shown in the other. Midnight Commander can do this, and much, much more. Features Midnight Commander is quite powerful and boasts an extensive set of features: • Performs all the common file and directory manipulations such as copying, moving, renaming, linking, and deleting. • Allows manipulation of file and directory permissions. • Can treat remote systems (via FTP or SSH) as though they were local directories. • Can treat archive files (like .tar and .zip) as though they were local directories. • Allows creation of a user-defined “hotlist” of frequently used directories. • Can search for files based on file name or file contents, and treat the search results like a directory. Availability Midnight Commander is part of the GNU project. It is installed by default in some Linux distributions, and is almost always available in every distribution’s software repositories as the package “mc”. Invocation To start Midnight Commander, enter the command mc followed optionally by either 1 or 2 directories to browse at start up. Midnight Commander 1 Screen Layout Midnight Commander screen layout 1. Left and Right Directory Panels The center portion of the screen is dominated by two large directory panels. One of the two panels (called the current panel) is active at any one time. To change which panel is the current panel, press the Tab key. 2. Function Key Labels The bottom line on the display contains function key (F1-F10) shortcuts to the most commonly used functions. 3. Menu Bar The top line of the display contains a set of pull-down menus. These can be activated by pressing the F9 key. 4. Command Line Just above the function key labels there is a shell prompt. Commands can be entered in the usual manner. One especially useful command is cd followed by a directory pathname. This will change the directory shown in the current directory panel. 5. Mini-Status Line At the very bottom of the directory panel and above the command line is the mini- status line. This area is used to display supplemental information about the currently selected item such as the targets of symbolic links. 2 Midnight Commander Directory hotlist To add a directory to the hotlist while browsing, select a directory and type Ctrl-x h. Directory History Each directory panel maintains a list of directories that it has displayed. To access this list, type Alt-H. From the list, a directory can be selected for browsing. Even without the history list display, we can traverse the history list forward and backward by using the Alt-u and Alt-y keys respectively. Using the Mouse We can perform many Midnight Commander operations using the mouse. A directory panel item can be selected by clicking on it and a directory can be opened by double clicking. Likewise, the function key labels and menu bar items can be activated by clicking on them. What is not so apparent is that the directory history can be accessed and traversed. At the top of each directory panel there are small arrows (circled in the image below). Clicking on them will show the directory history (the up arrow) and move forward and backward through the history list (the right and left arrows). There is also an arrow to the extreme lower right edge of the command line which reveals the command line history. Midnight Commander 5 Directory and command line history mouse controls Viewing and Editing Files An activity often performed while directory browsing is examining the content of files. Midnight Commander provides a capable file viewer which can be accessed by selecting a file and pressing the F3 key. File viewer 6 Midnight Commander As we can see, when the file viewer is active, the function key labels at the bottom of the screen change to reveal viewer features. Files can be searched and the viewer can quickly go to any position in the file. Most importantly, files can be viewed in either ASCII (regular text) or hexadecimal, for those cases when we need a really detailed view. File viewer in hexadecimal mode It is also possible to put the other panel into “quick view” mode to view the currently selected file. This is especially nice if we are browsing a directory full of text files and want to rapidly view the files, as each time a new file is selected in the current panel, it’s instantly displayed in the other. To start quick view mode, type Ctrl-x q. Midnight Commander 7 File tagging dialog This dialog stores a history of patterns. To traverse it, use Ctrl up and down arrows. It is also possible to un-tag a group of files. Pressing the / key will cause a pattern entry dialog to display. We Need a Playground To explore the basic file manipulation features of Midnight Commander, we need a “playground” like we had in Chapter 4 of TLCL. Creating Directories The first step in creating a playground is creating a directory called, aptly enough, playground. First, we will navigate to our home directory, then press the F7 key. 10 Midnight Commander Create Directory dialog Type “playground” into the dialog and press Enter. Next, we want the other panel to display the contents of the playground directory. To do this, highlight the playground directory and press Alt-o. Now let’s put some files into our playground. Press Tab to switch the current panel to the playground directory panel. We’ll create a couple of subdirectories by repeating what we did to create playground. Create subdirectories dir1 and dir2. Finally, using the command line, we will create a few files: me@linuxbox: ~/playground $ touch file1 file2 "ugly file" Midnight Commander 11 The playground Copying and Moving Files Okay, here is where things start to get weird. Select dir1, then press Alt-o to display dir1 in the other panel. Select the file file1 and press F5 to copy (The F6-RenMov command is similar). We are now presented with this formidable-looking dialog box: 12 Midnight Commander Using grouping The “?” wildcard behaves the same way. If we make the source mask “???? ????” (which again matches the file ugly file), we now have eight pieces of text that we can rearrange at will. For example, we could make the “to” mask “\8\7\6\5\4\3\2\1”, and the resulting file name would be “elifylgu”. Pretty neat. Midnight Commander can also perform case conversion on file names. To do this, we include some additional escape sequences in the to mask: • \u Converts the next character to uppercase. • \U Converts all characters to uppercase until another sequence is encountered. • \l Converts the next character to lowercase. • \L Converts all characters to lowercase until another sequence is encountered. So if we wanted to change the name ugly file to camel case, we could use the mask “\ u\L\1\u\L\2” and we would get the name UglyFile. Creating Links Midnight Commander can create both hard and symbolic links. They are created using these 3 keyboard commands which cause a dialog to appear where the details of the link can be specified: • Ctrl-x l creates a hard link, in the directory shown in the current panel. Midnight Commander 15 • Ctrl-x s creates a symbolic link in the directory shown in the other panel, using an absolute directory path. • Ctrl-x v creates a symbolic link in the directory shown in the other panel, using a relative directory path. The two symbolic link commands are basically the same. They differ only in the fact that the paths suggested in the Symbolic Link dialog are absolute or relative. We’ll demonstrate creating a symbolic link by creating a link to file1. To do this, we select file1 in the current panel and type Ctrl-x s. The Symbolic Link dialog appears and we can either enter a name for the link or we can accept the program’s suggestion. For the sake of clarity, we will change the name to file1-sym. Symbolic link dialog Setting File Modes and Ownership File modes (i.e., permissions) can be set on the selected or tagged files by typing Ctrl-x c. Doing so will display a dialog box in which each attribute can be turned on or off. If Midnight Commander is being run with superuser privileges, file ownership can be changed by typing Ctrl-x o. A dialog will be displayed where the owner and group owner of selected/tagged files can be set. 16 Midnight Commander Chmod dialog To demonstrate changing file modes, we will make file1 executable. First, we will select file1 and then type Ctrl-x c. The Chmod command dialog will appear, listing the file’s mode settings. By using the arrow keys we can select the check box labeled “execute/search by owner” and toggle its setting by using the space bar. Deleting Files Pressing the F8 key deletes the selected or tagged files and directories. By default, Midnight Commander always prompts the user for confirmation before deletion is performed. We’re done with our playground for now, so it’s time to clean up. We will enter cd at the shell prompt to get the current panel to list our home directory. Next, we will select playground and press F8 to delete the playground directory. Midnight Commander 17 On this dialog we can specify: where the search is to begin, a colon-separated list of directories we would like to skip during our search, any restriction on the names of the files to be searched, and the content of the files themselves. This feature is well-suited to searching large trees of source code or configuration files for specific patterns of text. For example, let’s look for every file in /etc that contains the string “bashrc”. To do this, we would fill in the dialog as follows: Search for files containing “bashrc” Once the search is completed, we will see a list of files which we can view and/or edit. 20 Midnight Commander Search results Panelizing There is a button at the bottom of the search results dialog labeled “Panelize.” If we click it, the search results become the contents of the current panel. From here, we can act on the files just as we can with any others. In fact, we can create a panelized list from any command line program that produces a list of path names. For example, the find program. To do this, we use Midnight Commander’s “External Panelize” feature. Type Ctrl-x ! and the External Panelize dialog appears: Midnight Commander 21 External panelize dialog On this dialog we see a predefined list of panelized commands. Midnight Commander allows us to store commands for repeated use. Let’s try it by creating a panelized command that searches the system for every file whose name has the extension .JPG starting from the current panel directory. Select “Other command” from the list and type the following command into the “Command” field: find . -type f -name "*.JPG" After typing the command we can either press Enter to execute the command or, for extra fun, we can click the “Add new” button and assign our command a name and save it for future use. Subshells We may, at any time, move from the Midnight Commander to a full shell session and back again by pressing Ctrl-o. The subshell is a copy of our normal shell, so whatever environment our usual shell establishes (aliases, shell functions, prompt strings, etc.) will be present in the sub-shell as well. If we start a long-running command in the sub-shell and press Ctrl-o, the command is suspended until we return to the sub-shell. Note that once a command is suspended, Midnight Commander cannot execute any further external commands until the suspended command terminates. 22 Midnight Commander use dash instead. dash is a compact shell program that is sh compatible but lacks many of the features found in bash. The dash man page describes the features of that shell. This command will reveal which program is actually providing the sh emulation (i.e., is symbolically linked to sh): me@linuxbox ~ $ ls -l /bin/sh Macros With that bit of silliness out of the way, let’s look at how we can get a user menu entry to act on currently selected or tagged files. First, it helps to understand a little about how Midnight Commander executes user menu commands. It’s done by writing the commands to a file (essentially a shell script) and then launching sh to execute the contents of the file. During the process of writing the file, Midnight Commander performs macro substitution, replacing embedded symbols in the menu entry with alternate values. These macros are single alphabetic characters preceded by a percent sign. When Midnight Commander encounters one of these macros, it substitutes the value the macro represents. Here are the most commonly used macros: Macro Meaning %f Selected file’s name %x Selected file’s extension %b Selected file’s name stripped of extension (basename) %d Name of the current directory %t The list of tagged files %s If files are tagged, they are used, else the selected file is used. List of common macros Let’s say we wanted to create a user menu entry that would resize a JPEG image using the ever-handy convert program from the ImageMagick suite. Using macros, we could write a menu entry like this, which would act on the currently selected file: # Resize an image using convert R Resize image to fit within 800 pixel bounding square size=800 convert "%f" -resize ${size}x${size} "%b-${size}.%x" Using the %b and %x macros, we are able to construct a new output file name for the resized image. There is still one potential problem with this menu entry. It’s possible to run the menu entry command on a directory, or a non-image file (Doing so would not be good). We could include some extra code to ensure that %f is actually the name of an image file, but Midnight Commander also provides a method for only displaying menu entries appropriate to the currently selected (or tagged) file(s). Midnight Commander 25 Conditionals Midnight Commander supports two types of conditionals that affect the behavior of a menu entry. The first, called an addition conditional determines if a menu entry is displayed. The second, called default conditional sets the default entry on a menu. A conditional is added to a menu entry just before the first line. A conditional starts with either a + (for an addition) or a = (for a default) followed by one or more sub-conditions. Sub-conditions are separated by either a | (meaning or) or a & (meaning and) allowing us to express some complex logic. It is also possible to have a combined addition and default conditional by beginning the conditional with =+ or +=. Two separate conditionals, one addition and one default, are also permitted preceding a menu entry. Let’s look at sub-conditions. They consist of one of the following: Sub-condition Description f pattern Match currently selected file F pattern Match last selected in other panel d pattern Match currently selected directory D pattern Match last selected directory in other panel t type Type of currently selected file T type Type of last selected file in other panel x filename File is executable ! sub-cond Negate result of sub-condition List of sub-conditions pattern is either a shell pattern (i.e., wildcards) or a regular expression according to the global setting configured in the Options/Configuration dialog. This setting can be overridden by adding shell_patterns=0 as the first line of the menu file. A value of 1 forces use of shell patterns, while a value of 0 forces regular expressions instead. type is one or more of the following: Type Description r regular file d directory n not a directory l link x executable file t tagged c character device b block device f FIFO (pipe) s socket List of file types 26 Midnight Commander While this seems really complicated, it’s not really that bad. To change our image resizing entry to only appear when the currently selected file has the extension .jpg or .JPG, we would add one line to the beginning of the entry (regular expressions are used in this example): # Resize an image using convert + f \.jpg$ | f \.JPG$ R Resize image to fit within 800 pixel bounding square size=800 convert "%f" -resize ${size}x${size} "%b-${size}.%x" The conditional begins with + meaning that it’s an addition condition. It is followed by two sub-conditions. The | separating them signifies an “or” relationship between the two. So, the finished conditional means “display this entry if the selected file name ends with .jpg or the selected file name ends with .JPG.” The default menu file contains many more examples of conditionals. It’s worth a look. Summing Up Even though it takes a little time to learn, Midnight Commander offers a lot of features and facilities that make file management easier when using the command line. This is particularly true when operating on a remote system where a graphical user interface may not be available. The user menu feature is especially good for specialized file management tasks. With a little configuration, Midnight Commander can become a powerful tool in our command line arsenal. Further Reading • The Midnight Commander man page is extensive and discusses even more features than we have covered here. • midnight-commander.org is the official site for the project. Midnight Commander 27 Multiple Windows At this point, screen is running and has created its first window . The terminology used by screen is a little confusing. It is best to think of it this way: screen manages a session consisting of one or more windows each containing a shell or other program. Furthermore, screen can divide a terminal display into multiple regions, each displaying the contents of a window. Whew! This will start to make sense as we move forward. In any case, we have screen running now, and it’s displaying its first window. Let’s enter a command in the current window: me@linuxbox: ~ $ top Initial screen window So far, so good. Now, let’s create another window. To do this, we type Ctrl-a followed by the character “c”. Our terminal screen should clear and we should see a new shell prompt. So what just happened to our first window with top running in it? It’s still there, running in the background. We can return to the first window by typing Ctrl-a p (think “p” for “previous”). Before we go any further, let’s talk about the keyboard. Controlling screen is pretty simple. Every command consists of Ctrl-a (called the “command prefix” or “escape sequence”) followed by another character. We have already seen two such commands: Ctrl-a c to create a new window, and Ctrl-a p to switch from the current window to the previous one. Typing the command Ctrl-a ? will display a list of all the commands. 30 Terminal Multiplexers GNU screen has several commands for switching from one window to another. Like the “previous” command, there is a “next” command Ctrl-a n. Windows are numbered, starting with 0, and may be chosen directly by typing Ctrl-a followed by a numeral from 0 to 9. It is also possible list all the windows by typing Ctrl-a ". This command will display a list of windows, where we can choose a window. Screen window list As we can see, windows have names. The default name for a window is the name of the program the window was running at the time of its creation, hence both of our windows are named “bash”. Let’s change that. Since we are running top in our first window, let’s make its name reflect that. Switch to the first window using any of the methods we have discussed, and type the command Ctrl-a A and we will be prompted for a window name. Simple. Okay, so we have created some windows, how do we destroy them? A window is destroyed whenever we terminate the program running in it. After all windows are destroyed, screen itself will terminate. Since both of our windows are running bash, we need only exit each respective shell to end our screen session. In the case of a program that refuses to terminate gracefully, Ctrl-a k will do the trick. Let’s terminate the shell running top by typing q to exit top and then enter exit to terminate bash, thereby destroying the first window. We are now taken to the remaining window still running its own copy of bash. We can confirm this by typing Ctrl-a " to view the window list again. Terminal Multiplexers 31 It’s possible to create windows and run programs without an underlying shell. To do this, we enter screen followed by the name of the program we wish to run, for example: me@linuxbox: ~ $ screen vim ~/.bashrc We can even do this in a screen window. Issuing a screen command in a screen window does not invoke a new copy of screen. It tells the existing instance of screen to carry out an operation like creating a new window. Copy and Paste Given that GNU screen was developed for systems that have neither a graphical user interface nor a mouse, it makes sense that screen would provide a way of copying text from one screen window to another. It does this by entering what is called scrollback mode. In this mode, screen allows the text cursor to move freely throughout the current window and through the contents of the scrollback buffer, which contains previous contents of the window. We start scrollback mode by typing Ctrl-a [. In scrollback mode we can use the arrow keys and the Page Up and Page Down keys to navigate the scrollback buffer. To copy text, we first need to mark the beginning and end of the text we want to copy. This is done by moving the text cursor to the beginning of the desired text and pressing the space bar. Next, we move the cursor to the end of the desired text (which is highlighted as we move the cursor) and press the space bar again to mark the end of the text to be copied. Marking text exits scrollback mode and copies the marked text into screen’s internal buffer. We can now paste the text into any screen window. To do this, we go to the desired window and type Ctrl-a ]. 32 Terminal Multiplexers • screen -d -r detaches a screen session from the previous terminal and reattaches it to the current terminal. • screen -D -R detaches a screen session from the previous terminal, logs the user off the old terminal and attaches the session to the new terminal creating a new session if no session existed. According to the screen documentation, this is the author’s favorite. The -d/-D and -r/-R options can be used independently, but they are most often used together to detach and reattach an existing screen session in a single step. We can demonstrate this process by opening two terminals. Launch screen on the first terminal and create a few windows. Now, go to the second terminal and enter the command screen -D -R. This will the cause the first terminal to vanish (the user is logged off) and the screen session to move to the second terminal fully intact. Customizing Screen Like many of the interactive GNU utilities, screen is very customizable. During invocation, screen reads the /etc/screenrc and ~/.screenrc files if they exist. While the list of customizable features is extensive (many having to do with terminal display control on a variety of Unix and Unix-like platforms), we will concern ourselves with key bindings and startup session configuration since these are the most commonly used. First, let’s look a sample .screenrc file: # This is a comment # Set some key bindings bind k # Un-bind the "k" key (set it to do nothing) bind K kill # Make `Ctrl-a K` destroy the current window bind } history # Make `Ctrl-a }` copy and paste the current # command line # Define windows 7, 8, and 9 at startup screen -t "mdnght cmdr" 7 mc screen -t htop 8 htop screen -t syslog 9 tailf /var/log/syslog As we can see, the format is pretty simple. The bind directive is followed by the key and the screen command it is to be bound to. A complete list of the screen commands can found in the screen man page. All of the screen commands we have discussed so far are simply key bindings like those in the example above. We can redefine them at will. The three lines at the end of our example .screenrc file create windows at startup. The commands set the window title (the -t option), a window number, and a command for the window to contain. This way, we can set up a screen session to be automatically built Terminal Multiplexers 35 when we start screen which contains a complete multi-window, command-line environment running all of our favorite programs. tmux Despite its continuing popularity, GNU screen has been criticized for its code complexity (to the point of being called “unmaintainable”) and its resource consumption. In addition, it is reported that screen is no longer actively developed. In response to these concerns, a newer program, tmux, has attracted widespread attention. tmux is modern, friendlier, more efficient, and generally superior to screen in most ways. Conceptually, tmux is very similar to screen in that it also supports the concept of sessions, windows and regions (called panes in tmux). In fact, it even shares a few keyboard commands with screen. Availability tmux is widely available, though not as widely as screen. It’s available in most distribution repositories. The package name is “tmux”. Invocation The program is invoked with the command tmux new to create a new session. We can optionally add -s <session_name> to assign a name to the new session and -n <window_name> to assign a name to the first window. If no option to the new command is supplied, the new itself may be omitted; it will be assumed. Here is an example: me@linuxbox: ~ $ tmux new -s "my session" -n "window 1" Once the program starts, we are presented with a shell prompt and a pretty status bar at the bottom of the window. 36 Terminal Multiplexers Initial tmux window Multiple Windows tmux uses the keyboard in a similar fashion to screen, but rather than using Ctrl-a as the command prefix, tmux uses Ctrl-b. This is good since Ctrl-a is used when editing the command line in bash to move the cursor to the beginning of the line. Here are the basic commands for creating windows and navigating them: Command Description Ctrl-b ? Show the list of key bindings (i.e., help) Ctrl-b c Create a new window Ctrl-b n Go to next window Ctrl-b p Go to previous window Ctrl-b 0 Go to window 0. Numbers 1-9 are similar. Ctrl-b w Show window list. The status bar lists windows, too. Ctrl-b , Rename the current window tmux window commands Multiple Panes Like screen, tmux can divide the terminal display into sections called panes. However, unlike the implementation of regions in screen, panes in tmux do not merely provide viewports to various windows. In tmux they are complete pseudo-terminals associated with the window. Thus a single tmux window can contain multiple terminals. Terminal Multiplexers 37 Text marked for copying As with the digital clock, we return to normal mode by typing “q”. Now we can paste our copied text by typing Ctrl-b ]. Detaching Sessions With tmux it’s easier to manage multiple sessions than with screen. First, we can give sessions descriptive names, either during creation, as we saw with our “PaneDemo” example above, or by renaming an existing session with Ctrl-b $. Second, it’s easy to switch sessions on-the-fly by typing Ctrl-b s and choosing a session from the presented list. While we are in a session, we can type Ctrl-b d to detach it and, in essence, put tmux into the background. This is useful if we want to create new a session by entering the tmux new command. If we start a new terminal (or log in from a remote terminal) and wish to attach an existing session to it, we can issue the command tmux ls to display a list of available sessions. To attach a session, we enter the command tmux attach -d -t <session_name>. The “-d” option causes the session to be detached from its previous terminal. Without this option, the session will be attached to both its previous terminal and the new terminal. If only one session is running, a tmux attach will connect to it and leave any existing connections intact. 40 Terminal Multiplexers Customizing tmux As we would expect, tmux is extremely configurable. When tmux starts, it reads the files /etc/tmux.conf and ~./.tmux.conf if they exist. It is also possible to start tmux with the -f option and specify an alternate configuration file. This way, we can have multiple custom configurations. The number of configuration commands is extensive, just as it is with screen. The tmux man page has the full list. As an example, here is a hypothetical configuration file that changes the command prefix key from Ctrl-b to Ctrl-a and creates a new session with 4 windows: # Sample tmux.conf file # Change the command prefix from Ctrl-b to Ctrl-a unbind-key C-b set-option -g prefix C-a bind-key C-a send-prefix ##### # Create session with 4 windows ##### # Create session and first window new-session -d -s MySession # Create second window and vertically split it new-window split-window -d -h # Create third window (and name it) running Midnight Commander new-window -d -n MdnghtCmdr mc # Create fourth window (and name it) running htop new-window -d -n htop htop # Give focus to the first window in the session select-window -t 0 Since this configuration creates a new session, we should launch tmux by entering the command tmux attach to avoid the default behavior of automatically creating a new session. Otherwise, we end up with an additional and unwanted session. Here’s a useful configuration file that remaps the keys used to create panes and changes copy and paste to behave more like vim. # Change bindings for pane-splitting from " and % to | and - unbind '"' unbind % bind | split-window -h bind - split-window -v # Enable mouse control (clickable windows, panes, resizable panes) set -g mouse on # Set color support to allow visual mode highlighting to work in vim Terminal Multiplexers 41 set -g default-terminal "screen-256color" # Make copy work like vi # Start copy ^b-[ # Use vi movement keys (arrows, etc.) # Select with v, V # Yank and end copy mode with y # Paste with ^b-] # View all vi key bindings with ^b-: followed with list-keys -T copy-mode-vi set-window-option -g mode-keys vi bind-key -T copy-mode-vi 'v' send -X begin-selection bind-key -T copy-mode-vi 'y' send -X copy-selection-and-cancel byobu byobu (pronounced “BEE-oh-boo”) from the Japanese word for “a folding, decorative, multi-panel screen” is not a terminal multiplexer per se, but rather, it is a wrapper around either GNU screen or tmux (the default is tmux). It aims to create a simplified user interface with an emphasis on presenting useful system information on the status bar. Availability byobu was originally developed by Canonical employee Dustin Kirkland, and as such is usually found in Ubuntu and other Debian-based distributions. Recent versions are more portable than the initial release, and it is beginning to appear in a wider range of distributions. It is distributed as the package “byobu”. Invocation byobu can be launched simply by entering the command byobu followed optionally by any options and commands to be passed to the backend terminal multiplexer (i.e., tmux or screen). For this adventure, we will confine our discussion to the tmux backend as it supports a larger feature set. 42 Terminal Multiplexers Status notifications Here we can choose from a wide variety of system status information to be displayed. Very useful if we are monitoring remote servers. The second is the Shift-F12 key, which disables byobu from interpreting the functions keys as commands. This is needed in cases where a text-based application (such as Midnight Commander) needs the function keys. Pressing Shift-F12 a second time re- enables the function keys for byobu. Unfortunately, byobu gives no visual indication of the state of the function keys, making this feature rather confusing to use in actual practice. Copy Mode byobu provides an interface to the copy mode of its backend terminal multiplexer. For tmux, it’s slightly simplified from normal tmux, but works about the same. Here are the key commands: Command Description Alt-PgUp Enter copy mode Space Start text selection Enter End text selection, copy text, and exit copy mode Alt-Insert Paste selected text byobu copy commands Terminal Multiplexers 45 Detaching Sessions To detach a session and log off, press the F6 key. To detach without logging off, type Shift-F6. To attach, simply enter the byobu command and the previous session will be reattached. If more than one session is running, we are prompted to select a session. While we are in a session, we can type Alt-Up and Alt-Down to move from session to session. Customizing byobu The local configuration file for byobu is located in either ~/.byobu/.tmux.conf or ~/.config/byobu/.tmux.conf, depending on the distribution. If one doesn’t work, try the other. The configuration details are the same as for tmux. Summing Up We have seen how a terminal multiplexer can enhance our command-line experience by providing multiple windows and sessions, as well as multiple regions on a single terminal display. So, which one to choose? GNU screen has the benefit of being almost universally available, but is now considered by many as obsolete. tmux is modern and well supported by active development. byobu builds on the success of tmux with a simplified user interface, but if we rely on applications that need access to the keyboard function keys, byobu becomes quite tedious. Fortunately, many Linux distributions make all three available, so it’s easy to try them all and see which one satisfies the needs at hand. Further Reading The man pages for screen and tmux are richly detailed. Well worth reading. The man page for byobu is somewhat simpler. GNU Screen • Official site: https://www.gnu.org/software/screen/ • A helpful entry in the Arch Wiki: https://wiki.archlinux.org/index.php/GNU_Screen • A Google search for “screenrc” yields many sample .screenrc files • Also look for sample files in /usr/share/doc/screen/examples tmux • Official site: https://www.gigastudio.com.ua • The tmux FAQ: https://github.com/tmux/tmux/wiki/FAQ • A helpful entry in the Arch Wiki: https://wiki.archlinux.org/index.php/tmux • A Google search for “tmux.conf” yields many sample .tmux.conf files • Also look for sample files in /usr/share/doc/tmux/examples 46 Terminal Multiplexers byobu • Official site: https://www.byobu.org • Answers to many common questions: https://askubuntu.com/tags/byobu/hot Terminal Multiplexers 47 As we recall from TLCL, shell functions are miniature shell scripts that we can add to our .bashrc file to perform anything that we may otherwise do with a shell script. Here is an example function that displays a quick snapshot of a system’s health: status() { { echo -e "\nuptime:" uptime echo -e "\ndisk space:" df -h 2> /dev/null echo -e "\ninodes:" df -i 2> /dev/null echo -e "\nblock devices:" blkid echo -e "\nmemory:" free -m if [[ -r /var/log/syslog ]]; then echo -e "\nsyslog:" tail /var/log/syslog fi if [[ -r /var/log/messages ]]; then echo -e "\nmessages:" tail /var/log/messages fi } | less } Unlike aliases, shell functions can accept positional parameters: params() { local argc=0 while [[ -n $1 ]]; do argc=$((++argc)) echo "Argument $argc = $1" shift done } Command Line Editing Aliases and shell functions are all well and good, provided we know in advance the operations we wish to perform, but what about the rest of the time? Most command line operations we perform are on-the-fly, so other techniques are needed. As we saw in Chapter 8 of TLCL, the bash shell includes a library called readline to handle keyboard input during interactive shell sessions. This includes text typed at the shell prompt and keyboard input using the read builtin when the -e option is specified. The readline library supports a large number of commands that can be used to edit what we type at the command line. Since readline is from the GNU project, many of the commands are taken from the emacs text editor. 50 Less Typing Control Commands Before we get to the actual editing commands, let’s look at some commands that are used to control the editing process. Command Description Enter Pressing the enter key causes the current command line to be accepted. Note that the cursor location within the line does not matter (i.e., it doesn’t have to be at the end). If the line is not empty, it is added to the command history. Esc Meta-prefix. If the Alt key is unavailable, the Esc key can be used in its place. For example, if a command calls for Alt-r but another program intercepts that command, press and release the Esc key followed by the r key. Ctrl-g Abort the current editing command. Ctrl-_ Incrementally undo changes to the line. Alt-r Revert all changes to the line (i.e., complete undo). Ctrl-l Clear the screen. Alt-num Where num is a number. Some commands accept a numeric argument. For those commands that accept it, type this first followed by the command. Editing control commands Moving Around Here are some commands to move the cursor around the current command line. In the readline documentation, the current cursor location is referred to as the point. Command Description Right Move forward one character. Left Move backward one character. Alt-f Move forward one word. Alt-b Move backward one word. Ctrl-a Move to the beginning of the line. Ctrl-e Move to the end of the line. Cursor movement commands Using Command History In order to save typing, we frequently reuse previously typed commands stored in the command history. We can move up and down the history list and the history list can be searched. Command Description Up Move to previous history list entry. Down Move to next history list entry. Less Typing 51 Command Description Alt-< Move to the beginning of the history list. Alt-> Move to the end of the history list. Ctrl-r Perform an incremental history search starting at the current position and moving up the history list. After a command is typed, a prompt appears and with each succeeding character typed, the position within the list moves to the next matching line. This is probably the most useful of the history search commands. Ctrl-s Like Ctrl-r except the search is performed moving down the history list. Alt-p Perform a non-incremental search moving up the history list. Alt-n Perform a non-incremental search moving down the history list. Alt-Ctrl-y Insert the first argument from the previous history entry. This command can take a numeric argument. When a numeric argument is given, the nth argument from the previous history entry is inserted. Alt-. Insert the last argument from the previous history entry. When a numeric argument is given, behavior is the same as Alt-Ctrl-y above. History commands Changing Text Command Description Ctrl-d Delete the character at the point. Ctrl-t Transpose characters. Exchange the character at the point with the character preceding it. Alt-t Transpose words. Exchange the word at the point with the word preceding it. Alt-u Change the current word to uppercase. Alt-l Change the current word to lowercase. Alt-c Capitalize the current word. Editing commands Cutting and Pasting As with vim, cutting and pasting in readline are referred to as “killing” and “yanking.” The clipboard is called the kill-ring and is implemented as a circular buffer. This means that it contains multiple entries (i.e., each kill adds a new entry). The latest entry is referred to as the “top” entry. It is possible to “rotate” the kill-ring to bring the previous entry to the top and delete the latest entry. However, this feature is rarely used. Mostly, the kill commands are used to simply delete text rather than save it for later yanking. 52 Less Typing generally available for others. To check for the package, examine the /etc/bash- completion.d directory. If it exists, the package is installed. The bash-completion package adds support for many command line programs, allowing us to perform completion on both command options and arguments. The ls command is a good example. If we type “ls –” then the Tab key a couple of times, we will see a list of possible options to the command: me@linuxbox: ~ $ ls -- --all --ignore= --almost-all --ignore-backups --author --indicator-style= --block-size= --inode --classify --literal --color --no-group --color= --numeric-uid-gid --context --quote-name --dereference --quoting-style= --dereference-command-line --recursive --dereference-command-line-symlink-to-dir --reverse --directory --show-control-chars --dired --si --escape --size --file-type --sort --format= --sort= --group-directories-first --tabsize= --help --time= --hide= --time-style= --hide-control-chars --version --human-readable --width= An option can be completed by typing a partial option followed by Tab. For example, typing “ls –ver” then Tab will complete to “ls –version”. The bash-completion system is interesting in its own right as it is implemented by a series of shell scripts that make use of the complete and compgen bash builtins. The main body of the work is done by the /etc/bash_completion (or /usr/share/bash- completion/bash_completion in newer versions) script along with additional scripts for individual programs in either the /etc/bash-completion.d directory or the /usr/share/bash-completion/completions directory. These scripts are good examples of advanced scripting technique and are worthy of study. Summing Up This adventure is a lot to take in and it might not seem all that useful at first, but as we continue to gain experience and practice with the command line, learning these labor- saving tricks will save us a lot of time and effort. Less Typing 55 Further Reading • “The beginning of time” actually has meaning in Unix-like operating systems such as Linux. It’s January 1, 1970. See: https://en.wikipedia.org/wiki/Unix_time for details. • Aliases and shell functions are discussed in Chapters 5 and 26, respectively, of The Linux Command Line: https://linuxcommand.org/tlcl.php. • The READLINE section of the bash man page describes the many keyboard shortcuts available on the command line. • The HISTORY section of the bash man page covers the command line history features of bash. • The official home page of the bash-completion project: https://github.com/scop/bash-completion • For those readers interested in learning how to write their own bash completion scripts, see this tutorial at the Linux Documentation Project: https://tldp.org/LDP/abs/html/tabexpansion.html. 56 Less Typing 4 More Redirection As we learned in Chapter 6 of TLCL, I/O redirection is one of the most useful and powerful features of the shell. With redirection, our commands can send and receive streams of data to and from files and devices, as well as allow us to connect different programs together into pipelines. In this adventure, we will look at redirection in a little more depth to see how it works and to discover some additional features and useful redirection techniques. What’s Really Going On Whenever a new program is run on the system, the kernel creates a table of file descriptors for the program to use. File descriptors are pointers to files. By convention, the first 3 entries in the table (descriptors 0, 1, and 2) are used as standard input (stdin), standard output (stdout), and standard error (stderr). Initially, all three descriptors point to the terminal device (which the system treats as a read/write file), so that standard input comes from the keyboard and standard output and standard error go to the terminal display. When a program is started as a child process of another (for instance, when we run an executable program in the shell), the newly launched program inherits a copy of the parent’s file descriptor table. Redirection is the process of manipulating the file descriptors so that input and output can be routed from/to different files. The shell hides the presence of file descriptors in common redirections such as: command > file Here we redirect standard output to a file, but the full syntax of the redirection operator includes an optional file descriptor. We could write the above statement this way and it would have exactly the same effect: command 1> file As a convenience, the shell assumes we want to redirect standard output if the file descriptor is omitted. Likewise, the following two statements are equivalent when referring to standard input: command < file command 0< file More Redirection 57 exec 3> /dev/tty # open fd 3 and point to controlling terminal count=0 while read; do # read line from stdin echo "$REPLY" # send line to stdout ((count++)) printf "\b\b\b\b\b\b%06d" $count >&3 done echo " Lines Counted" >&3 exec 3>&- # close fd 3 This program simply copies standard input to standard output, but it displays a running count of the number of lines that it has copied. If we invoke it this way, we can see it in action: me@linuxbox ~ $ find /usr/share | ./counter-exec > ~/find_list.txt In this pipeline example, we generate a list of files using find, and then count them before writing the list in a file named find_list.txt. The script works by reading a line from the standard input and writing the REPLY variable (which contains the line of text from read) to standard output. The printf format specifier contains a series of six backspaces and a formatted integer that is always six digits long padded with leading zeros. /dev/tty The mysterious part of the script above is the exec. The exec is used to open a file using file descriptor 3 which is set to point to /dev/tty. /dev/tty is one of several special files that we can access from the shell. Special files are usually not “real” files in the sense that they are files that exists on a physical disk. Rather, they are virtual like the files in the /proc directory. The /dev/tty file is a device that always points to a program’s controlling terminal, that is, the terminal that is responsible for launching the program. If we run the command ps aux on our system, we will see a listing of every process. At the top of the listing is a column labeled “TTY” (short for “Teletype” reflecting its historical roots) that contains the name of the controlling terminal. Most entries in this column will contain “?” meaning that the process has no controlling terminal (the process was not launched interactively), but others will contain a name like “pts/1” which refers to the device /dev/pts/1. The term “pty” means pseudo-terminal, the type of terminal used by terminal emulators rather than actual physical terminals. Noclobber When the shell encounters a command with output redirection, such as: command > file 60 More Redirection the first thing that happens is that the output stream is started by either creating file or, if file already exists, truncating it to zero length. This means that if command completely fails or doesn’t even exist, file will end up with zero length. This can be a safety issue for new users who might overwrite (or truncate) a valuable file. To avoid this, we can do one of two things. First we can use the “>>” operator instead of “>” so that output will be appended to the end of file rather than the beginning. Second, we can set the “noclobber” shell option which prevents redirection from overwriting an existing file. To activate this, we enter: set -o noclobber Once we set this option, attempts to overwrite an existing file will cause the following error: bash: file: cannot overwrite existing file The effect of the noclobber option can be overridden by using the >| redirection operator like so: command >| file To turn off the noclobber option we enter this command: set +o noclobber Summing Up While this adventure may be more on the “interesting” side than the “fun” side, it does provide some useful insight into how redirection actually works and some of the interesting ways we can use it. In a later adventure, we will put this new knowledge to work expanding the power of our scripts. Further Reading • A good visual tutorial can be found at The Bash Hackers Wiki: https://wiki.bash- hackers.org/howto/redirection_tutorial • For a little background on file descriptors, see this Wikipedia article: https://en.wikipedia.org/wiki/File_descriptor • This Linux Journal article covers using exec to manage redirection: https://www.linuxjournal.com/content/bash-redirections-using-exec • The Linux Command Line covers redirection in Chapters 6 (main discussion), 25 (here documents), 28 (here strings), and 36 (command grouping, subshells, process substitution, named pipes). • The REDIRECTION section of the bash man page, of course, has all the details. More Redirection 61 There are many different terminal types defined in the terminfo database and there are many terminal capnames. The terminfo man page contains a complete list. Note, however, that in general practice, there are only a relative handful of capnames supported by all of the terminal types we are likely to encounter on Linux systems. Reading Terminal Attributes For the following capnames, tput outputs a value to stdout: Capname Description longname Full name of the terminal type lines Number of lines in the terminal cols Number of columns in the terminal colors Number of colors available Capability names The lines and cols values are dynamic. That is, they are updated as the size of the terminal window changes. Here is a handy alias that creates a command to view the current size of our terminal window: alias term_size=`echo "Rows=$(tput lines) Cols=$(tput cols)"' If we define this alias and execute it, we will see the size of the current terminal displayed. If we then change the size of the terminal window and execute the alias a second time, we will see the values have been updated. One interesting feature we can use in our scripts is the SIGWINCH signal. This signal is sent each time the terminal window is resized. We can include a signal handler (i.e., a trap) in our scripts to detect this signal and act upon it: #!/bin/bash # term_size2 - Dynamically display terminal window size redraw() { clear echo "Width = $(tput cols) Height = $(tput lines)" } trap redraw WINCH redraw while true; do : done With this script, we start an empty infinite loop, but since we set a trap for the SIGWINCH signal, each time the terminal window is resized the trap is triggered and the new terminal size is displayed. To exit this script, we type Ctrl-c. tput 65 term_size2 Controlling the Cursor The capnames below output strings containing control codes that instruct the terminal to manipulate the cursor: Capname Description sc Save the cursor position rc Restore the cursor position home Move the cursor to upper left corner (0,0) cup <row> <col> Move the cursor to position row, col cud1 Move the cursor down 1 line cuu1 Move the cursor up 1 line civis Set to cursor to be invisible cnorm Set the cursor to its normal state Cursor control capnames We can modify our previous script to use cursor positioning and to place the window dimensions in the center as the terminal is resized: #!/bin/bash # term_size3 - Dynamically display terminal window size # with text centering redraw() { local str width height length width=$(tput cols) height=$(tput lines) str="Width = $width Height = $height" 66 tput length=${#str} clear tput cup $((height / 2)) $(((width / 2) - (length / 2))) echo "$str" } trap redraw WINCH redraw while true; do : done As in the previous script, we set a trap for the SIGWINCH signal and start an infinite loop. The redraw function in this script is a bit more complicated, since it has to calculate the center of the terminal window each time its size changes. term_size3 Text Effects Like the capnames used for cursor manipulation, the following capnames output strings of control codes that affect the way our terminal displays text characters: Capname Description bold Start bold text smul Start underlined text rmul End underlined text rev Start reverse video blink Start blinking text invis Start invisible text smso Start “standout” mode tput 67 # tput_colors - Demonstrate color combinations. for fg_color in {0..7}; do set_foreground=$(tput setaf $fg_color) for bg_color in {0..7}; do set_background=$(tput setab $bg_color) echo -n $set_background$set_foreground printf ' F:%s B:%s ' $fg_color $bg_color done echo $(tput sgr0) done tput_colors Clearing the Screen These capnames allow us to selectively clear portions of the terminal display: Capnam e Description smcup Save screen contents rmcup Restore screen contents el Clear from the cursor to the end of the line el1 Clear from the cursor to the beginning of the line ed Clear from the cursor to the end of the screen clear Clear the entire screen and home the cursor Screen erasure capnames Using some of these terminal capabilities, we can construct a script with a menu and a separate output area to display some system information: #!/bin/bash 70 tput # tput_menu: a menu driven system information program BG_BLUE="$(tput setab 4)" BG_BLACK="$(tput setab 0)" FG_GREEN="$(tput setaf 2)" FG_WHITE="$(tput setaf 7)" # Save screen tput smcup # Display menu until selection == 0 while [[ $REPLY != 0 ]]; do echo -n ${BG_BLUE}${FG_WHITE} clear cat <<- _EOF_ Please Select: 1. Display Hostname and Uptime 2. Display Disk Space 3. Display Home Space Utilization 0. Quit _EOF_ read -p "Enter selection [0-3] > " selection # Clear area beneath menu tput cup 10 0 echo -n ${BG_BLACK}${FG_GREEN} tput ed tput cup 11 0 # Act on selection case $selection in 1) echo "Hostname: $HOSTNAME" uptime ;; 2) df -h ;; 3) if [[ $(id -u) -eq 0 ]]; then echo "Home Space Utilization (All Users)" du -sh /home/* 2> /dev/null else echo "Home Space Utilization ($USER)" du -s $HOME/* 2> /dev/null | sort -nr fi ;; 0) break ;; *) echo "Invalid entry." ;; esac printf "\n\nPress any key to continue." read -n 1 done # Restore screen tput rmcup echo "Program terminated." tput 71 tput_menu Making Time For our final exercise, we will make something useful; a large character clock. To do this, we first need to install a program called banner. The banner program accepts one or more words as arguments and displays them like so: [me@linuxbox ~]$ banner "BIG TEXT" ###### ### ##### ####### ####### # # ####### # # # # # # # # # # # # # # # # # # # ###### # # #### # ##### # # # # # # # # # # # # # # # # # # # # # # ###### ### ##### # ####### # # # This program has been around for a long time and there are several different implementations. On Debian-based systems (such as Ubuntu) the package is called “sysvbanner”, on Red Hat-based systems the package is called simply “banner”. Once we have banner installed we can run this script to display our clock: #!/bin/bash # tclock - Display a clock in a terminal BG_BLUE="$(tput setab 4)" FG_BLACK="$(tput setaf 0)" FG_WHITE="$(tput setaf 7)" terminal_size() { # Calculate the size of the terminal terminal_cols="$(tput cols)" terminal_rows="$(tput lines)" 72 tput terminals that support bce, this is easy. We simply set the background color and then clear the screen. Terminals that do not support bce always erase to the default color (usually black). To solve this problem, our this script creates a long string of spaces that will fill the screen. On terminal types that do not support bce (for example, screen) the background color is set, the cursor is moved to the home position and then the string of spaces is drawn to fill the screen with the desired background color. Summing Up Using tput, we can easily add visual enhancements to our scripts. While it’s important not to get carried away, lest we end up with a garish, blinking mess, adding text effects and color can increase the visual appeal of our work and improve the readability of information we present to our users. Further Reading • The terminfo man page contains the entire list of terminal capabilities defined terminfo database. • On most systems, the /lib/terminfo and /usr/share/terminfo directories contain the all of the terminals supported by terminfo. • Bash Hacker’s Wiki has a good entry on the subject of text effects using tput. The page also has some interesting example scripts. • Greg’s Wiki contains useful information about setting text colors using tput. • Bash Prompt HOWTO discusses using tput to apply text effects to the shell prompt. tput 75 6 dialog If we look at contemporary software, we might be surprised to learn that the majority of code in most programs today has very little to do with the real work for which the program was intended. Rather, the majority of code is used to create the user interface. Modern graphical programs need large amounts of CPU time and memory for their sophisticated eye candy. This helps explain why command line programs usually use so little memory and CPU compared to their GUI counterparts. Still, the command line interface is often inconvenient. If only there were some way to emulate common graphical user interface features on a text display. In this adventure, we’re going to look at dialog, a program that does just that. It displays various kinds of dialog boxes that we can incorporate into our shell scripts to give them a much friendlier face. dialog dates back a number of years and is now just one member of a family of programs that attempt to solve the user interface problem for command line users. The More Redirection adventure is a suggested prerequisite to this adventure. Features dialog is a fairly large and complex program (it has almost 100 command line options), but compared to the typical graphical user interface, it’s a real lightweight. Still, it is capable of many user interface tricks. With dialog, we can generate the following types of dialog boxes (version 1.2 shown): Dialog Option Description Build List --buildlist Displays two lists, side-by-side. The list on the left contains unselected items, the list on the right selected items. The user can move items from one list to the other. Calendar --calendar Displays a calendar and allow the user to select a date. Checklist --checklist Presents a list of choices and allow the user to select one or more items. Directory Select --dselect Displays a directory selection dialog. Edit Box --editbox Displays a rudimentary text file editor. Form --form Allows the user to enter text into multiple fields. File Select --fselect A file selection dialog. Gauge --gauge Displays a progress indicator showing the percentage of completion. Info Box --infobox Displays a message (with an optional timed pause) and terminates. Input Box --inputbox Prompts the user to enter/edit a text field. Menu Box --menubox Displays a list of choices. dialog 77 Screen shot of the fselect dialog Availability dialog is available from most distribution repositories as the package “dialog”. Besides the program itself, the dialog package includes a fairly comprehensive man page and a large set of sample programs that demonstrate the various dialog boxes it can display. After installation on a Debian-based system, these sample programs can be found in the /usr/share/doc/dialog/examples directory. Other distributions are similar. By the way, using Midnight Commander to browse the examples directory is a great way to run the example programs and to study the scripts themselves: 80 dialog Browsing the examples with Midnight Commander How it Works On the surface, dialog appears straightforward. We launch dialog followed by one or more common options (options that apply regardless of the desired dialog box) and then the box option and its associated parameters. The tricky part of using dialog is getting data out of it. The data that dialog takes in (such as a string entered into a input box) is normally returned on standard error. This is because dialog uses standard output to display text on the terminal when it is drawing the dialog box itself. There are a couple of techniques we can use to handle the returned data. Let’s take a look at them. Method 1: Store the Results in a Temporary File The first method is to use a temporary file. The sample programs supplied with dialog provide some examples (this script has been modified from the original for clarity): #!/bin/bash # inputbox - demonstrate the input dialog box with a temporary file # Define the dialog exit status codes : ${DIALOG_OK=0} : ${DIALOG_CANCEL=1} : ${DIALOG_HELP=2} : ${DIALOG_EXTRA=3} : ${DIALOG_ITEM_HELP=4} : ${DIALOG_ESC=255} dialog 81 # Create a temporary file and make sure it goes away when we're dome tmp_file=$(tempfile 2>/dev/null) || tmp_file=/tmp/test$$ trap "rm -f $tmp_file" 0 1 2 5 15 # Generate the dialog box dialog --title "INPUT BOX" \ --clear \ --inputbox \ "Hi, this is an input dialog box. You can use \n this to ask questions that require the user \n to input a string as the answer. You can \n input strings of length longer than the \n width of the input box, in that case, the \n input field will be automatically scrolled. \n You can use BACKSPACE to correct errors. \n\n Try entering your name below:" \ 16 51 2> $tmp_file # Get the exit status return_value=$? # Act on it case $return_value in $DIALOG_OK) echo "Result: `cat $tmp_file`";; $DIALOG_CANCEL) echo "Cancel pressed.";; $DIALOG_HELP) echo "Help pressed.";; $DIALOG_EXTRA) echo "Extra button pressed.";; $DIALOG_ITEM_HELP) echo "Item-help button pressed.";; $DIALOG_ESC) if test -s $tmp_file ; then cat $tmp_file else echo "ESC pressed." fi ;; esac The first part of the script defines some constants that are used to represent the six possible exit status values supported by dialog. They are used to tell the calling script which button on the dialog box (or alternately, the Esc key) was used to terminate the dialog. The construct used to do this is somewhat interesting. First, each line begins with the null command “:” which is a command that does nothing. Yes, really. It intentionally does nothing, because sometimes we need a command (for syntax reasons) but don’t actually want to do anything. Following the null command is a parameter expansion. The expansion is similar in form to one we covered in Chapter 34 of TLCL: ${parameter:=value} This sets a default value for a parameter (variable) that is either unset (it does not exist at all), or is set, but empty. The author of the example code is being very cautious here and 82 dialog Before and After Now that we have a basic grip on how to use dialog, let’s apply it to a practical example. Here we have an “ordinary” script. It’s a menu-driven system information program similar to one discussed in Chapter 29 of TLCL: #!/bin/bash # while-menu: a menu-driven system information program DELAY=3 # Number of seconds to display results while true; do clear cat << _EOF_ Please Select: 1. Display System Information 2. Display Disk Space 3. Display Home Space Utilization 0. Quit _EOF_ read -p "Enter selection [0-3] > " if [[ $REPLY =~ ^[0-3]$ ]]; then case $REPLY in 1) echo "Hostname: $HOSTNAME" uptime sleep $DELAY continue ;; 2) df -h sleep $DELAY continue ;; 3) if [[ $(id -u) -eq 0 ]]; then echo "Home Space Utilization (All Users)" du -sh /home/* 2> /dev/null else echo "Home Space Utilization ($USER)" du -sh $HOME 2> /dev/null fi sleep $DELAY continue ;; 0) break ;; esac else echo "Invalid entry." sleep $DELAY fi done dialog 85 echo "Program terminated." A script displaying a text menu The script displays a simple menu of choices. After the user enters a selection, the selection is validated to make sure it is one of the permitted choices (the numerals 0-3) and if successfully validated, a case statement is used to carry out the selected action. The results are displayed for the number of seconds defined by the DELAY constant, after which the whole process is repeated until the user selects the menu choice to exit the program. Here is the script modified to use dialog to provide a new user interface: #!/bin/bash # while-menu-dialog: a menu driven system information program DIALOG_CANCEL=1 DIALOG_ESC=255 HEIGHT=0 WIDTH=0 display_result() { dialog --title "$1" \ --no-collapse \ --msgbox "$result" 0 0 } while true; do exec 3>&1 selection=$(dialog \ --backtitle "System Information" \ --title "Menu" \ --clear \ --cancel-label "Exit" \ 86 dialog --menu "Please select:" $HEIGHT $WIDTH 4 \ "1" "Display System Information" \ "2" "Display Disk Space" \ "3" "Display Home Space Utilization" \ 2>&1 1>&3) exit_status=$? exec 3>&- case $exit_status in $DIALOG_CANCEL) clear echo "Program terminated." exit ;; $DIALOG_ESC) clear echo "Program aborted." >&2 exit 1 ;; esac case $selection in 1 ) result=$(echo "Hostname: $HOSTNAME"; uptime) display_result "System Information" ;; 2 ) result=$(df -h) display_result "Disk Space" ;; 3 ) if [[ $(id -u) -eq 0 ]]; then result=$(du -sh /home/* 2> /dev/null) display_result "Home Space Utilization (All Users)" else result=$(du -sh $HOME 2> /dev/null) display_result "Home Space Utilization ($USER)" fi ;; esac done dialog 87
Docsity logo



Copyright © 2024 Ladybird Srl - Via Leonardo da Vinci 16, 10126, Torino, Italy - VAT 10816460017 - All rights reserved