
The Ultimate Linux Shell Scripting Guide
Description
Alles über E-Books | Antworten auf Fragen rund um E-Books, Kopierschutz und Dateiformate finden Sie in unserem Info- & Hilfebereich.
- Progress seamlessly through chapters with clear concepts, practical examples, and hands-on labs for skill development
- Build real-world Linux administration scripts, enhancing your troubleshooting and management skills
Book DescriptionDive into the world of Linux shell scripting with this hands-on guide. If you're comfortable using the command line on Unix or Linux but haven't fully explored Bash, this book is for you. It's designed for programmers familiar with languages like Python, JavaScript, or PHP who want to make the most of shell scripting. This isn't just another theory-heavy book-you'll learn by doing. Each chapter builds on the last, taking you from shell basics to writing practical scripts that solve real-world problems. With nearly a hundred interactive labs, you'll gain hands-on experience in automation, system administration, and troubleshooting. While Bash is the primary focus, you'll also get a look at Z Shell and PowerShell, expanding your skills and adaptability. From mastering command redirection and pipelines to writing scripts that work across different Unix-like systems, this book equips you for real-world Linux challenges. By the end, you'll be equipped to write efficient shell scripts that streamline your workflow and improve system automation.What you will learn - Grasp the concept of shells and explore their diverse types for varied system interactions
- Master redirection, pipes, and compound commands for efficient shell operations
- Leverage text stream filters within scripts for dynamic data manipulation
- Harness functions and build libraries to create modular and reusable shell scripts
- Explore the basic programming constructs that apply to all programming languages
- Engineer portable shell scripts, ensuring compatibility across diverse platforms beyond Linux
Who this book is forThis book is for programmers who use the command line on Unix and Linux servers already, but don't write primarily in Bash. This book is ideal for programmers who've been using a scripting language such as Python, JavaScript or PHP, and would like to understand and use Bash more effectively. It's also great for beginning programmers, who want to learn programming concepts.
All prices
More details
Other editions
Additional editions

