- GNU-Linux Rapid Embedded Programming
- Rodolfo Giometti
- 3261字
- 2021-07-09 18:40:29
Basic OS management
Now it's time to take a quick tour of some basic system management commands, which may be useful in the next sections.
You should notice that the following commands can be used indifferently into each developer kit presented in this book as is in the host PC as is in any other GNU/Linux-based OS! This is a really important feature of GNU/Linux systems that allows a developer to have the same command set into its working machine as the one in the embedded devices.
For the sake of simplicity, the following examples are executed into the host PC.
File manipulation and Co
One of the main principles of Unix systems is that everything is a file. This means that in a Unix system, (almost) everything can be accessed as a file! So we can use the same commands to read/write a file for every peripheral connected to the system (that is, disks, terminals, serial ports, and so on).
Since this book's main goal is to show you how to get access to the system's peripherals, it's quite obvious that these commands are very important to know. Moreover, in the next chapters, we are going to use several command-line tools to set up our developer kits and their attached peripherals, so in this section, we are going to do a little list of them.
Tip
The following tutorial will not cover all possible file manipulation and tool commands nor all possible usages, so let me encourage those of you curious to get further information by surfing the Internet. A good starting point is at: http://en.wikipedia.org/wiki/List_of_Unix_commands .
For each presented command, you should take a look at the relative man pages, which we cannot entirely reproduce here due to spacing reasons because even an experienced developer may learn a lot of useful things by reading them from time to time.
To get the man pages of a generic command, we can try to use the following command line:
$ man <command>
Here, the <command>
string is obviously the desired command to visit. If we have to use a different command to get this information, you will be informed accordingly.
echo and cat
Well, in order to manipulate the files, the first commands we can use are echo
and cat
; the former can be used to put some text into a file and the latter to read the file content:
$ echo 'Some text' > /tmp/foo $ cat /tmp/foo Some text
To append some text, instead of rewriting it, we can simply replace the >
char with >>
in the preceding command, as shown here:
$ echo 'Another line' >> /tmp/foo $ cat /tmp/foo Some text Another line
In the echo
command's man pages, we find that the command's description is Echo the STRING(s) to standard output; so, by using the Bash redirection behavior (with the >
and >>
characters), we can use it to write into a normal file due the fact that even the standard output is a file!
Again, as shown in the cat
command in the relative man pages, we find that the description is concatenate files and print on the standard output. Again, what we already said about the echo
command is still valid for cat
, but looking at its description, we notice another interesting mode to use it, which is that it can be used to concatenate two or more files (the inverse operation of the split
command). Let's consider the following commands:
$ ls -lh /bin/bash -rwxr-xr-x 1 root root 664K Nov 12 2014 /bin/bash $ split -b 100K /bin/bash bash_ $ ls -lh bash_* -rw-r--r-- 1 root root 100K Apr 2 17:55 bash_aa -rw-r--r-- 1 root root 100K Apr 2 17:55 bash_ab -rw-r--r-- 1 root root 100K Apr 2 17:55 bash_ac -rw-r--r-- 1 root root 100K Apr 2 17:55 bash_ad -rw-r--r-- 1 root root 100K Apr 2 17:55 bash_ae -rw-r--r-- 1 root root 100K Apr 2 17:55 bash_af -rw-r--r-- 1 root root 64K Apr 2 17:55 bash_ag
We split the /bin/bash
program (our shell) into six pieces of 100 KB plus a smaller one of about 64 KB. Then, we can rebuild the original file using cat
, as shown here:
$ cat bash_* > bash_rebuilded
Then, we can check the bash_rebuilded
file against the original one using the md5sum
tool, as follows:
$ md5sum /bin/bash bash_rebuilded 4ad446acf57184b795fe5c1de5b810c4 /bin/bash 4ad446acf57184b795fe5c1de5b810c4 bash_rebuilded
They have the same hash and they have the same content!
Tip
The split
and md5sum
commands are not covered in this book, but those of you curious may take a look at the relative man pages for further information on these tools:
$ man split
$ man md5sum
dd
The dd
command is very powerful since it can be used for several different purposes. We already used it in Chapter 1 , Installing the Developing System , U-Boot (with MLO) and others, where it were used in the following form:
$ sudo dd if=u-boot.img of=/dev/sdb count=2 seek=1 bs=384k
The if
option argument defines the input file where you're reading data from, while the of
option defines the output file where you're writing data to (note that while the input file is a normal file, the output file is a block device and for our command, they are absolutely interchangeable), and then the bs
option defines a block size of 384 KB that shows how many bytes must be read and written at a time, so by specifying the option arguments, count=2
and seek=1
, we ask dd
to copy only two input blocks skipping one block at the start of the output. This operation is used to place a file at a specified offset into a block device. Take a look at the following figure for a graphical representation of this operation:
By looking at the command man pages, you should notice that as the seek
option is used to skip N blocks of the output, the skip
option can be used to do the same into the input file. Also it is useful to note that using the ibs
and obs
options, we can differentiate the input from the output block size.
Another usage of dd
is the following:
$ dd if=/dev/sda of=/dev/sdb
In this case, both the input and output files are not common files but they are block devices; in particular, they are two hard disks, and by using the preceding command, we copy the entire content of the first hard disk to the second one!
Again, using the following command, we can create an image of the first hard disk in the sda_image
file:
$ dd if=/dev/sda of=sda_image
On the other hand, we can wipe a disk by writing all zeros on it:
$ dd if=/dev/zero of=/dev/sda
Or, we can safely erase the hard disk content by writing random data into it:
$ dd if=/dev/urandom of=/dev/sda
Tip
The /dev/zero
and /dev/urandom
files are special files created by the kernel where we can read data from: in the former, we're going to read all zeros, while from the latter, we're going to read (pseudo) random data generated internally by the kernel.
For further information, you can take a look at the man pages of these files (yes, even files might have man pages) using the following commands:
$ man zero
$ man urandom
The last note on dd
is about the possibility to transform the data read from the input file before writing it to the output file. In the next command, we read data from the standard input, we swap the byte in each word, and then we write the result to the standard output:
$ echo 1234 | dd conv=swab 2143
Or we can convert all characters in the input to the uppercase:
$ echo "test string" | dd conv=ucase TEST STRING
Tip
There are only a few of the several converting options offered by dd
. Refer to the man pages for a complete list.
grep and egrep
Another useful command is grep
(and its variant egrep
), which can be used to select some text from a file. If you remember, the file created earlier with the echo
command can be executed as follows:
$ grep "Another" /tmp/foo Another line
The output is just the line where the Another
word is written.
If we spend some time to take a look at the grep
command's man pages, we can see that there are tons of option arguments related to these commands; however, due to space reasons, we're going to report only the ones used in this book.
The first option argument is -r
, which can be used to recursively read all files under a specified directory, for instance, the following command searches in which the file under the /etc
directory of the Ubuntu release number of my host PC is stored:
$ rgrep -r '15\.10' /etc/ 2>/dev/null /etc/issue.net:Ubuntu 15.10 /etc/os-release:VERSION="15.10 (Wily Werewolf)" /etc/os-release:PRETTY_NAME="Ubuntu 15.10" /etc/os-release:VERSION_ID="15.10" /etc/apt/sources.list:#deb cdrom:[Ubuntu 15.10 _Wily Werewolf_ - Relea se amd64 (20151021)]/ wily main restricted /etc/lsb-release:DISTRIB_RELEASE=15.10 /etc/lsb-release:DISTRIB_DESCRIPTION="Ubuntu 15.10" /etc/issue:Ubuntu 15.10 \n \l
Tip
Note that the 2>/dev/null
setting is used to drop all possible error messages due to invalid reading permissions into the /dev/null
file. As for /dev/zero
and /dev/urandom
, you can take a look at the man pages of /dev/null
using the following command:
$ man null
Another useful option argument is -i
, which is used to ignore the case, so to search for the Ubuntu 15.10
string in both lower case or uppercase (or mixed case), we can use the following command:
$ grep -r -i 'ubuntu 15\.10' /etc/ 2>/dev/null /etc/issue.net:Ubuntu 15.10 /etc/os-release:PRETTY_NAME="Ubuntu 15.10" /etc/apt/sources.list:#deb cdrom:[Ubuntu 15.10 _Wily Werewolf_ - Relea se amd64 (20151021)]/ wily main restricted /etc/lsb-release:DISTRIB_DESCRIPTION="Ubuntu 15.10" /etc/issue:Ubuntu 15.10 \n \l
Tip
Note that in most distributions (as Ubuntu or Debian), the grep -r
command as an alias named rgrep
can be used in place, so the preceding command can be written as follows:
$ rgrep -i 'ubuntu 15\.10' /etc/ 2>/dev/null
You should take into account that all these commands are based on regular expressions that are not covered in this book, so you should use the man pages for further information on this powerful tool. Here's the command:
$ man 7 regex
tr and sed
If we need to modify a text file or a binary one (normally, we don't use these commands for binary files but we'll soon see that this can be done sometimes) in a quick and dirty manner, we can consider in using these commands.
The tr
command can be used to translate or delete characters, and the simplest usage is as follows:
$ echo 'this is a testing string' | tr 'a-z' 'A-Z' THIS IS A TESTING STRING
We've replaced all lowercases to the corresponding uppercase.
Tip
Note that a more cryptic but equivalent form of the preceding command is as follows:
$ echo 'this is a testing string' | \
tr '[:lower:]' '[:upper:]'
Another interesting usage is its usefulness in removing a set of characters. For example, we can remove all non-printable characters from a binary file with the following command:
$ tr -d -c '[:print:]' < /bin/ls
The -d
option argument tells tr
to to delete the characters specified in the command, while the -c
option negates the set. Since the set is defined by '[:print:]'
, it means that -c
transforms all printable characters into all the non-printable characters, and the desired result as shown as follows:
$ tr -d -c '[:print:]' < /bin/ls ELF>I@@8@8@@@@@@88@8@@@ aah aaTT@T@DDPtdTTATAQtdRtdaa/lib64/ld-linux-x 86-64.so.2GNU GNUL7=K"q2rH?(rstvy{|~Pv2|qX|,cr<OBE9L>bA1 >[ju`=9)F^1= +Um_{j}?p*$vD(NfKN- q<*6UH8< ]u=|nP |6ZZa<Aaj"@F@#@! aahae a`)A&na'Aa5 @a=(Aj!a#@(A0#aJ'A['A'@alibsel
Tip
We drop the command's output after a few lines since it's really quite long.
The last usage of tr
we may need is the ability to replace binary data. In fact, using the \NNN
form (where the NNN
number is specified as octal), we can address every ASCII code. A useful aspect of this feature is when we need to fill a file (or a device) with a fixed value; when we talked about dd
, we saw that we can wipe a hard disk by filling it with zeros with the following command:
$ dd if=/dev/zero of=/dev/sda
However, if we need to fill it with 255
(that is, 0xff
in hexadecimal or 0377
in octal), we can use the following command:
$ dd if=/dev/zero | tr '\000' '\377' | dd of=/dev/sda
On the other hand, the sed
command can be used when we need to modify a file holding normal text (for instance, a configuration file) using a single command instead of opening our preferred text editor. As an example, we can recall what we did in chapter 1, Installing the Developing System, BeagleBone Black: USB, networking, and overlays when we had to modify the settings into the /etc/ssh/sshd_config
file by replacing the PermitRootLogin without-password
line with PermitRootLogin yes
. Most probably, we did it using a text editor but we could use the sed
command, as follows:
$ sed -i -e 's/^PermitRootLogin without-password$/PermitRootLogin yes/' /etc/ssh/sshd_config
The -i
option tells sed
to to edit the file in place, while using the -e
option argument, we can specify the script to be executed.
Another useful form is the one we can use to comment out a string by adding a #
character at the beginning of the line we want to comment out. For example, in the /etc/ssh/sshd_config
file, if we want specify that we don't trust the ~/.ssh/known_hosts
file for RhostsRSAAuthentication
, we have to uncomment the following line:
#IgnoreUserKnownHosts yes
The command line to do it is as follows:
root@bbb:~# sed -i -e 's/^#IgnoreUserKnownHosts yes$/IgnoreUserKnownHo sts yes/' /etc/ssh/sshd_config root@bbb:~# grep IgnoreUserKnownHosts /etc/ssh/sshd_config IgnoreUserKnownHosts yes
Tip
This time, the command has been executed into BeagleBone Black instead of the host PC, but the result will be perfectly the same in both cases.
Another useful feature is the ability to replace eight consecutive spaces into a single tab character to perfectly indent a file holding our code. The sed
command is the following:
$ sed -i -e 's/ /\t/g' code.c
head and tail
These commands can be used to display the beginning or the end of a file. Short examples are as follows:
$ echo -e '1\n2\n\3\n4\n5\n6\n7\n8\n9\n10' > /tmp/bar $ head -2 /tmp/bar 1 2 $ tail -2 /tmp/bar 9 10
Here, we used the echo
command to fill the /tmp/bar
file with ten lines holding numbers 1
to 10
, one per line, and then we used the head
and tail
commands to show, respectively, the first and the last two lines of the file.
These commands can be used in several other ways, but in this book, we're going to use mostly the tail
command with the -f
option arguments in order to display a file that can grow up. This class of files is usually log files and we can use the following command line to display the system's log messages as soon as they arrive:
$ tail -f /var/log/syslog
The command will start displaying the last ten lines (if available) and then it will display any other lines that will be appended to the /var/log/syslog
log file.
od and hexdump
Other interesting commands are od
and hexdump
, which can be used to inspect file content one byte at a time (or in a more complex form). For instance, we can read the preceding /tmp/foo
text file one byte at a time using a binary format:
$ od -Ax -tx1 < /tmp/foo 000000 53 6f 6d 65 20 74 65 78 74 0a 41 6e 6f 74 68 65 000010 72 20 6c 69 6e 65 0a 000017
The hexdump
quasi equivalent command is as follows:
$ hexdump -C < /tmp/foo 00000000 53 6f 6d 65 20 74 65 78 74 0a 41 6e 74 68 65 |some text .A nothe| 00000010 72 20 6c 69 6e 65 0a |r line.| 00000017
In the output of the second command, you can also easily note that each byte is the ASCII coding of each letter of the preceding strings.
file
The file
command is used to detect a file type:
$ file /tmp/foo /tmp/foo: ASCII text $ file /dev/urandom /dev/urandom: character special $ file /usr/bin/file /usr/bin/file: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dy namically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Lin ux 2.6.32, BuildID[sha1]=ec8d8159accf4c85fde8985a784638f62e10b4e9, str ipped
Looking at the preceding output, we discover that the /tmp/foo
file we created in previous examples is just an ASCII text file; the /dev/urandom
file is a special character file and the /usr/bin/file
file (which is where the file
command is stored) is an executable for the x86-64 platform.
strings
The strings
command is used to find strings in a binary file; for example, we can extract the usage string of the file
command using this:
root@beaglebone:~# strings /usr/bin/file | grep Usage Usage: %s [-bchikLlNnprsvz0] [--apple] [--mime-encoding] [--mime-type] Usage: file [OPTION...] [FILE...]
strace
This is one of the most powerful debugging commands we can use in a GNU/Linux-based system. Using this command, we can trace all system calls a process does during its execution!
Even if this is not strictly related to file manipulation, we have to present it here due the fact that it can be used to easily debug a program and because we can use it to know which files are managed by a program without writing any extra code. In fact, the power of this command is that it can do its job even if the program is compiled with no debugging symbols at all. As an example, let's suppose we wish to know how the cat
program works, which we can do as follows:
$ strace cat /tmp/foo execve("/bin/cat", ["cat", "/tmp/foo"], [/* 29 vars */]) = 0 brk(0) = 0x2409000 ... open("/tmp/foo", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0664, st_size=23, ...}) = 0 fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0 mmap(NULL, 139264, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f80dc009000 read(3, "Some text\nAnother line\n", 131072) = 23 write(1, "Some text\nAnother line\n", 23Some text Another line ) = 23 read(3, "", 131072) = 0 munmap(0x7f80dc009000, 139264) = 0 close(3) = 0 close(1) = 0 close(2) = 0 exit_group(0) = ? +++ exited with 0 +++
In the preceding output, we can read that after a prologue (removed into this output due to spacing reasons), the program execute open()
on the /tmp/foo
file (which is the file we supplied to cat
), which returns the file descriptor number 3
, and then it executes read()
on that file descriptor returning the file content and, in the end, it executes a write()
system call on the file descriptor 1
(that is, the standard output), passing to it the just read buffer. When the program executes another read()
and it returns 0
(that is, an End-of-File), the program exits, closing all opened files descriptors. In the end, strace
returns the program's exit code as well.
Package management
In the first chapter, we already learned how install a package into our new Debian distribution; however, there are a few more things to add in order to manage the system's packages.
The following commands can be executed indifferently in the host PC or in one of our developer kits (for the next examples, as a developer kit, we used the BeagleBone Black).
Searching a software package
For example, we know that installing the vim (Vi Improved) package can be simply done using the following command:
root@bbb:~# aptitude install vim
In the preceding command, we're assuming that the package containing vim
has the same name as that of the software tool. However, this is not always true! For instance, if we wish to install the PHP command-line interface (the tool used to execute PHP scripts from the command line), we may assume the package's name was php-cli
, and then we can try to install the package using this command:
root@bbb:~# aptitude install php-cli
But, in this case, we will get the following error message:
Couldn't find package "php-cli". However, the following packages contain "php-cli" in their name: php-google-api-php-client No packages will be installed, upgraded, or removed. 0 packages upgraded, 0 newly installed, 0 to remove and 3 not upgraded Need to get 0 B of archives. After unpacking 0 B will be used.
Doh! So, which is the correct package name? Here is where the apt-cache
command comes in handy. Just type the following command on the console:
root@bbb:~# apt-cache search php cli
We will get a long list of packages related to the words php
and cli
(in fact, we can assume that both these words may be in both package names or descriptions). Now we can search which package suits our needs and we can try to filter the output using the grep
command, as shown here:
root@bbb:~# apt-cache search php cli | grep '^php[^ ]*cli' php-google-api-php-client - Google APIs client library for PHP php-horde-cli - Horde Command Line Interface API php-horde-imap-client - Horde IMAP Client php-horde-socket-client - Horde Socket Client php5-cli - command-line interpreter for the php5 scripting language php-seclib - implementations of an arbitrary-precision integer arithme tic library
Tip
The ^php[^ ]*cli
string is a regular expression, which asks grep
to select only those lines whose hold at the beginning of the line is a string starting with php
and ending with the cli
chars without any space in the middle.
Now, as we can see, the output is now shorter and at a quick glance we can see that the desired package is named php5-cli
.
Another useful command is the apt-file
command, which can be used to find a package holding a specific file even if it is not installed on the system. It's unlikely that this command is installed into our developer kit's default distribution by default, so we must install it ourselves:
root@bbb:~# aptitude install apt-file
When the installation ends, we must update apt-file
data through the following command:
root@bbb:~# apt-file update
Now, for example, if we get an error during a compilation where a file, say, libcurses.so
is missing, we can obtain the package name holding that file using the apt-file
command, as shown here:
root@bbb:~# apt-file search libncurses.so libncurses-gst: /usr/lib/gnu-smalltalk/libncurses.so libncurses5: /lib/arm-linux-gnueabihf/libncurses.so.5 libncurses5: /lib/arm-linux-gnueabihf/libncurses.so.5.9 libncurses5-dbg: /usr/lib/debug/lib/arm-linux- gnueabihf/libncurses.so. 5.9 libncurses5-dbg: /usr/lib/debug/libncurses.so.5 libncurses5-dbg: /usr/lib/debug/libncurses.so.5.9 libncurses5-dev: /usr/lib/arm-linux-gnueabihf/libncurses.so
The preceding message shows us that the desired package name is libncurses5-dev
.
Installing a package
A brief note on some pitfalls in installing new packages must be added. We already told you how to install a package; we can use both apt-get
and aptitude
commands, as reported in the next two commands:
root@arm:~# apt-get install evtest root@arm:~# aptitude install evtest
The commands can be used interchangeably even if, as reported in the next section, they have several differences. However, for both of them, we can get an error message as follows:
root@arm:~# aptitude install evtest The following NEW packages will be installed: evtest libxml2{a} sgml-base{a} xml-core{a} 0 packages upgraded, 4 newly installed, 0 to remove and 29 not upgrade d. Need to get 846 kB of archives. After unpacking 1658 kB will be used. Do you want to continue? [Y/n/?] Err http://ftp.us.debian.org/debian/ wheezy/main libxml2 armhf 2.8.0+d fsg1-7 404 Not Found [IP: 64.50.233.100 80] Err http://ftp.us.debian.org/debian/ wheezy/main sgml-base all 1.26+nm u3 404 Not Found [IP: 64.50.233.100 80] ...
In this case, the list of available packages is not updated to their latest version and they must be updated using one of the two commands here:
root@arm:~# apt-get update root@arm:~# aptitude update
As in the install
case, the preceding commands are perfectly equivalent. In fact we have:
root@arm:~# aptitude update Ign http://ftp.us.debian.org wheezy InRelease Get: 1 http://ftp.us.debian.org wheezy Release.gpg [2373 B] Get: 2 http://ftp.us.debian.org wheezy Release [191 kB] Get: 3 http://ftp.us.debian.org wheezy/main Sources [5984 kB] ...
Then the installation should go till the end without errors:
root@arm:~# aptitude install evtest The following NEW packages will be installed: evtest libxml2{a} sgml-base{a} xml-core{a} 0 packages upgraded, 4 newly installed, 0 to remove and 111 not upgrad ed. Need to get 803 kB/848 kB of archives. After unpacking 1621 kB will be used. Do you want to continue? [Y/n/?] Get: 1 http://ftp.us.debian.org/debian/ wheezy/main libxml2 armhf 2.8. 0+dfsg1-7+ wheezy5 [788 kB] Get: 2 http://ftp.us.debian.org/debian/ wheezy/main sgml-base all 1.26 +nmu4 [14. 6 kB] ...
As a final note, the next two commands can be used to upgrade all packages to their most recent version:
root@arm:~# apt-get dist-upgrade root@arm:~# aptitude safe-upgrade
Tip
There are other commands that can be used to upgrade all packages with different behaviors not reported in this book; however, you can take a look at the commands' man pages to get further information on them.
apt-get and friends versus aptitude
Since the first chapter, we suggested that you install the aptitude
tool to manage the Ubuntu or Debian packages used in the host PC or our developer kits. We asserted that aptitude
is smarter than apt-get
; now it's time to explain a bit why.
Looking at the apt-get
man pages, we see that this command is a command-line interface to handle packages and may be considered the backend for the other low-level tools of the package management system. In fact, using it, we can easily install or remove a package with its dependencies and/or update a single package or the whole system.
On the other hand, the aptitude
command's man pages tells us similar things. In fact, this command is still a high-level interface for the package manager but, as already stated, it's smarter; we can use it for several useful tasks that we do with apt-get
or apt-cache
and other commands of the same family:
- Easy package installation or removal at once: We can install and remove packages using a single command. For instance, the following command will install
packageA
, removepackageB
, and purgepackageC
:$ aptitude install packageA packageB- packageC_
- We can put one or more packages in a hold status, that is, we inform the system to cancel any active installation, upgrade or remove, and prevent this package from being automatically upgraded in the future. The command is the same as earlier, but the package name is followed by the
=
sign. An example ispackageD=
. - We can get very detailed information about one or more packages:
$ aptitude show vim Package: vim State: installed Automatically installed: no Version: 2:7.4.1689-3ubuntu1 Priority: optional Section: editors Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com> Architecture: amd64 Uncompressed Size: 2377 k Depends: vim-common (= 2:7.4.1689-3ubuntu1), vim-runtime (= 2:7.4.1689-3ubuntu1), libacl1 (>= 2.2.51-8),libc6 (>= 2.15), libgpm2 (>= 1.20.4), libselinux1 (>= 1.32), libtinfo5 (>= 6) Suggests: ctags, vim-doc, vim-scripts Conflicts: vim:i386 Provides: editor Provided by: vim-athena (2:7.4.1689-3ubuntu1), vim-athena-py2 (2:7.4.1689-3ubuntu1), vim-gnome (2:7.4.16893ubuntu1), ... Description: Vi IMproved - enhanced vi editor Vim is an almost compatible version of UNIX editor Vi. Many new features have been added: multi level undo, syntax highlighting, command-line history, online help, filename completion, block operations, folding, Unicode support, and so on. This package contains a version of vim compiled with a rather standard set of features. This package does not provide a GUI version of Vim. Refer to the other vim-* packages if you need more (or less). Homepage: http://www.vim.org/
- We have a very powerful package searching engine! For example, using the following command, we can get a list of all installed packages that have the string editor in their description field:
$ aptitude search '~i?description(editor)' i dia - Diagram editor i A dia-common - Diagram editor (common files) i A dia-libs - Diagram editor (library files) i A dia-shapes - Diagram editor i A docbook-xml - standard XML documentation sys tem for soft i ed - classic UNIX line editor i emacs - GNU Emacs editor (metapackage) ... i nano - small,friendly text editor inspired by Pi i sed - The GNU sed stream editor i vim - Vi IMproved - enhanced vi i vim-common - Vi IMproved - Common files i A vim-runtime - Vi IMproved - Runtime files i vim-tiny - Vi IMproved - enhanced vi i A x11-apps - X applications
- Also, we can use boolean expressions; using the following command, we search all packages that have the
firmware
string in thename
field andwireless
in thedescription
one:$ aptitude search '?and(?name(firmware),?description(wireless))' p atmel-firmware - Firmware for Atmel at76c50x p firmware-b43-installer - firmware installer for the b43 p firmware-b43legacy-installer - firmware installer for the b43l
- We can ask
aptitude
to explain the reason why a particular package should or cannot be installed on the system or to find a dependency chain leading to a conflict with the target package. If we try to execute this command selecting a package to install, we'll get all related information:$ aptitude why xvile i vim Suggests vim-scripts p vim-scripts Suggests exuberant-ctags p exuberant-ctags Suggests vim | nvi | vile | emacsen p vile Depends vile-common (= 9.8q-1build1) p vile-common Recommends vile | xvile
- We can show all package names that are installed and that are not either essential or automatically installed by dependencies:
$ aptitude search '~i!(~E|~M)' -F '%p'
Note
Refer to the following URL for a detailed guide:
- Then, last but not least,
aptitude
has a text-based menu interface to manage all packages! In fact, if we execute it without any arguments, it starts in its visual interface, as shown in the following figure:
The deb files
Another useful command to manage a package is dpkg
. This is a very basic command to manage packages and it should be used by experienced users only since we can damage our system if improperly used!
However, we're going to use it when we have to install a package hold into a deb file using the following command line:
root@bbb:~# dpkg -i <package.deb>
Where <package.deb>
is the package's file.
Managing the kernel messages
As already stated, the serial console is very helpful if we need to set up a system from scratch but it's also very useful if we wish to see kernel messages as soon as they are generated. However, using a silly trick, we can get these kernel messages on a terminal emulator through a normal SSH connection too by executing the tail
command introduced earlier, as shown here:
root@bbb:~# tail -f /var/log/kern.log
In fact, the tail
command executed with the option argument -f
will open the target file and will display any new line appended to it. This can be very similar to what happens on a serial console, but you should consider the following:
- If the system is not yet fully functional, we have no network devices to use for the SSH connection.
- Using the
tail
command, we may miss important kernel messages, that is, an Oops message, due to the fact that the system can become unstable because of some kernel bugs! In this situation, we need to display the errors as soon as they arrive and thetail
command cannot do it safely.Note
An Oops is an error, a deviation from correct behavior of the kernel, that produces a kernel panic condition that may allow continued operation but with compromised reliability. The output produced by these errors is typically called Oops messages. They are special kernel debugging messages that may arrive, for instance, during an interrupt handler causing a system crash and, in this special situation, the
tail
command will not work as expected. Only the serial console can help the developer!
On the other hand, if we are connected to the serial console, we can capture these special messages since they are displayed on the serial console as soon as they arrive!
Note that this behavior can be disabled by default, and then the easier way to enable it again is using a special file in the procfs filesystem named /proc/sys/kernel/printk
.
If we try to read its content, we get the following output:
root@bbb:~# cat /proc/sys/kernel/printk 4 4 1 7
These obscure numbers have a well-defined meaning; in particular, the first one represents the error message level that must be shown on the serial console.
Let me explain this a bit better. Kernel messages are defined in the linux/include/linux/kern_levels.h
file.
Note
The procfs (proc filesystem) is one of the most important filesystems we can find in a Linux-based system, so you may spend some time to study it. A good starting point can be found at http://en.wikipedia.org/wiki/Procfs . This file is present in the Linux's source tree, and in the next chapter, we'll learn how to obtain it.
The definitions are as follows:
#define KERN_EMERG KERN_SOH "0" /* system is unusable */ #define KERN_ALERT KERN_SOH "1" /* action must be taken immediat. */ #define KERN_CRIT KERN_SOH "2" /* critical conditions */ #define KERN_ERR KERN_SOH "3" /* error conditions */ #define KERN_WARNING KERN_SOH "4" /* warning conditions */ #define KERN_NOTICE KERN_SOH "5" /* normal but significant condit. */ #define KERN_INFO KERN_SOH "6" /* informational */ #define KERN_DEBUG KERN_SOH "7" /* debug-level messages */
Since the first number in the /proc/sys/kernel/printk
file is 4
, it means that the only displayed messages will be KERN_EMERG
, KERN_ALERT
, KERN_CRIT
and KERN_ERR
.
Now it's quite simple to guess that in order to enable all kernel messages, we must replace the first number 4
with 8
because there are no kernel messages with a lower priority than 7
:
root@bbb:~# echo 8 > /proc/sys/kernel/printk
Tip
Kernel messages' priorities start from 0
(the highest) and go up till 7
(the lowest)!
On the other hand, we can disable all kernel messages using the number 0
:
root@bbb:~# echo 0 > /proc/sys/kernel/printk
Note that the preceding commands just replace the first number; in fact, if we read the file content again, we get the following output:
root@bbb:~# cat /proc/sys/kernel/printk 0 4 1 7