This is a riveting series:
- On the LPIC-1 Exam 101: System Architecture
- On the LPIC-1 Exam 101: Linux Installation and Package Management
- On the LPIC-1 Exam 101: GNU and Unix Commands
- On the LPIC-1 Exam 101: Devices, Linux Filesystems, FHS
When studying for the Linux Professional Institute LPIC-1 certification, I took a bunch of notes when reading the docs and doing an online course. Note that this is not exhaustive, so do not depend on this article to get you prepared for the exam.
The menu items below are not in any order.
This roughly covers Topic 103: GNU and Unix Commands.
Caveat emptor.
- Exam Details
- Topic 103: GNU and Unix Commands
- Summary
- References
Exam Details
- Exam Objectives Version: 5.0
- Exam Code: 101-500
Topic 103: GNU and Unix Commands
Some Unix
and Shell Commands
uname
Get kernel name:
$ uname
Linux
$ uname -s
Linux
Print kernel release:
$ uname -r
5.10.0-20-amd64
Print kernel version:
$ uname -v
#1 SMP Debian 5.10.158-2 (2022-12-13)
Print the machine hardware:
$ uname -m
x86_64
Print the network node hostname:
$ uname -n
kilgore-trout
Print the OS:
$ uname -o
GNU/Linux
hash
To increase performance, recently used commands will be added to a hash table for faster lookup. The type
Bash builtin will show if a command has been hashed.
For example:
$ type man
man is /usr/bin/man
$ man man
$ type man
man is hashed (/usr/bin/man)
To remove a command from the hash table:
$ type man
man is hashed (/usr/bin/man)
$ hash -d man
$ type man
man is /usr/bin/man
To add a command(s) to the hash table:
$ type man which
man is /usr/bin/man
which is /usr/bin/which
$ hash man which
$ type man which
man is hashed (/usr/bin/man)
which is hashed (/usr/bin/which)
To view the help:
$ help hash
history
To write the current history to the history file (usually, `$HOME/.bash_history):
$ history -w
Commands that have been recently executed are not automatically written to the
.bash_history
file. The-w
switch will “flush” the history list to the file.
To clear the history list by deleting all of the entries:
$ history -c
To select and execute the 666th command in the history list:
$ !666
To view the help:
$ help history
env
vs set
env
will print all of the environment variables for a shell session.
set
will also print the environment variables, but it also will print the functions, too.
However, unlike set
, env
will not print custom variables that have not been exported:
$ biscuit=yum
$ set | ag biscuit
biscuit=yum
$ env | ag biscuit
Let’s now export it:
$ export biscuit
$ env | ag biscuit
biscuit=yum
Why is this?
Recall that set
is a Bash builtin, while env
will run in a subprocess. That subprocess, however, will not inherit an environment variable that has not been exported, just as spawning a new shell would not inherit an unexported variable as part of its environment inherited from its parent.
The current set of Bash options is in the special
-
parameter:$ "$-" himBCHs
These can then be looked up by running
help set
.
paste
The paste
command will merge lines from multiple files. The delimiter between the colums defaults to TAB
, but this can be changed with the -d
switch:
$ echo -e "a\nb\nc\nd\ne" > chars
$ cat chars
a
b
c
d
e
$ echo -e "1\n2\n3\n4\n5" > ints
$ cat ints
1
2
3
4
5
$ paste chars ints
a 1
b 2
c 3
d 4
e 5
$ paste -d: chars ints
a:1
b:2
c:3
d:4
e:5
sort
od
The tool od
lists out a file’s contents in octal format.
$ od cmds.txt
0000000 072542 075156 070151 005062 075142 060543 005164 075142
0000020 070151 005062 060543 005164 072547 075156 070151 063412
0000040 064572 005160 067165 075170 074012 005172 075170 060543
0000060 005164 061572 072141 000012
0000067
The first column is the byte offset for each line of output. The following eight columns each contain the octal value of he data within the column.
Display printable characters:
$ od -ac cmds.txt
0000000 b u n z i p 2 nl b z c a t nl b z
b u n z i p 2 \n b z c a t \n b z
0000020 i p 2 nl c a t nl g u n z i p nl g
i p 2 \n c a t \n g u n z i p \n g
0000040 z i p nl u n x z nl x z nl x z c a
z i p \n u n x z \n x z \n x z c a
0000060 t nl z c a t nl
t \n z c a t \n
0000067
Note the newlines.
od
can display the data in other character formats, such as hexadecimal:
$ od -x cmds.txt
0000000 7562 7a6e 7069 0a32 7a62 6163 0a74 7a62
0000020 7069 0a32 6163 0a74 7567 7a6e 7069 670a
0000040 697a 0a70 6e75 7a78 780a 0a7a 7a78 6163
0000060 0a74 637a 7461 000a
0000067
$ od -cx cmds.txt
0000000 b u n z i p 2 \n b z c a t \n b z
7562 7a6e 7069 0a32 7a62 6163 0a74 7a62
0000020 i p 2 \n c a t \n g u n z i p \n g
7069 0a32 6163 0a74 7567 7a6e 7069 670a
0000040 z i p \n u n x z \n x z \n x z c a
697a 0a70 6e75 7a78 780a 0a7a 7a78 6163
0000060 t \n z c a t \n
0a74 637a 7461 000a
0000067
Hide the offset column:
$ od -An -c cmds.txt
b u n z i p 2 \n b z c a t \n b z
i p 2 \n c a t \n g u n z i p \n g
z i p \n u n x z \n x z \n x z c a
t \n z c a t \n
cut
cut
will remove sections from each line of a file.
The canonical example is to use /etc/passwd
:
$ cut -d: -f1,7 /etc/passwd | tail
saned:/usr/sbin/nologin
colord:/usr/sbin/nologin
geoclue:/usr/sbin/nologin
btoll:/bin/bash
systemd-timesync:/usr/sbin/nologin
systemd-coredump:/usr/sbin/nologin
nm-openvpn:/usr/sbin/nologin
Debian-gdm:/bin/false
lightdm:/bin/false
debian-tor:/bin/false
The will print out the first and seventh columns, which are the username and login shell, respectively.
As another example, select the first 10 characters of every line:
$ cut -c1-10 /etc/passwd | tail
saned:x:11
colord:x:1
geoclue:x:
btoll:x:10
systemd-ti
systemd-co
nm-openvpn
Debian-gdm
lightdm:x:
debian-tor
And the first, third and fifth character of every line:
$ cut -c1,3,5 /etc/passwd | tail
snd
clr
gol
bol
sse
sse
n-p
Dba
lgt
dba
tr
The tr
tool will translate or delete characters that it receives on its standard input channel. It expects its input to be redirected.
The canonical example is to change (translate) the colon delimiters in the /etc/passwd
file to another character. Here, we use a pipe character:
$ tr : "|" < /etc/passwd | head
root|x|0|0|root|/root|/bin/bash
daemon|x|1|1|daemon|/usr/sbin|/usr/sbin/nologin
bin|x|2|2|bin|/bin|/usr/sbin/nologin
sys|x|3|3|sys|/dev|/usr/sbin/nologin
sync|x|4|65534|sync|/bin|/bin/sync
games|x|5|60|games|/usr/games|/usr/sbin/nologin
man|x|6|12|man|/var/cache/man|/usr/sbin/nologin
lp|x|7|7|lp|/var/spool/lpd|/usr/sbin/nologin
mail|x|8|8|mail|/var/mail|/usr/sbin/nologin
news|x|9|9|news|/var/spool/news|/usr/sbin/nologin
Remove the ^M
EOL control character from Windows files:
$ tr -cd '\11\12\40-\176' < chars
nl
The nl
tool numbers the lines of the files. This is only for display, it doesn’t modify the file.
$ nl README.md
sed
Let’s start with a small file filled with Unix commands:
$ cat cmds.txt
bunzip2
bzcat
bzip2
cat
gunzip
gzip
unxz
xz
xzcat
zcat
We’ll demonstrate the different ways we can get information from the file using the stream editor sed
.
Stream editors operate on a line at a time.
List only the lines displaying the word “cat”:
$ sed -n '/cat/p' cmds.txt
bzcat
cat
xzcat
zcat
The -n
option will suppress the automatic printing of everything in the pattern space (the entire file). Let’s see what happens when we remove it:
$ sed '/cat/p' cmds.txt
bunzip2
bzcat
bzcat
bzip2
cat
cat
gunzip
gzip
unxz
xz
xzcat
xzcat
zcat
zcat
It has printed everything in the pattern space and the lines that include the word “cat” twice. This makes, since the p
sed
command told it to print lines that contain the search word.
sed -n 'p' cmds.txt
is equivalent tocat cmds.txt
.
To delete all the lines containing the word “cat” and output the rest:
$ sed '/cat/d' cmds.txt
bunzip2
bzip2
gunzip
gzip
unxz
xz
Find and replace and print only the lines that match the word to be replaced:
$ sed -n 's/cat/dog/p' cmds.txt
bzdog
dog
xzdog
zdog
Find and replace and print the entire file:
$ sed 's/cat/dog/' cmds.txt
bunzip2
bzdog
bzip2
dog
gunzip
gzip
unxz
xz
xzdog
zdog
Do in-place editing:
$ sed -i.backup 's/cat/dog/' cmds.txt
$
This will first make a copy of the original file called cmds.txt.backup
. Nothing will be printed to the screen, since the original file was edited in-place:
$ ls
cmds.txt cmds.txt.backup
Omit the suffix (so, just
-i
) to not create a backup.
Note that I’ve used quotes in all of the sed
examples in this section, but they aren’t strictly necessary.
find
Can search on file type:
All are prefeced by -type
, i.e., -type f
:
- files
f
- directories
d
- symbolic links
l
- sockets
s
- character devices
c
- block devices
b
- named pipes
p
Other interesting expressions:
-user
-group
-atime
(access time in hours)-amin
(access time in minutes)- `-delete (delete all files that match result)
-empty
(or-size 0b
)-exec
(perform action on the result set)find -type f -name *.log -exec rm {} \;
find . -name "*.conf" -exec chmod 644 '{}' \;
-readable
(matches for current user)-writable
(matches for current user)-executable
(matches for current user)-perm
-iname
(inode)-mtime
(modification time)-maxdepth
-size
-print0
(print the full filename on the standard output, followed by a null character (instead of the newline character that-print
uses))- good for scripting and
find -exec
- good for scripting and
-mount
- avoid searching mounted filesystems
-fstype
tar
See Archiving and Compressing.
cpio
The cpio
archive tool takes its list of files to archive piped to stdin
and writes to stdout
. For example, to create an archive:
ls | cpio -vo > archive.cpio
-o
isCopy-out
mode.
To extract this archive:
cpio --no-absolute-filenames -id < archive.cpio
-i
isCopy-in
mode.
Note that the default is --absolute-filenames
, which is to preserve the system prefix components of the filenames.
dd
The tool dd
is used to convert and copy a file. I’ve used it mainly to create a live USB.
$ sudo dd if=~/Downloads/ubuntu-22.04-desktop-amd64.iso of=/dev/sdb1 bs=4M
bs
is the number of bytes to read and write at a time.
Add a progress bar:
$ sudo dd if=~/Downloads/ubuntu-22.04-desktop-amd64.iso of=/dev/sdb1 bs=4M status=progress
Convert to uppercase:
$ dd if=oldfile of=newfile conv=ucase
uniq
The uniq
will print the non-duplicate lines to standard out. It’s important to note, however, that non-contiguous duplicate lines are not counted as duplicates and will be displayed by uniq
. For this reason, it’s highly recommended to sort
prior to running uniq
.
$ sort chars | uniq
a
b
c
d
e
$ sort chars | uniq -c
2 a
2 b
2 c
2 d
2 e
The following example is functionally equivalent to the previous one:
$ uniq -c <(sort chars)
2 a
2 b
2 c
2 d
2 e
Let’s take another similar file with less data to save room on this article, because it’s getting completely out of control:
$ cat chars
a
b
c
a
b
c
Only print duplicate lines, one for each group:
$ sort chars | uniq -d
a
b
c
Print all duplicate lines:
$ sort chars | uniq -D
a
a
b
b
c
c
tee
tee
reads from stdin
and writes to both stdout
and files.
$ ls | tee dir_list.txt
This is good for things such as running in a command in very verbose mode (-vvv
) and at the same time capturing the output in a logfile.
Append to an existing file:
$ ./my_command -vvv | tee -a out.txt
Capture both stdout
and stderr
when compiling:
$ make 2>&1 | tee log.txt
xargs
Build and execute command lines from standard input using xargs
.
-n 1
or-L 1
-0
-I
In the following examples, pretend that filelist.txt
contains a list of images.
$ xargs -I IMG convert IMG -resize 25% small/IMG < filelist.txt
The following is equivalent:
$ cat filelist.txt | xargs -I IMG convert IMG -resize 25% small/IMG
jobs
jobs
is a shell builtin. They are attached to the user who invoked them. If the session is killed, the background processes are re-parented to PID 1 (active foreground processes are killed dead along with their parent).
Jobs can be stopped with a jobspec
:
- job ID (different from PID)
kill %1
- string
kill %sleep
- contains string
kill %?eep
- current job
kill %+
kill %%
- previous job
kill %-
If there is only one job, it will be both current and previous.
nohup
The nohup
(“no hang up”) command runs a command immune to hangups, with output going to a non-tty
(so, a file) with a default name of nohup.out
. This file will be written to by both stdout
and stderr
.
The hangups refer to a signal called SIGHUP
that are sent to a process when its controlling terminal is closed.
$ nohup ping localhost &
[1] 1251
$ nohup: ignoring input and appending output to 'nohup.out'
^C
Note that you can also use the Bash builtin
disown
to target a running process to not receive aSIGHUP
signal on shell logout, just as with thenohup
command.
watch
The watch
utility will watch a program periodically (by default, every two seconds) and will display fullscreen. To exit, send watch
the SIGINT
signal (Ctrl-C
).
Change the time interval:
watch -n 8 free
Don’t display the title:
watch -t free
top
By default top
will sort by CPU percentage used by a process (P
) in descending order. Here are some other ways to sort (all are uppercase):
M
- memory usageN
- PIDT
- running timeR
- toggle between ascending and descending listing
Other useful keybindings that may be interactive, i.e., top
will ask for more information (like a PID):
?
orh
- helpk
- kill a process, will ask for PID and signal (defaults toSIGTERM
)r
- change the priority, aka,renice
, will ask for value (-20 through 19)- only superuser can change to a negative value or lower than the current value
u
- only list processes from a particular user, will ask for user (either name or UID)c
- show a program’s absolute path and differentiate between userspace processes and kernelspace processesV
- shows process hierarchyt
orm
- change the look of CPU and memory readings respectively in a four-stage cycle:- the first two presses show progress bars
- the third hides the bar
- the fourth brings it back
W
- saves configuration settings (saved mine to “$HOME/.config/procps/toprc”)
Note that the summary (top) area of top
shows much of the same information as uptime
and free
(and also w
).
Other
top
variants arehtop
andatop
.
nice
Play nice
.
renice
renice
changes the priority of a running process.
A program can also be reniced by
top
. Intop
, pressr
, enter then the PID, and then change the value.
Only privileged users can renice to a negative value and a value lower than what is currently assigned.
locate
The locate
command, used to quickly search a system for a file, does not search the filesystem, but a datase.
This database will need to be updated manually by running updatedb
, so any files created or added since its last invocation will not be searchable by locate
.
The location of the database on my system is
/var/lib/mlocate/mlocate.db
.
Conversely, any files that have been deleted since its last run will also still be in the search database.
$ touch ooga-booga
$ locate ooga-booga
$ locate ooga-booga
/home/btoll/projects/benjamintoll.com/ooga-booga
$ rm ooga-booga
$ locate ooga-booga
/home/btoll/projects/benjamintoll.com/ooga-booga
Let’s say that we know that it will take to long to update the database, so we don’t want to run updatedb
. But, we don’t want to include false positives, like ooga-booga
. What is there to do?
Just add the -e
switch, yo, that will print only entries that refer to files existing at the time locate
is run.
$ locate -e ooga-booga
$
Just don’t forget to run updatedb
as soon as possible.
By default, the searches will be case sensitive. Just use the -i
switch to do a case insensitive search.
Pass multiple search patterns and count the results (-c
):
$ locate -c zip jpg gz
27807
Use -A
to only match on all search patterns:
$ locate -cA zip jpg gz
0
Write statistics about each read database to standard output instead of searching for files and exit successfully:
$ locate -S
Database /var/lib/mlocate/mlocate.db:
45,883 directories
5,28,916 files
3,43,05,654 bytes in file names
1,38,08,284 bytes used to store database
Note that it’s possible to configure the behavior of updatedb
by modifying /etc/updatedb.conf
.
My default configuration file looks like this:
$ cat /etc/updatedb.conf
PRUNE_BIND_MOUNTS="yes"
# PRUNENAMES=".git .bzr .hg .svn"
PRUNEPATHS="/tmp /var/spool /media /var/lib/os-prober /var/lib/ceph"
PRUNEFS="NFS afs autofs binfmt_misc ceph cgroup cgroup2 cifs coda configfs curlftpfs debugfs devfs devpts devtmpfs ecryptfs ftpfs fuse.ceph fuse.glusterfs fuse.gvfsd-fuse fuse.mfs fuse.rozofs fuse.sshfs fusectl fusesmb hugetlbfs iso9660 lustre lustre_lite mfs mqueue ncpfs nfs nfs4 ocfs ocfs2 proc pstore rpc_pipefs securityfs shfs smbfs sysfs tmpfs tracefs udev udf usbfs"
Note that all except the last should have space-delimited values.
PRUNEFS=
- a case-insensitive list of filesystem types that should be ignoredPRUNENAMES=
- a list of directory names that will be ignoredPRUNEPATHS=
- a list of path names that will be ignoredPRUNE_BIND_MOUNTS=
- if “yes”, bind mounts will be ignored
Processes
ps
The ps
command allows for three different styles of options:
BSD
- no hyphensps U alice
Unix
- one hyphenps -u alice
GNU
- two hyphensps --user alice
A very common example:
ps aux
- BSD-style
- similar to the output of
top
a
- show process that have atty
u
- display user-oriented format (all users)x
- show process that are not attached to atty
Information can be displayed differently depending upon which style is employed (unfortunately).
In addition to the PID
, TTY
, TIME
and CMD
columns that ps
shows, the long listing also shows UID
, PPID
, PRI
(priority), NI
(nice
), etc.
$ ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 1000 4772 4471 0 80 0 - 2195 - pts/0 00:00:01 bash
0 T 1000 27289 4772 0 80 0 - 5980 - pts/0 00:00:16 vim
0 S 1000 27929 1 0 80 0 - 24720 - pts/0 00:00:00 python
4 R 1000 42349 4772 0 80 0 - 2421 - pts/0 00:00:00 ps
Let’s say all that you have is the process ID 591720 (PID). How can you find out more information about it?
$ ps -Fl -p 591720
F S UID PID PPID C PRI NI ADDR SZ WCHAN RSS PSR STIME TTY TIME CMD
0 S btoll 591720 1 0 80 0 - 1343 - 568 2 13:42 ? 00:00:00 sleep 777
Switches:
-F
: extra full format (implies-f
)-l
: long format-p
: specifies the PID
You can also use the [
pidof
] command to find the PID of a running process.
pgrep
List the process of a (effective) user (use -l
to print the program name of the corresponding PID
):
$ pgrep -lu btoll
3386 systemd
3388 (sd-pam)
3486 pipewire
3487 pulseaudio
3490 bash
3508 dbus-daemon
3530 pipewire-media-
3595 gpg-agent
3609 dbus-daemon
3872 startx
3901 xinit
3902 Xorg
4467 sh
4471 tmux: server
4772 bash
4778 i3
...
Print the processes for both a specific user and terminal:
$ pgrep -lu btoll -t tty1
3490 bash
3872 startx
3901 xinit
3902 Xorg
4467 sh
4778 i3
Find the PID
of a Vim session:
$ pgrep -u btoll vim
47988
renice
all my Firefox web containers:
$ renice +10 $(pgrep "Isolated Web Co")
6858 (process ID) old priority 0, new priority 10
6875 (process ID) old priority 0, new priority 10
7393 (process ID) old priority 0, new priority 10
7496 (process ID) old priority 0, new priority 10
11869 (process ID) old priority 0, new priority 10
11927 (process ID) old priority 0, new priority 10
22608 (process ID) old priority 0, new priority 10
22644 (process ID) old priority 0, new priority 10
...
pkill
Sends SIGTERM
by default to each process.
Display the name and the PID
of the process being killed:
$ sleep 10000 &
[2] 17314
$ pkill -e sleep
sleep killed (pid 17314)
[2]- Terminated sleep 10000
Kill it dead using either symbolic or numeric signal name:
$ sleep 8888 &
[2] 18184
$ pkill --signal SIGKILL sleep
[2]- Killed sleep 8888
$
$ sleep 7777 &
[2] 20880
$ pkill -9 sleep
[2]- Killed sleep 7777
Archiving, Compressing and Tarballing
The tar
(tap archiver) command will collect a group of files into one archive file.
Archiving
Common operations:
c
,--create
x
,--extract
t
,--list
u
,--update
Common switches:
-f
,--file
-v
,--verbose
-C
,--directory
The traditional usage is the BSD-style of no hyphens, tar cvf
or tar xvf
. Here, we’ll use the Unix-style usage of switches that use the single hyphen:
-
creating
tar -cvf
-
extracting
tar -xvf
-
extract to a specific directory
tar -xvf archive.tar -C /tmp
Compressing
Compression utilities:
Creating:
gzip README.md
- replaces
README.md
withREADME.md.gz
- replaces
bzip2 README.md
- replaces
README.md
withREADME.md.bzip2
- replaces
xz README.md
- replaces
README.md
withREADME.md.xz
- replaces
Uncompression utilities:
Extracting a tarball:
gunzip README.md.gz
bunzip2 README.md.bzip2
unxz README.md.xz.
Tarballing
A tarball is a compressed tar
archive.
( And I don’t know if anyone actually says “tarballing”. )
-
creating a tarball
gzip
tar -czvf archive.tgz music
- another common extension is
.tar.gz
bzip2
tar -cjvf archive.bz2 music
- another common extension is
.tar.bz2
or.tar.bz
xz
tar -cJvf archive.xz music
- another common extension is
.tar.xz
-
extracting a tarball
gunzip
tar -xzvf archive.tgz music
bunzip2
tar -xjvf archive.bz2 music
unxz
tar -xJvf archive.xz music
-
listing a tarball
tar -tf foo.tar.xz
- works regardless of compression
-
updating a tarball
gunzip
tar -xzvf archive.tgz music
bunzip2
tar -xjvf archive.bz2 music
unxz
tar -xJvf archive.xz music
Viewing Compressed Tarballs
-
- viewing
gzip
tarballs zcat foo.tar.gz
- viewing
-
- viewing
bzip2
tarballs bzcat foo.tar.bz2
- viewing
-
- viewing
xz
tarballs xzcat foo.tar.xz
- viewing
Shell Quoting
$ foo=42
$ echo $foo
42
$ echo "$foo"
42
$ echo '$foo'
$foo
Checksums
A checksum is a small block of data that is derived mathematically (based on a cryptographic hash function) from another block of data for the purpose of detecting errors and verifying data integrity.
They are frequently used when downloading archives, tarballs, disk images, etc., from the Internet.
Common command-line utilities to compute checksums are:
Compute a checksum:
$ sha256sum README.md
aa85c32f6fe4f5cd76b808a9d4e11a4cbf034fda626a9d6006a8ea1878731ef1 README.md
Output a checksum:
$ sha256sum README.md > SHA256SUMS
$ cat SHA256SUMS
aa85c32f6fe4f5cd76b808a9d4e11a4cbf034fda626a9d6006a8ea1878731ef1 README.md
Note that the calculated checksum is the same. It will always be the same for the same block of data.
Verify the integrity of the README.md
file against the checksum file:
$ sha256sum -c SHA256SUMS
README.md: OK
The file doesn’t need to be included when checking the checksum file, as it is included after the checksum itself (TAB
delimited).
Verify the integrity of multiple files:
$ sha256sum README.md build_and_deploy.sh config.toml > SHA256SUMS
$ cat SHA256SUMS
aa85c32f6fe4f5cd76b808a9d4e11a4cbf034fda626a9d6006a8ea1878731ef1 README.md
d82135b2e46c3a5b8d16db1ae30cddca772f255b381f9db929c9ecbd757878b7 build_and_deploy.sh
2baf225d6a8a4df97d869f79c941d370002f8277ae367ac86b4e40cc54480ebe config.toml
$ sha256sum --check SHA256SUMS
README.md: OK
build_and_deploy.sh: OK
config.toml: OK
Of course, if the checksum doesn’t match what was expected for the file, you wouldn’t want to use it, possibly even alerting the owner of the file as to the failure (that is, after repeated downloads resulted in failures and wasn’t the result of something arbitrary and innocuous).
File Globbing
File globbing is using special characters known as wildcards to match one or more filenames on the system. The wildcards are are expanded by the shell to find all possible matches.
*
- matches zero or more characters
?
- matches a single character
[]
- matches characters within the brackets
- like a character class in a regular expression
Of course, they can be combined and used more than once in a search pattern.
Redirects
Every Linux process gets three file descriptors by default.
For instance, my Bash shell process has the following open file descriptors:
$ ls -l /proc/$$/fd
total 0
lrwx------ 1 btoll btoll 64 Jan 17 14:00 0 -> /dev/pts/1
lrwx------ 1 btoll btoll 64 Jan 17 14:00 1 -> /dev/pts/1
lrwx------ 1 btoll btoll 64 Jan 17 14:00 2 -> /dev/pts/1
lrwx------ 1 btoll btoll 64 Jan 18 00:04 255 -> /dev/pts/1
Since I’m using a pseudo-terminal, they are all symlinks to /dev/pts/1
(the reason for this is out of the scope of this article).
The reassignment of a channel’s file descriptor in the shell environment is called a redirect. The target of a redirect can be either a file or a file descriptor.
Redirecting stdout
:
>
>>
1>
1>>
Redirecting stdin
:
<
0<
<<
0<<
Redirecting stderr
:
2>
2>>
Programs often send debug information to
stderr
as well as error information.
Redirect both stdout
and stderr
:
&>
>&
&>>
>>&
Redirect both stdout
and stderr
to a file:
> log.txt 2>&1
Redirect stdout
to a file and stderr
to the abyss:
> log.txt 2> /dev/null
Here Document and Here String
Here documents and here strings are formally stream literals, and they can be redirected to a command that expects to receive its input from stdin
. In less formal terms, it can take the place of a file descriptor.
They are ordinary strings used for input redirection.
Here is an example of a here document:
If the file descriptor isn’t specified, it’s assumed to be 0, stdin
.
$ uniq -c <<EOF
> dooby
> dooby
> doo
> EOF
2 dooby
1 doo
Here, we’re explicit about the file descriptor, with the same results:
$ uniq -c 0<<EOF
> dooby
> dooby
> doo
> EOF
2 dooby
1 doo
Here is an example of a here string:
$ wc -c <<<"Stevie Ray Vaughan will always Rave On"
39
$ wc -c <<<"Stevie Ray Vaughan will always Rave On"
39
I often do this when using bc
:
$ bc <<<1*2*3*4*5
120
You can think of
bc
as a command-line calculator.
Here is one last example of a here-document
:
$ cat <<.>/dev/stdout
> poo
> bear
> wha?
> .
poo
bear
wha?
Bash will enter Heredoc
input mode and then exit when a period appears in a line by itself (of course, the delimiting identifier could be any textual string).
In this case, the typed text will be redirected to stdout
, but I’ve often done this where I’m taking some quick notes and redirecting the output to a file for later perusal.
$ cat <<NOTES> /tmp/for/later.txt
There must be two greater than symbols (
<
) directly prior to the delimiting identifier (“NOTES”, in the last example).
Terminal Multiplexers
In electronics, a multiplexer (or mux
) is a device that allows for multiple inputs to be connected to a single output. A terminal multiplexer gives us the ability to switch between different inputs as required.
Process Priority
Linux is a preemptive multi-processing operating system. The preemptive means that a process with a higher priority cantake control of the CPU over a process currently controlling the CPU but with a lower priority.
The Linux scheduler handles the scheduling of processes, or tasks, and handles CPU resource allocation for these running tasks.
Processes have two predicates that intervene on their behalf:
- scheduling policy
- real-time policy
- processes under this policy are scheduled by their priority values directly
- lower priority processes only gain control when the higher priority processes are idle or are waiting on a response from hardware (I/O)
- only a few processes fall under the umbrellas of real-time processes
- normal policy
- most processes on a system run under a normal policy (both system and user)
- real-time policy
- scheduling priority
- usually called static scheduling priorities
- static priorities range from 0 - 99 for real-time processes
- static priorities range from 100 - 139 for normal processes
- meaning that there are 39 different priorities
- lower values have a higher priority
- processes under a normal policy usually have the same priority value
- they can be changed using
nice
andrenice
- usually called static scheduling priorities
Only processes under normal scheduling policy will be affected when inspecting and tuning process scheduling.
You can view the priority number of a process by getting the information about the scheduling information about the process:
$ grep ^prio /proc/$$/sched
prio : 120
$ grep ^prio /proc/1/sched
prio : 120
The standard priority of a normal process is 120, as shown here. It can be increased to 139 or decreased to 100.
The priority of all running processes can be seen with
top
or `ps.For example, the following command and options are equivalent:
ps -el ps -Al
See:
Summary
Continue your journey with the fourth (and last) installment in this titillating series, On the LPIC-1 Exam 101: Devices, Linux Filesystems, FHS.