Person
Donald A. Tevault - but you can call him Donnie - got involved with Linux way back in 2006, and has been working with it ever since. He holds the Linux Professional Institute Level 3-Security certification, and the GIAC Incident Handler certification. Donnie is a professional Linux trainer, and thanks to the magic of the internet, teaches Linux classes literally the world over from the comfort of his living room. He's also a Linux security researcher for an IoT security company.
Content
- Cover
- Title Page
- Copyright Page
- Contributors
- Table of Contents
- Preface
- Free Benefits with Your Book
- Chapter 1: Getting Started with the Shell
- Understanding Shells
- Free Benefits with Your Book
- Finding Help with Shell Commands
- Understanding Manual Pages
- Understanding Info Pages
- Getting to Know the Linux Documentation Project
- Using Your Favorite Search Engine
- Using a Text Editor to Create Shell Scripts
- Text-mode Editors
- GUI Text Editors
- Understanding Compiled versus Interpreted Programming
- Understanding root and sudo Privileges
- Summary
- Questions
- Further Reading
- Answers
- Chapter 2: Interpreting Commands
- Understanding the Structure of a Command
- Using Command Options
- Hands-on Lab - Practice With Command Options
- Using Command Arguments
- Executing Multiple Commands at Once
- Running Commands Interactively
- Using Command Sequences
- Chaining Commands with a Semi-Colon
- Conditional Command Execution with Double Ampersands
- Conditional Command Execution with Double Pipes
- Using the find Utility
- Performing Multiple Actions with find
- Hands-on Lab - Using find to Perform Other Commands
- Running Commands Recursively
- Hands-on Lab - Using Commands with Recursion
- Understanding the Command History
- Escaping and Quoting
- Escaping Metacharacters
- Quoting
- Summary
- Questions
- Further Reading
- Answers
- Chapter 3: Understanding Variables and Pipelines
- Understanding Environmental Variables
- Understanding Programming Variables
- Understanding Pipelines
- Summary
- Questions
- Further Reading
- Answers
- Chapter 4: Understanding Input/Output Redirection
- Introduction to Input/Output Redirection
- Understanding stdout
- Preventing File Overwrites
- Using the File Descriptor
- Understanding stdin
- Understanding stderr
- Understanding tee
- Hands-on Lab - Pipes, Redirectors, and find
- Summary
- Questions
- Further Reading
- Answers
- Chapter 5: Customizing the Environment
- Technical Requirements
- Reviewing the Environmental Variables
- Understanding Shell Sessions
- Understanding the Configuration Files
- bash Global Configuration Files on Fedora
- Users' Configuration Files on Fedora
- bash Global Configuration Files on Debian
- Users' Configuration Files on Debian
- Setting the Default Editor on Debian
- Setting Shell Options from the Command-line
- Understanding Aliases
- Summary
- Questions
- Further Reading
- Answers
- Chapter 6: Text-Stream Filters - Part 1
- Technical Requirements
- Introduction to Text-Stream Filters
- Using cat
- Using tac
- Using cut
- Using paste
- Using join
- Using sort
- Summary
- Questions
- Further Reading
- Answers
- Chapter 7: Text Stream Filters - Part 2
- Technical Requirements
- Using expand
- Using unexpand
- Using nl
- Using head
- Using tail
- Using Head And Tail Together
- Using od
- Using uniq
- Using wc
- Using fmt
- Using split
- Using tr
- Using xargs
- Using pr
- Printing from the Command-line
- Summary
- Questions
- Further Reading
- Answers
- Chapter 8: Basic Shell Script Construction
- Technical Requirements
- Understanding Basic Shell Script Construction
- Hands-on Lab - Counting Logged-in Users
- Performing Tests
- Using the test Keyword
- Enclosing a test Condition Within Square Brackets
- Using an if. . .then Construct
- Using Other Types of Tests
- Understanding Subshells
- Hands-on Lab - Testing Conditions
- Understanding Scripting Variables
- Creating and Deleting Variables
- Understanding Variables and Shell Levels
- Understanding Case Sensitivity
- Understanding Read-Only Variables
- Understanding Array Variables
- Hands-on Lab - Using Arrays
- Understanding Variable Expansion
- Substituting a Value for an Unset Variable
- Substituting a Value for a Set Variable
- Assigning a Value to a Variable
- Displaying an Error Message
- Using Variable Offsets
- Matching Patterns
- Understanding Command Substitution
- Understanding Decisions and Loops
- The if. .then Construct
- The do. . while construct
- The for..in Construct
- The for Construct
- Using break
- Using continue
- The until Construct
- The case Construct
- Using Positional Parameters
- Understanding Exit Codes
- Standard Shell Exit Codes
- User-defined Exit Codes
- More Information About echo
- Looking at Some Real-World Examples
- Hands-on Lab: Using if..then
- Hands-on Lab - Parsing an Apache Access Log
- Hands-on Lab - Beta Testing a Hard Drive
- Summary
- Questions
- Further Reading
- Answers
- Chapter 9: Filtering Text with grep, sed, and Regular Expressions
- Technical Requirements
- Understanding Regular Expressions
- Literals and Metacharacters
- Understanding sed
- Understanding sed Portability Issues
- Installing gsed on FreeBSD
- Installing gsed on macOS
- Installing gsed on OpenIndiana
- Substitution with sed
- Example 1: Modifying an Office Memo
- Example 2: Modifying a List of Hollywood Actors
- Example 3: Modifying Lists of Cars
- Example 4: Performing a Whole-Word Substitution
- Deletion with sed
- Example 1: Deleting Items from a List
- Example 2: Deleting Blank Lines
- Appending and Inserting with sed
- Example 1: Appending Lines of Text
- Example 2: Performing Multiple Operations at Once
- Example 3: Inserting Lines of Text
- Changing with sed
- Example 1: Changing Edsel to Studebaker
- Example 2: Changing Entire Lines of Text
- Other Miscellaneous sed tricks
- Example 1: Using the q Command
- Example 2: Using the w Command
- Example 3: Using the r Command
- Using sed program files
- Example 1: Appending Lines in a Text File
- Example 2: Changing Lines in a Text File
- Example 3: Substituting Text
- Example 4: Copying Lines from One File to Another
- Compound Scripts in sed Program Files
- Using sed in Shell Scripts
- Understanding grep
- Basic Searches with grep
- More Advanced Searches with grep
- Example 1: Searching for Whole Words
- Even More Advanced Searches with grep
- Example 1: Auditing Source Code Files
- Example 2: Searching for Social Security Numbers
- Example 3: Using the ^ Metacharacter
- Using Extended Regular Expressions with grep
- Example 1: Basic Search with Extended Syntax
- Example 2: Searching for Consecutive Duplicate Words
- Example 3: Searching for Words that Begin with a Certain Letter
- Example 4: Searching for Words with Digits
- Using Fixed-strings Regular Expressions with grep
- Using RegEx Helper Programs
- RegexBuddy and RegexMagic
- Regex101
- Looking at Some Real-World Examples
- Modifying Multiple Files at Once
- Searching Through Apache Webserver Logs for Cross-site Scripting Attacks
- Automating Third-party Repository Installations
- Filling Empty Fields in a .csv File
- Summary
- Questions
- Further Reading
- Answers
- Chapter 10: Understanding Functions
- Technical Requirements
- Introduction to Functions
- Defining a Function
- Using Functions in Shell Scripts
- Creating and Calling Functions
- Passing Positional Parameters to Functions
- Passing Values from a Function
- Creating Function Libraries
- Looking at Some Real-World Examples
- Checking Network Connectivity
- Using the CoinGecko API
- Hands-on Lab - Creating the coingecko.sh Script
- Summary
- Questions
- Further Reading
- Answers
- Chapter 11: Performing Mathematical Operations
- Technical Requirements
- Performing Integer Math with Expressions
- Using the expr Command
- Using echo with Math Expressions
- Performing Integer Math with Integer Variables
- Performing Floating Point Math with bc
- Using bc in Interactive Mode
- Using bc Program Files
- Using bc in Shell Scripts
- Summary
- Questions
- Further Reading
- Answers
- Chapter 12: Automating Scripts with here Documents and expect
- Technical Requirements
- Using here Documents
- Creating here Documents with Static Data
- Creating here documents with Dynamic Data
- Using Functions in here Documents
- Automating Responses with expect
- Security Implications with expect
- Summary
- Questions
- Further Reading
- Answers
- Chapter 13: Scripting with ImageMagick
- Technical Requirements
- Converting Non-standard Filename Extensions
- Installing ImageMagick
- Displaying Images
- Viewing Image Properties
- Resizing and Customizing Images
- Batch-processing Image Files
- Using Fred's ImageMagick Scripts
- Summary
- Questions
- Further Reading
- Answers
- Chapter 14: Using awk - Part 1
- Introducing awk
- Understanding Patterns and Actions
- Obtaining Input from Text Files
- Looking for Human Users
- Parsing Webserver Access Logs
- Using Regular Expressions
- Obtaining Input from Commands
- Summary
- Questions
- Further Reading
- Answers
- Chapter 15: Using awk - Part 2
- Technical Requirements
- Basic awk Script Construction
- Using Conditional Statements
- Using a while Construct and Setting Variables
- Summing Numbers in a Line
- Finding the CPU Generation
- Using for loops and Arrays
- Using Floating Point Math and printf
- Working with Multi-Line Records
- Summary
- Questions
- Further Reading
- Answers
- Chapter 16: Creating User Interfaces with yad, dialog, and xdialog
- Technical Requirements
- Creating a Graphical User Interface with yad
- The yad Basics
- Creating Data Entry Forms
- Creating a Drop-down List
- Using the yad File Manager
- Creating a File Checksum Utility
- Creating a GUI Front-end for ImageMagick
- Programming Form Buttons
- Some Final Thoughts about yad
- Creating User Interfaces with dialog and xdialog
- The dialog Basics
- The xdialog Basics
- Automatically Choosing Either dialog or xdialog
- Adding Widgets
- Creating an SSH Login Interface
- Summary
- Questions
- Further Reading
- Answers
- Chapter 17: Using Shell Script Options with getops
- Technical Requirements
- Understanding the Need for getopts
- Understanding getopt versus getopts
- Using getopts
- Looking at Real-world Examples
- The Modified Coingecko Script
- The Tecmint Monitor Script
- Summary
- Questions
- Further Reading
- Answers
- Chapter 18: Shell Scripting for Security Professionals
- Technical Requirements
- Simple Scripts for Auditing
- Identifying an Operating System
- A Simple Port-scanning Script
- Auditing the root User Account
- Creating the root Account Auditing Script for Linux and OpenIndiana
- Modifying the root Account Auditing Script for Use on FreeBSD
- Creating a User Activity Monitoring Script
- Creating Simple Firewall Scripts
- Creating an IP Address Blocking Script for Red Hat Distros
- Hands-on Lab: Create the Script with an Array and a for loop
- Hands-on Lab: Creating the Script with xargs
- Searching for Existing Security-related Scripts
- Summary
- Questions
- Further Reading
- Answers
- Chapter 19: Shell Script Portability
- Technical Requirements
- Running bash on Non-Linux Systems
- Using env to Set the bash Environment
- Creating a Symbolic Link to bash
- Understanding POSIX compliance
- Understanding the Differences Between Shells
- Understanding Bashisms
- Using Portable Tests
- Making Portable Arrays
- Understanding Portability Problems with echo
- Testing Scripts for POSIX Compliance
- Creating Scripts on a POSIX-compliant Shell
- Using checkbashisms
- Using shellcheck
- Specifying a Shell with the -s Option
- Hands-on Lab - Using -s to Scan Function Libraries
- Using shall
- Summary
- Questions
- Further Reading
- Answers
- Chapter 20: Shell Script Security
- Technical Requirements
- Controlling Access to Your Scripts
- Assigning sudo Privileges
- Hands-on Lab - Configuring sudo
- Using an Access Control List
- Hands-on Lab - Setting an ACL for Horatio on Linux
- Hands-on Lab - Setting an ACL for Horatio on FreeBSD 14
- Hands-on Lab - Setting an ACL for Horatio on OpenIndiana
- Obfuscating Plain-Text Scripts
- Installing shc
- Hands-on Lab - Using shc
- Hands-on Lab - Creating Untraceable Executables
- Decrypting shc Binaries
- Understanding SUID and SGID Considerations
- Avoiding Sensitive Data Leakage
- Securing Temporary Files
- Understanding the /tmp/ Directory
- The Wrong Way to Create Temporary Files
- The Right Way to Create Temporary Files
- Using Passwords in Shell Scripts
- Hands-on Lab - Encrypting Passwords
- Understanding Command Injection with eval
- Using eval on the Command-line
- Using eval Safely
- Using eval Dangerously
- Using Alternatives to eval
- Using Command Substitution
- Evaluating if eval is Necessary
- Understanding Path Security
- Attack Scenario 1: Compromising the User's Account
- Attack Scenario 2: Social Engineering
- Summary
- Questions
- Further Reading
- Answers
- Chapter 21: Debugging Shell Scripts
- Technical Requirements
- Understanding Common Scripting Errors
- Not Enough Quoting
- Filenames with Blank Spaces
- Problems with Unset Variables
- Creating a Wild Loop
- Using Shell Script Debugging Tools and Techniques
- Using echo Statements
- Using xtrace for Debugging
- Checking for Undefined Variables
- Checking for Errors with the -e Option
- Understanding the Problems with set -e and -e
- Using bash Debugger
- Installing bashdb on Linux
- Installing bashdb on FreeBSD
- Installing on macOS
- Debugging a Script with bashdb
- Getting Help with bashdb
- Summary
- Questions
- Further Reading
- Answers
- Chapter 22: Introduction to Z Shell Scripting
- Technical Requirements
- Introducing zsh
- Installing zsh
- Understanding the Unique Features of zsh Scripting
- Differences in Variable Expansion
- Substituting Values
- Substituting Substrings
- Translating Between Upper and Lower Case
- Extended File Globbing
- Understanding zsh Arrays
- Enhanced Math Capabilities
- Using zsh Modules
- Using the mathfunc Module
- The datetime Module
- Summary
- Questions
- Further Reading
- Answers
- Chapter 23: Using PowerShell on Linux
- Technical Requirements
- Installing PowerShell on Linux and macOS
- Installing PowerShell on Linux via a snap Package
- Installing PowerShell on Fedora
- Installing PowerShell on macOS
- Invoking PowerShell
- Reasons for Linux and Mac Admins to Learn PowerShell
- Working with Mixed Operating System Environments
- PowerShell Commands Can Be Simpler
- Enhanced Builtin Math Capabilities
- Differences Between PowerShell Scripting and Traditional Linux/Unix Scripting
- Using Filename Extensions and the Executable Permission
- PowerShell is Object-oriented
- PowerShell Uses Cmdlets
- Using Aliases on PowerShell
- Viewing the Available PowerShell Commands
- Getting Help with PowerShell Commands
- Real-World Cross-Platform PowerShell Scripts
- The write-marquee.ps1 Script
- The check-cpu.ps1 Script
- Summary
- Further Reading
- Chapter 24: Unlock Your Exclusive Benefits
- Packt Page
- Other Books You May Enjoy
- Index
Preface
Welcome to The Ultimate Linux Shell Scripting Guide! This book, which is ideal for both Linux beginners and more advanced Linux administrators, will guide you through the shell script creation process. We'll begin with basic command-line usage and will progress through more advanced concepts in every succeeding chapter. You'll see how to build scripts that can help you automate repetitive administrative tasks, as well as many other cool things. We'll primarily concentrate on bash scripting throughout most of the book. Later, we'll show you how to make your scripts portable so that they can run on legacy Unix systems that can't run bash. After chapters on shell script debugging and shell script security, we'll wrap up with introductions to the Z Shell and PowerShell.
Who this book is for
This book is appropriate for anyone who needs to master the concepts of shell scripting. Linux beginners can benefit, because it can help them master the concepts that will be covered on the CompTIA Linux+/Linux Professional Institute exam. More advanced Linux administrators can benefit because it will show them the more advanced concepts that they need to build really useful, practical shell scripts.
What this book covers
Chapter 1, Getting Started with the Shell, this chapter covers the basics of operating system shells that can be found on Linux and Unix-like systems. The reader will need to know these principles in order to understand principles that will be presented in later chapters.
Chapter 2, Interpreting Commands, there are five things that an operating system shell will do for us. These include interpreting commands, setting variables, enabling pipelines, allowing input/output redirection, and allowing customization of the user's working environment. In this chapter, we'll look at how shells interpret a user's commands.
Chapter 3, Understanding Variables and Pipelines, in this chapter, we'll look at the next two things that an operating system shell does for us, which is to allow us to set variables and use command pipelines. There's not that much to say about either of these topics, which is why we're combining them both into one chapter.
Chapter 4, Understanding Input/Output Redirection, in this chapter, we'll look at how to send the text output of a command to somewhere other than the terminal, which is the default output device. We'll then look at how to make a command bring in text from somewhere other than the keyboard, which is the default input device.
Finally, we'll look at how to send error messages to somewhere other than the terminal.
Chapter 5, Customizing the Environment, in this chapter, we'll look at the various configuration files for the various shell environments. We'll look at how to customize these configuration files, and how to set certain environmental options from the command-line.
Chapter 6, Text Stream Filters - Part 1, many times, an administrator will need to write a shell script that will retrieve text information from an external source, format it, and create a report. In this chapter, we'll introduce the concept of text stream filters, which can help with this process. Also, knowing about these text stream filters can help you pass certain Linux certification exams, such as the LPI/Linux+ exam. We will then show you how to use several of these filters.
Chapter 7, Text Stream Filters - Part 2, in this chapter, we'll continue our exploration of text stream filters.
Chapter 8, Basic Shell Script Construction, in this chapter, we'll explain about the basic structure of a shell script, and will use some of the text stream filters from the previous chapters to create simple scripts. We'll also look at some basic programming constructs that are common to all programming languages, and show you how to use them.
Chapter 9, Filtering Text with grep, sed, and Regular Expressions, in this chapter, you'll learn about the concept of regular expressions, and how to use them with grep and sed to filter or manipulate text. These techniques can not only help you find certain text, but can also help automate the creation of reports and the editing of multiple text files at once.
Chapter 10, Understanding Functions, functions are an important part of every programming language, because they make it easy for a programmer to reuse a block of code in numerous programs, or in numerous places within one single program. The programmer can pass parameters to a function, have the function operate on those parameters, and pass back the results to the main program.
Chapter 11, Performing Mathematical Operations, the various operating system shells all have means of performing mathematical operations either from the command-line, or from within a shell script. In this chapter, we'll look at how to perform operations with both integer and floating point math.
Chapter 12, Automating Scripts with here Documents and expect, although it's easy to have a shell script pull data out of a separate text file, it's sometimes handier to store the data within the shell script itself. We'll do that using a "here" document. In this chapter, you'll learn how to create and use "here" documents. You'll also see how to automate certain scripts with the expect utility.
Chapter 13, Scripting with ImageMagick, imageMagick is a text-mode program that is used to edit, manipulate, and view graphical image files. In this chapter, you'll learn how to automate the processing of images by using ImageMagick commands within shell scripts.
Chapter 14, Using awk-Part 1, this chapter covers awk, which is a tool that can extract specific text from text files, and automate the creation of reports and databases. Since awk is a full-blown programming language in its own right, we won't be covering it in depth here. Instead, we'll give you enough information so that you can create awk "one-liners" that can be used within shell scripts.
Chapter 15, Using awk-Part 2, this is a continuation of the previous chapter, in which we'll cover the more advanced concepts of scripting with awk.
Chapter 16, Creating User Interfaces with yad, dialog, and xdialog, so far, we've only looked at shell scripts that run strictly from the command-line. And indeed, that's how most people use them, and is what most people think about when they think about shell scripts. But, it's also possible to create shell scripts that offer a user interface. In this chapter, we'll use yad to create graphical user interfaces, and dialog to create ncurses-style interfaces.
Chapter 17, Using Shell Script Options with getopts, often, an administrator will need to pass both arguments and options to a shell script. Passing arguments, the objects upon which a script will operate, is easy. To also pass options, which modify how the script will operate, requires another type of operator. In this chapter, you'll learn how to use getopts to pass options to a script.
Chapter 18, Shell Scripting for Security Professionals, in this chapter, you'll learn how to either create shell scripts or search for existing shell scripts that can help security administrators perform their jobs. We'll also look at how to modify or improve existing shell scripts to meet specific needs of security administrators.
Chapter 19, Shell Script Portability, large organizations, such as large government agencies or large corporations, might have a diverse mix of Linux, Unix, and Unix-like machines. Sometimes, it's handy to write shell scripts that can automatically detect the type of system on which they're running, and run the appropriate code for each type of system. In this chapter, we'll look at several methods for enhancing script portability.
Chapter 20, Shell Script Security, scripting errors can cause a script to inadvertently cause the exposure of sensitive data, or to allow someone to perform unauthorized activities on a system. In this chapter, we'll look at ways to help the reader write shell scripts that are as secure as they possibly can be.
Chapter 21, Debugging Shell Scripts, shell scripts can have bugs, the same as with any other programming language. Sometimes, the bugs are easy to find, and sometimes they're not. In this chapter, we'll look at various methods that can help a busy administrator debug shell scripts that aren't working properly.
Chapter 22, Introduction to Z Shell Scripting, the Z Shell, or zsh, is an alternate shell that can be used in place of bash. It's mainly used in the same manner as bash, but it also has enhancements that bash doesn't have. In this chapter, we'll look at these enhancements, and also at some scripting tricks that you can't do with bash.
Chapter 23, Using PowerShell on Linux, powerShell was created by Microsoft for use on Windows operating systems back in 2006. In 2016, Microsoft announced that they had open-sourced PowerShell, and were making it available for Linux and macOS, as well as for Windows. In this chapter, we'll look at how PowerShell can be beneficial for Linux administrators, how to install it, and how to use it.
To get the...
System requirements
File format: ePUB
Copy protection: Adobe-DRM (Digital Rights Management)
System requirements:
- Computer (Windows; MacOS X; Linux): Install the free reader Adobe Digital Editions prior to download (see eBook Help).
- Tablet/smartphone (Android; iOS): Install the free app Adobe Digital Editions or the app PocketBook before downloading (see eBook Help).
- E-reader: Bookeen, Kobo, Pocketbook, Sony, Tolino and many more (not Kindle).
The file format ePub works well for novels and non-fiction books – i.e., „flowing” text without complex layout. On an e-reader or smartphone, line and page breaks automatically adjust to fit the small displays.
This eBook uses Adobe-DRM, a „hard” copy protection. If the necessary requirements are not met, unfortunately you will not be able to open the eBook. You will therefore need to prepare your reading hardware before downloading.
Please note: We strongly recommend that you authorise using your personal Adobe ID after installation of any reading software.
For more information, see our ebook Help page.
File format: ePUB
Copy protection: without DRM (Digital Rights Management)
System requirements:
- Computer (Windows; MacOS X; Linux): Use a reader that can handle the file format ePUB, such as Adobe Digital Editions or FBReader – both free (see eBook Help).
- Tablet/Smartphone (Android; iOS): Install the free app Adobe Digital Editions or the app PocketBook (see eBook Help).
- E-reader: Bookeen, Kobo, Pocketbook, Sony, Tolino and many more (not Kindle).
The file format ePUB works well for novels and non-fiction books – i.e., 'flowing' text without complex layout. On an e-reader or smartphone, line and page breaks automatically adjust to fit the small displays.
This eBook does not use copy protection or Digital Rights Management
For more information, see our eBook Help page.