meta name="revised" content="2/20/2026">
Updated: 2/20/2026
In 2021, there were 27.9 millions of lines of source code in the Linux Kernel, and 1.3 million in systemd. Systemd is the first process to run when Linux starts. It is a replacement for init. The "D" in Systemd is for Directories. Systemd is used by most but all Linux distributions. Android does not use systemd.
/bin /sbin /usr/bin/ and usr/sbin : Where executable programs are stored.
/bin : OS critical binary (executable) files
/sbin : - Support S binary (executable) files
/usr : User files (non-administator files - sometimes install by a user).
/usr/bin : User binary (executable) files.
/usr/sbin : Support user binary (executable) files.
/opt : Optional or added files by the user.
/boot : files need to boot the OS.
/var : Where varable-length files, like log files are stored.
/etc : Where configuration (.conf) files are stored.
/dev : Where device files are stored.
/mnt : mount
/media : CD ROM and Thumb Drives
/temp : temporary
/proc : runing process (porgrams)
/home : Where User Directories are stored.
| * | # Matches any number of characters |
| ? | # Matches any single character |
| [ ] | # Matches any character in the brackets (character set) |
| Examples: | |
| F* | # Matches any string that begins with "F" |
| *.txt | # Matches any string that ends with ".txt" |
| *ing | # Matches any string that ends with "ing" |
| F*ing | # Matches any string that begins with "F" and ends in "ing". |
| S?n | # Matches any 3 character string that begins with "S" and end with "n" |
| S[ao]n | # Matches "San" and "Son" |
| ls [option]... [file or dir]... | |
| -l | # long |
| -1 | # one file per line |
| -a | # all including hidden |
| -A | # almost all does not list . or .. |
| -h | # human readable file size |
| -d | # directory details |
| -F | # Forward slash appended to directories |
| -t | # time sort (newest first) |
| -S | # Size sort (smallest first) |
| -X | # eXtension sort (file type) - no macOS |
| -r | # reverse sort order |
| -R | # Recursive list subdirectories and file |
| -s | # Allocated size (sparse file size) |
| Examples | |
| ls | // list visible files in the current directory |
| ls -alhF Documents | // list all files in the Document directory |
| ls -lh file_1.txt | // list file_1.txt if it exist else print error message |
| ls -alh file_1.txt Documents | // list both |
File and directory names can contain wild cards * and ?, but the ls command does NOT support regular expressions.
Very Useful, but not installed by Default on most Linux Distributions
| options | |
| -a | all including hidden |
| -d | directory list only |
| -L | Level of Directories |
| -t | time sort |
| -f | full file name |
| -r | reverse sort |
| -p | permissions |
| -u | user name |
| -g | group name |
| -D | Date |
| -s | size |
| -h | human readable size |
| -P | Pattern Match |
| -x | exlude other file systems |
| -dirsfirst | directories first |
| Examples | |
| ls | // list visible files in the current directory |
| ls -alhF documents | // list all files in the document directory |
| ls -lh file_1.txt | // list file_1.txt if it exist else print error message |
| ls -alh file_1.txt documents | // list both |
| mv [options] source... destination | |
| mv source_file destination_directory | # move without renaming |
| mv file_1 file_2 ... destination_dir | # move multiple files |
| mv source_file destination_dir/new_file_name | # move and rename the file |
| mv source_directory destination_directory | # if the destination dir exist, places the source dir inside the destination dir else renames the directory. |
| Options | |
| -i | (Interactive) - ask before overwritting |
| -n | (No Overwite) |
| -u | (Update) - Overwrite only if newer |
To avoid mistakes, it is best practice to place a forward slash, "/", after directories.
| cp [options] source... destination | |
| cp source_file destination_directory | # copies a file into the destination directory |
| cp file_1 file_2 ... destination_dir | # copies multiple files into the destination directory |
| cp source_file distination_file | # makes a copy with a different name |
| cp source_file destination_dir/new_file_name | # makes a copy in the destitnation directory with a different name |
| cp -r source_directory destination_directory | # copies the soure directory files and sub directories into destination directory |
| Options | |
| -r | (recursive) |
| -i | (Interactive) - ask before overwritting |
| -n | (No Overwite) |
| -u | (Update) - Overwrite only if newer |
| rm [option]... [file]... | |
| -i | # Interactive - ask before removing |
| -r or -R | # Recursive - removes files and directories |
| -f | # force - will prompt for removal of write protected files. |
rm -rf / wil remove all file and distroy the system. There is no undo command in linux. When using wild cards, it is a good idea to test first using the ls command.
| mkdir directory... | # make directory |
| rmdir directory... | # Will only remove Empty directories |
| # use rm -r to remove non-empty directories |
| cat | Send contents of a file to the console. Option -n adds line numbers to output. |
| nl | number lines. Option -n a numbers blank Lines. |
| head -n 17 | Send the 1st 17 lines to the console (default is 10 lines). |
| tails -n 19 | Send the last 19 lines to the console (can also use -n #_of_lines). |
| more | Pagination - see table below. Cannot page up . |
| less | Pagination - see table below. Can page up; also can search /. |
| Pagination Table | |
|---|---|
| next line: | enter |
| next page: | Page Down, space bar, n |
| up page: | Page Up, N |
| search: | /pattern |
| quit: | q |
| -maxdepth 3 | # search 3 dir deep |
| -type f | # search for file |
| -type d | # search for directory |
| -name pattern | # search for file name |
| -iname pattern | # case insensitive name |
| -size +600MB | # files > 600MB |
| -user uname | # files owned by uname |
| Time in Days: | |
| -atime +6 | # accessed > 6 days |
| -mtime -6 | # modified < 6 days |
| -ctime 6 | # changed 6 days ago |
| Time in Minutes: | |
| -amin +60 | # accessed > 60 min |
| -mmin -60 | # modified < 6 min |
| -cmin 60 | # changed 60 min ago |
| Permissions: | |
| - perm mode | # exact match |
| - perm -mode | # AND (at least all) match |
| - perm /mode | # OR (any) match |
| Regular Expressions | |
| -regex expression | # regular expression |
| -regextype type | # default type is emacs |
| Logical Combinations | |
| -o | # logical OR |
| -a | # logical AND - default if not specified |
| -not | # logical NOT |
If the find command does not have permission to open a directory you will get a permisson denied error message. To not show the error messages use redirection i.e. 2> /dev/null (redirect errors to /dev/null).
A changed file is one where the contents remains the same, but the meta data changes i.e. renamed file or permissions change.
The find command support regular expressions via the -regex option.
The -name option does NOT support regular expressions.
Regular Expressions Cheat Sheet
Examples:
# In the Vidoes directory, all mp4 files:
find ~/Videos/ -maxdepth 1 -iname '*.mp4'
# Starting in the users home directory, find all files greater than 1.1 GB:
find ~/ >1.1GB
# Starting in the current directory, find files modified less than 2 hours ago:
find . - mmin -120
find . - mmin -$[60*2] # using command expansion
# Starting in the documents directory, find all text and script (shell) files:
find ~/Documents/ -name '*.txt' -o -name "*.sh"
# In the documents directory, find all non-text files:
find ~/Documents/ -maxdepth 1 -not -name '*.txt'
# Sarting in the current dir, find text files not in hidden directories:
find ! -path "./.*" -name "*.txt"
Find every file in the filesystem, where the user (owner) is root and the SUID permission is set:
sudo find / -user root -perm -4000
| Examples: | |
| find ~/Videos/ -iname '*.mp4' | # find, in the Video directory, all mp4 files. |
| find . -iname '*.txt' -name "*.sh" | # find, in the current directory, all text and script (shell) files. |
| find ~/ >1.1GB | # find, in the home directory, files greater than 1.1 GB. |
| find . - mmin -120 | # find, in the current directory, files modified less than 120 minutes ago. |
Not Installed by Default in Debian or MacOS
Locate does not search for files, but looks in a database.
To update the database:
sudo updatedb
Indexed the entire hard drive. May take considerable time to update the db.
(MacOS)
WARNING: The locate database (/var/db/locate.database) does not exist.
To create the database, run the following command:
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist
Please be aware that the database can take some time to generate; once
the database has been created, this message will no longer appear.
| whereis command | List all the locations of a command |
| which command | List the first locations of a command |
| type command | List the locations & type of a command |
Grep searches a file or files for a pattern and prints the line with the pattern.
The -E option replaces the deprecated egrep version of grep.
The -F option replaces the deprecated fgrep version of grep.
| grep [options] pattern filename[s] | |
| -i | # case insensitive |
| -w | # whole word |
| -v | # invert match - line that don't match |
| -n | # line number |
| -r | # recursive |
| -l | # list files with matching lines |
| -E | # extended regexp |
| -F | # fixed (plain) strings |
Examples:
grep -i "Pi" /etc/passwd # prints user pi line
grep -E "pi|dave" /ect/passwd # prints users pi and dave lines
grep -v "^#" etc/sudoers.d # filter out comment lines
grep \bif\b /~script_file.sh # print lines with the word if (not elseif etc. \b boundary)
| sort [options]... [File]... | |
| -b | # ignore leading blanks |
| -f | # ignore case - fold lower case to uper case |
| -i | # ignore non printing characters |
| -n | # numerical sort |
| -o | # output results to a file |
| -r | # reverse sort |
| -k | # table column sort sort |
| -u | # unique only lines |
Examples:
ls -l /home/$USER | sort -nk5 # Sort by column 5 (file size)
The uniq command can suppress duplicates line or count the number of times each word occurs in a piece of text.
| uniq [options]... [Input][Outout] | |
| -c | # count number of occurances |
| -d | # print only duplicate lines |
| -D | # print all duplicate lines |
| -f N | # Skip first N fields |
| -i | # ignore case |
| -u | # print only unique lines |
Examples:
The uniq command can suppress duplicates line or count the number of times each word occurs in a piece of text.
| uniq [options]... [Input][Outout] | |
| -c | # count number of occurances |
| -d | # print only duplicate lines |
| -D | # print all duplicate lines |
| -f N | # Skip first N fields |
| -i | # ignore case |
| -u | # print only unique lines |
Examples:
su [-] [user]
| su user | # change to user but keep environment and current directory |
| su - user | # change to user and to user's environment and change to user's directory |
| sudo su | # change to root but keep envirnoment |
| sudo su - | # change to root and change to root's environment |
| uname [options] | ||
| -a | --all | # all |
| -s | --kernel-name | # kernel name (default) |
| -o | --operating-system | # operating system |
| -r | --kernel-release | # kernel revision |
| -m | --machine-name | # machine hardware name |
| -p | --processor | # processor name |
| -i | --hardware-platform | # hardware platform |
| -n | --nodename | # network node hostname |
| --versioin | # version number | |
| --help | # help | |
To see which release of Debian you are running:
cat /etc/os-release
History Commands
fc - fix command
Alias Commands
Set Command
| chsh [options] | ||
| -s | full_path_shell_name | # change shells |
| -h | --help | # change shells |
example:
chsh -s $(which dash) // change shell to dash
grep user_name /etc/passwd
Interactive Mode
Sshpass is a method of supplying the password on the same line with the command rather than waiting to be promted to enter a password. This allows you to ssh into a host from a batch file and execute commands on the host.
sshpass is not install by default. To install it:
sudo apt install sshpass
| sshpass | p'Password' | -o StrickHostKeyChecking=no | ssh | usernae@ip_address |
For example:
sshpass -p'123456' -o StrickHostIKeyChecking=no ssh bill@192.168.0.1
sshpass is used in my script that detects a power outage. The script logs into my NAS's (Synology) and exectutes a a "shutdown -h now" command.
| ping [options] | ||
| -4 | only IPv4 ping | |
| -6 | only IPv6 ping | |
| -c | count | # number of pings |
| -W | wait | # seconds to wait for a response |
example:
if ! (ping -4 -c 1 -W 1 192.168.0.1); then
echo "host 192.168.0.1 is down"
fi
In an if statement, a zero exit code is mapped to "true", and a non-zero exit code is mapped to "false" [2].
| wc [opinions] file_name | |
| new lines, words, bytes | |
| -w | words |
| -l | lines |
| -c | bytes |
| -m | char |
| id [opinions] [user_name] | |
| -u | user effective ID |
| -g | group effective ID |
| -G | All Groups |
| -n | names instead of ID:ws |
| -r | real instead of effective |
| --version | version number |
| --help | help |
pwd - present working director
date - date and time
whoami
id
hostnamectl
hostname
The passwd command will prompt you for the new password twice. You do not have to enter the old password.
-r removes user's files - best practice
df [-options]
-h : human readable
--total : calculate totals
df works only on mounted devices.
The Raspberry Pi OS does not install package by default. To install it:
sudo apt install lshw
| lshw [options] |
| lsblk [options] [device...] | |
| -a | # all |
| -D --discard | # discard (TRIM UNMAP) |
| -f --fs | # filesystem info |
| -m | # permissions |
| -S --scsi | # scsi only |
| -v | # version |
References:
| lsuab [options] | ||
| -t | # tree view | |
| -d | # by device | |
| -s | # specific device by bus | |
| -v | # verbose output | |
| ssh username@IP_address(or host_name) [options] |
| -p port_number |
The ssh sever configuration file is: /etc/ssh/sshd_config. At the end of sshd_config, you can add an allow and/or a deny list:
AllowUsers user1 user 2
DenyUsers user3 user 4
The allow/deny directives are processed in the following order: DenyUsers, AllowUsers, DenyGroups, and finally AllowGroups.
| sftp [options] username@IP_address(or host_name) | |
| -P port_number | Captial P - Port to Connect to on Remote |
| -oPort=number | - Specify Port to Connect to on Remote |
| get [-afpR] remote-path [local-path] | |
| -R | # Recursive |
| -p | # preserve ownership and file properities |
| put [-afpR] local-path [remote-path] | |
| -R | # Recursive |
| -p | # preserve ownership and file properities |
"SFTP allows you to run a command using the local shell by adding an exclamation mark (!) before the command. This lets users run commands that aren't a part of the standard SFTP shell on the local system [].
| sudo apt update | # update the package list |
| sudo apt upgrade | # install updates |
| sudo apt upgrade -y | # Ans. yes, install the updates |
| apt install pkg_name | # install package |
| apt remove pkg_name | # remove package leave config files |
| apt purge pkg_name | # remove package and config files |
| apt list --upgradable | # see which packages will be upgraded |
| apt list --installed | # list installed packages |
| apt list --installed pkg_name | # see if package is installed |
| dpkg -s package_name | # see which version of package is installed |
| apt show package_name | # show version and dependences |
| apt search games | # search for games or editors, etc |
It is possible to keep some packages from updating:
sudo apt-mark hold pkg_name # Keep a Package from Updating
sudo apt-mark unhold pkg_name # Release Hold and Allow Package Update
sudo apt-mark showhold # Show held packages
To see previous versions of packages that were install:
apt-cache policy pkg_name
This is usefully when you want to roll back to a previous version.
sudo apt install pkg_name=version_number
You can also directly install packages that you compile or download load from the Internet:
sudo dpkg -i pkg_name.deb
| options | command | args | // full ststem update |
| update | // full ststem update | ||
| check-update | // check for packages that can be updated | ||
| upgrade | // update all packages | ||
| upgrade | package_name | // update package_name | |
| search | package_name | // update package_name | |
| install | package_name | // update package_name | |
| remove | package_name | // update package_name | < /tr>|
| autoremove | package_name | // update package_name | |
| downgrade | package_name | < td> // install previous version of package_name||
| update | --exclude package_name | // update package_name |
To exclude a package from being updated, you have to add an excludepkgs statement to the /etc/dnf/dnf.conf file [1]. For example:
excludepkgs=nordvpn
There may be another way to exclude installing or updating packages by first installing dnf plugins. There are both core and third party plugins for dnf. I want my OS to be as lean as possible.
| hostname |
| icon name |
| Machine ID |
| Boot ID |
| Operating System |
| Kernel |
| Architecture |
| -a | all |
| Computer name |
date [options]...[+format]
| -I | # YYYY-MM-DD i.e. 2025-06-22 |
| -R | # i.e. Sun, 22 June 2025 08:48:14 -0500 |
| -u | # universal time (UTC) i.e. Sun, June 22 01:58:14 PM UTC 2025 |
| [+format] | |
| %d | # Day of the Month |
| %m | # Month (01-12) |
| %y | # Year 22 |
| %Y | # Year 2022 |
| %H | # Hours (00-23) |
| %I | # Hours (01-12) |
| %M | # Minutes (00-59) |
| %S | # Seconds (00-59) |
| date +%m-%d-%Y | # ie 6-22-2025 with dashes |
| date +%m/%d/%y | # ie 6/22/25 with slashes |
| date +%D | # same as %m/%d/%y |
Definations:
| Type | Name | Drive Name |
| scsi, sata, usb | scsi device | sd followed by a letter |
| eMMC & SD card | embedded Multi-Media Card block | mmcblock for by p and a number |
| NVMe | Non-Volatile Memory express | nvme followed by a number, the letter n, drive number |
mount /dev/Partition_to_Mount Path_Where_to_Mount
umount Path_to_Umount
Note, the command is "umount" and NOT "unmount"
Most Linux Distros with a GUI (Desktop) will automatically mount a USB drive at /media. However, Debian still requires you to unmount the usb drive with the command line before detaching it from the USB port. In 2023, the Raspberry Pi OS added an eject button to unmount the drive. The easiest way to unmount a drive is use the lsblk command (below) and copy the mount point then run "sudo umount" and paste in the mount point.
Syntax: lsblk [-options]
Appearently, lsblk will not list network drives. However, the following command will:
df -h
Syntax DD if=input_file of=output_file
bs=? (block size) default 512
conv=sparse
status=progress
Examble - Using DD to create an image file of a disk:
sudo dd if=/dev/sda of=/home/pi/2023_10_13_Dell_Rpi_Zero2W.img conv=sparse status=progress
Unfortunately, for a 128 GB micro SD card with only around 7 GB being used, this took over two hours to complete. This is because dd copies empty blank spaces. Without the conv=sparse option the image file size and the allocated space is 128 GBytes. With the conv=spare option, the apparent file size is 128 GBytes, but the allocated space is only 7.1 GB. To see the allocated space use the -s option with ls or use the du command.
The reverse process was much faster:
sudo dd=2023_10_13_Dell_Rpi_Zero_2W.ing of=sda
It took less than 10 minutes. However, the SD was NOT bootable by a Raspberry Pi 4.
Syntax: df [-options]
-h : human readable
--total : calculate totals
df works only on mounted devices.
Syntax: lsblk [-options]
Syntax: sudo fdisk [-options]
-l list
-h help
Unfornately, if you do not put sudo in front of this command, the system returns "command not found", which is misleading.
Syntax: du [options] [directory/file]
ps [options]
-a = all proccess
-u = users/owners show
-x = not attached to this terminal
ps displays processes in the order they were started.
Examples:
ps -aux
Top shows only the top CPU processes are shown. It continueously updates. To stop it, ctrl c.
Example:
top
htop is an improved version of top that allows you to scroll both horrizonally and vertically. You can also highlight a process and kill it with k.
Example:
htop
kill [options] <pi> [...]
kill [options] process_name [...]
Nice and renice or used to changed the priority of a process.
ATo make a backup image of everything on the system disk, the Rasberry Pi Organization gave us the accessory program "SD Card Copier" [1]. They stated "this has been difficult with the command-line tools that we recommended in the past" [1]. It works well; but it is strickly a GUI program, which excludes it from being used with servers without a GUI.
I have not been able to copy a SD-Card connected via USB to another SD-Card connected via USB. In fact, if their chipset are the same, I can not even get two SD-Cards connnected via USB to mount. This program should have been called SD-Image Copier instead of SD-Card Copier.