Commonly used Ubuntu Linux commands 常用的Ubuntu Linux指令

Go to End

Note

18/7/2026: "Backup a directory of files", "Mount devices" and "Set up SSH keys to access remote computer" updated, and "Define time scheduled jobs" and "Install Chrony" sections added.

15/7/2026: "Update firmware" section added.

6/7/2026: More commands added to view system information.

23/4/2026: "Switch user" section added.

3/2/2026: "Recreate deleted user with specific UID" and "Recreate mailbox-only account" sections added.
29/1/2026: "micro" added as an editor. "gksudo gedit" removed.

29/7/2022: Setting up SSH keys added.

18/4/2022: cp -Rav added.

14/4/2022: Command to delete multiple empty sub-directories added.

18/12/2021: Updated.

6/10/2018: Updated.

27/9/2018: Updated.

21/3/2018: Updated.

27/8/2017: Created.

Intro

$ = the terminal command prompt against which commands are entered.

sudo = superuser acting as the root user.

<text> = information to be entered, angle brackets themselves are not to be entered.

[abc] = options a, b and c, brackets are not necessary.

Capitals and small letters behave differently.

Switch user

(section added, 23/4/2026)

Precede a terminal command with "sudo" if acting like the root user is required.

$ sudo <command statement>
  • Files created to be owned by the superuser.

Switch to act as the root user:

$ sudo -i

Exit root:

# exit

Switch to act as another user, and exit later:

$ sudo -u <another_name> -i
$ exit
  • No need to precede with sudo.
  • Cannot act as the root user.
  • Files created to be owned by "another_name".

View system information

(more commands added, 6/7/2026)

Show who am I:

$ whoami

Show current date and time:

$ date

Show this month's calendar:

$ cal

List processes with details like user ids, process ids (PID), CPU/memory usages, and commands of the current user:

$ ps aux

or

$ ps -ef
  • showing less columns

or

$ ps aux | less
  • giving a progressive list

or

$ ps aux | grep dovecot
  • filter to show lines containing "dovecot"

or

$ ps -f
  • showing processes in the current terminal session

Show process id of a process by name:

$ pgrep -l dovecot

List commands and process ids of the current user:

$ lsof -i

List commands and process ids of all users:

$ sudo lsof -i

Show real-time view of running processes:

$ top
  • press "q" to exit
  • press "Shift + P" to sort by CPU
  • press "Shift + M" to sort by memory

Aternatively:

$ htop
  • press "F10" to exit

List active internet connections (only servers)

$ sudo netstat -lptu

or

$ sudo netstat -lptun

Display disk space:

$ df

Display disk space in a more readable format:

$ df -h

Display file contents:

$ cat <directory>/<sub-directory>/<filename>

Use path and file names

<directory path> = <directory>/<sub-directory> referring from the current directory, without filename stated.

<filename path> = <directory>/<sub-directory>/<filename> referring from the current directory.

Precede with "/" if referring the path from the root directory. Deleting files under a sub-directory but incorrectly referring to the root directory is dangerous. Better avoid referring from the root directory.

Use "*" as a wildcard to represent texts before or after directory or file name, e.g. "*name", "name*" or "*" for any name.

Use "." alone to represent the current directory.

Use "../" to represent the directory immediately above the current directory.

Use "/." at the end to represent all under the stated <directory path>, e.g. "<sub-directory>/."

Search things

Find files with filenames containing <filename> in <directory path>:

$ find <directory path> -name "<filename>"

Use "-iname" to ignore upper or lower case differences.

Find the files and open for editing:

$ find <directory path> -iname "<filename>" -exec micro '{}' \;

Find text in files:

$ grep -[options] <text> <filename path>

where option:

  • -i = ignore upper or lower case differences
  • -r = search sub-directories recursively
  • -h = hide names of files preceding lines of output
  • -w = search for exact text
  • -c = count the number of matches
  • -n = precede lines of output with the numbers of lines containing the text
  • -v = show only lines not containing the text
  • -l = list filenames only
  • --colour = display the output in colour

Adjust disk space

Find duplicate files across several directories and replace duplicate files with hard links to save space:

$ sudo rdfind -makehardlinks true <directory path 1> <directory path 2>

note: rdfind downloadable at https://rdfind.pauldreik.se/rdfind.1.html#lbAG.

Recover such harddisk space of deleted files not reported by "$ df":

$ cd /<directory name of the harddisk> 
​​$ sudo dd if=/dev/zero of=tempfile 
$ sudo rm tempfile

Edit files

Text editor

$ sudo micro <filename path>

or text editor

$ sudo nano <filename path>

or GUI editor

$ sudo gedit <filename path>

Shutdown and start up

Shutdown the system:

$ sudo shutdown

Shutdown and reboot the system:

$ sudo reboot

Start a service:

$ sudo systemctl start <service name>

or older method:

$ sudo service <service name> start

or even older method:

$ sudo /etc/init.d/<service name> start

Restart a service:

$ sudo systemctl restart <service name>

or older method:

$ sudo service <service name> restart

or even older method:

$ sudo /etc/init.d/<service name> restart

Stop a service:

$ sudo systemctl stop <service name>

or older method:

$ sudo service <service name> stop

or even older method:

$ sudo /etc/init.d/<service name> stop

Mount devices

(updated 18/7/2026)

Mount a single device, e.g. Network attached system, qnap2:

$ sudo mkdir /mnt/qnap2
$ sudo mount /mnt/qnap2

Can use /media or any /<folder> instead of /mnt.

Remounting required after reboot.

Umount single device "/mnt/qnap2":

$ sudo umount -l /mnt/qnap2

Check devices defined in the filesystem table file "fstab" to be mounted upon booting:

$ cat /etc/fstab

Check devices actually mounted (this would show more than those defined in "fstab"):

$ sudo mount -l

Set up SSH keys to access remote computer

(section added, 29/7/2022)

(updated, 15/7/2026)

SSH keys

rsa key is older.

ed25519 key is newer

Generate public/private rsa key pair:

$ sudo ssh-keygen -t rsa
(or)
$ sudo ssh-keygen -t ed25519

Enter file in which to save the key (/root/.ssh/<'id_rsa' or 'id_ed25519'>): <accept or change>

Skip entering passphrase if you do not want to use it upon logging in with ssh.

Skip it for use with remote drive to be automatically mounted.

If "sudo" is not used, the prompted file to save will be "/home/<your_user_name>/.ssh/<'id_rsa' or 'id_ed25519'>".

Use "sudo" because mounting remote drive would need "root".

If the file already exists, answer overwrite or not.

id_rsa (private key) and id_rsa.pub (public key) will actually be created.

or

id_ed25519 (private key) and id_ed25519.pub (public key) will actually be created.

Copy the public key to the remote computer connectable via <port_number>:

$ sudo ssh-copy-id -i /root/.ssh/id_rsa.pub -p <port_number> <login_name>@<remote_computer_address>
(or)
$ sudo ssh-copy-id -i /root/.ssh/id_ed25519.pub -p <port_number> <login_name>@<remote_computer_address>

Enter password to the remote login name.

It will check whether the key has already existed.

Add "-f" if desired to force copy to overwrite an existing key:

$ ssh-copy-id -f -i /root/.ssh/id_rsa.pub -p <port_number> <login_name>@<remote_computer_address>
(or)
$ ssh-copy-id -f -i /root/.ssh/id_ed25519.pub -p <port_number> <login_name>@<remote_computer_address>

Verify by logging in after successful copying:

$ sudo ssh -i /root/.ssh/id_rsa.pub -p <port_number> <login_name>@<remote_computer_address>
(or)
$ sudo ssh -i /root/.ssh/id_ed25519.pub -p <port number> <login_name>@<remote_computer_address>

If login successful, you are at the command prompt of the remote computer and can execute commands there:

$ ls -la .ssh
(to show)
$ ls -la .ssh/authorized_keys
(which contains the copied public key)

Enter "exit" after use.

Mount using a script file

To mount the remote computer (NAS qnap2) on /mnt/qnap2:

$ sudo micro setupsshfs.sh

Enter in the file:

sudo sshfs -o IdentityFile=/root/.ssh/id_rsa,port=12022,reconnect,ServerAliveInterval=15,ServerAliveCountMax=3,uid=1000,gid=1000,idmap=user,allow_other <login_name>@<remote_computer_address>:</remote/path> /mnt/qnap2

No space permitted except as shown.
Save and exit.

Execute to mount:

$ sudo mkdir /mnt/qnap2
$ ./setupsshfs.sh
(to mount)
$ df -h
$ ls -ls /mnt/qnap2
(to verify)

This method is stable but the mounted drive needs to be remounted after re-booting.

Mount using fstab

To make the mounting permanent, configure in /etc/fstab:

$ sudo micro /etc/fstab

Add the following line:

sshfs#<login_name>@<remote_computer_address>:</remote/path>: /mnt/qnap2 fuse IdentityFile=/root/.ssh/id_rsa,port=<port number>,reconnect,ServerAliveInterval=15,ServerAliveCountMax=3,uid=1000,gid=1000,idmap=user,allow_other,_netdev 0 0

No space permitted except as shown.
Save and exit.

Execute to mount:

$ sudo systemctl daemon-reload
$ sudo mount /mnt/qnap2
(or)
$ sudo mount -a
$ df -h
(to see whether actually mounted on /mnt/qnap2)

Try this to connect the mount if the remote computer was not connected when the computer was booted:

$ ls /mnt/qnap2

However, this method is not very stable.

Mount using systemd service

The best is to configure it as a systemd service:

$ sudo micro /etc/systemd/system/mnt-qnap2.mount

Edit as:

[Unit]
Description=SSHFS mount for QNAP2
After=network-online.target
Wants=network-online.target

[Mount]
What=sshfs#<login name>@<remote computer address>:</remote/path>
Where=/mnt/qnap2
Type=fuse
Options=IdentityFile=/root/.ssh/id_rsa,port=12022,reconnect,ServerAliveInterval=15,ServerAliveCountMax=3,uid=1000,gid=1000,idmap>

# no space permitted

[Install]
WantedBy=multi-user.target

[Service]
Restart=on-failure
RestartSec=120
TimeoutSec=10
  • TimeoutSec=10 → each sshfs attempt gives up after 10 seconds if the NAS isn’t reachable.
  • RestartSec=120 → systemd waits 2 minutes before trying again.

Save and exit.
Execute to mount:

$ sudo systemctl daemon-reload
$ sudo systemctl enable mnt-qnap2.mount
$ sudo systemctl start mnt-qnap2.mount
$ sudo systemctl status mnt-qnap2.mount

See "setupsshfs.txt" in our administrator's home folder to see our company's exact settings for the above three methods.

Add or delete groups and users

Create new group:

$ sudo addgroup <new group name>

Create new user, with a group and a home directory of the same name created if not already existing:

$ sudo adduser <new user name>

To verify:

$ ls -lh /home

shows that the new directory has "drwxr-xr-x" permissions, i.e. "d" for directory with "rwx" owner permissions but "r-x" group and others' permissions.

Add a user to a group:

$ sudo adduser <user name> <group name>

Delete user, and group of the same name, keeping the home directory:

$ sudo deluser <user name>

Delete group:

$ sudo delgroup <group name>

Change ownership

Change file or directory ownership:

$ chown -R <owner name>:<group name> <filename path>

where:

  • -R = recursively from and below if <filename> is a sub-directory

Change permissions

Change file or directory permissions:

$ chmod -R [ugoa][-+=][rwxXst] <filename path>

where:

  • -R = recursively from and below if <filename> is a <sub-directory>
  • u=owner, g=group, o=others, a=all
  • -+= mean minus, add or equal permissions
  • r=read, w=write and delete, x=execute file or change directory into; Xst=for more special choices
  • e.g. "u+rw" = add read and write permission to owner

An alternative form is:

$ chmod -R <ugo> <filename path>

where:

  • <ugo> is a 3 digit number where u=owner, g=group, o=others
  • each digit can be:
    • 0 for nothing
    • 1 for execute "x"
    • 2 for write "w"
    • 3 = 1 + 2 = "wx"
    • 4 for read "r"
    • 5 = 4 + 1 = "rx"
    • 6 = 4 + 2 = "rw"
    • 7 = 4 + 2 + 1 = "rwx"

therefore:

  • 666 = read and write permissions to all
  • 777 = read, write and execute permissions to all

Change password

Change own password:

$ passwd

Change other user 's password:

$ sudo passwd <other user's name>

Recreate deleted user with specific UID

(section added, 3/2/2026)

To recreate deleted user account:

  • Existing email folders: /home/xyz/Maildir
  • User ID = 1234
  • User name = xyz

Open Command Prompt.

Check the presence of directory xyz and the UID of the Maildir is 1234:

> ls -ls /home
> sudo ls -ld /home/xyz/Maildir

Re-create full user account with the same UID and login shell:

> sudo useradd -u 1234 -d /home/xyz -s /bin/bash xyz
  • -u 1234 → sets the UID to 1234
  • -d /home/xyz → sets the home directory
  • -s /bin/bash → sets the default shell

Set the password for the re-created user:

> sudo passwd xyz

Enter and confirm the password.

Fix ownership of the Maildir (if needed) if the Maildir or home directory files are not owned by UID 1234 after recreating the user:

> sudo chown -R xyz:xyz /home/xyz

Ensure UID is 1234 and Maildir is accessible:

> id xyz
> sudo -u xyz ls /home/xyz/Maildir

If another user already exists with UID 1234, resolve that conflict first (either delete or re-assign that user).
Always back up the Maildir before making changes, just in case ownership or permissions get misapplied.

Recreate mailbox-only account

(section added, 3/2/2026)

To recreate deleted user account for mail delivery:

  • Existing email folders: /home/xyz/Maildir
  • User ID = 1234
  • User name = xyz

Open Command Prompt.

Check the presence of directory xyz and the UID of the Maildir is 1234:

> ls -ls /home
> sudo ls -ld /home/xyz/Maildir

Re-create mailbox-only account with the same UID but without login shell:

> sudo useradd -u 1234 -d /home/xyz -s /usr/sbin/nologin xyz

-s /usr/sbin/nologin → prevents shell login

Set a locked password o nobody can log in interactively:

> sudo passwd -l xyz

Enter and confirm the password.

Fix ownership of the Maildir (if needed) if the Maildir or home directory files are not owned by UID 1234 after recreating the user:

> sudo chown -R xyz:xyz /home/xyz

Ensure UID is 1234 and Maildir is owned by xyz.

> id xyz
> ls -ld /home/xyz/Maildir

If another user already exists with UID 1234, resolve that conflict first (either delete or re-assign that user).
Always back up the Maildir before making changes, just in case ownership or permissions get misapplied.

Optional: Restrict home directory access if you want to prevent accidental browsing:

> sudo chmod 700 /home/xyz
  • Only xyz (and root) can access it.

The account will still be valid for mail delivery and IMAP/POP access using Postfix + Dovecot.

The nologin shell ensures it can’t be used for SSH or console login.

Create directories

Make new directory:

$ mkdir <directory>

Make new directory and sub-directory in one go, "-p" means making parent directory also:

$ mkdir -p <directory>/<sub-directory>

Remove files and directories

Remove empty sub-directory:
$ rmdir <directory path>

Remove one empty sub-directory and its parent directory in one go:

$ rmdir /<parent directory>/<sub-directory>

Remove all empty sub-directories and their parent directories in one go:

$ cd <directory>
$ find . -type d -empty -print -delete

If directory is empty, print name then delete.

(added, 14/4/2022)

Remove file:

$ rm <filename path>

Remove files and directories starting from and below sub-directory, even for empty sub-directory:

$ rm -r <directory path>

List and change directories

List names of current directory contents, hiding entries starting with ".":

$ ls

List current directory contents, with more detailed information:

$ ls -[options]

where options

  • l = list also permissions, owners, date and size
  • a = list also entries starting with "."
  • h = to be used in conjunction with "l", show file sizes in "K" or "M"

List other directory contents:

$ ls -[options] <directory path>

Change working directory:

$ cd <directory path>

Copy files and directories

(section added, 18/4/2022)

Copy a file within the same directory:

$ cp <source filename> <new filename>

Copy a file across different directories, keeping the same filename:

$ cp <source directory>/<sub-directory>/<filename> <target directory>/<sub-directory>/.​

to give:

<target directory>/<sub-directory>/<filename>

​Copy a file across different directories, to a new filename:

$ cp <source directory>/<sub-directory>/<filename> <target directory>/<sub-directory>/<new filename>

to give:

<target directory>/<sub-directory>/<new filename>

Omit:

<source directory>/<sub-directory>/

if copying files in the current directory.

Copy directories recursively, keeping the directory name:

$ cp -R <source directory>/<sub-directory A> <target directory>/.

to give:

<target directory>/<sub-directory A>

Copy directories recursively:

$ cp -R <source directory>/<sub-directory A> <target directory>/<sub-directory B>

If sub-directory B exists, all files and directories under sub-directory A will be copied under sub-directory B.

If sub-directory B does not exist, it will be created, and all files and directories under sub-directory A will be copied under it.

Copy directories recursively (-R) keeping original attributes (-a) and showing verbose progress (-v):

$ cp -Rav <source directory>/<sub-directory A> <target directory>/<sub-directory B>

Move files and directories

Use "mv" instead of "cp" for the above copy commands. No need to use "-R". Recursive move is the default.

Backup a directory of files

(updated, 19/7/2026)

Archive (-a) all files under a sub-directory (A) and all sub-sub-directories underneath to the same sub-directory name under another sub-directory (B) keeping all the file attributes, symbolic links and time-stamps unchanged, preserving hard-links (-H) and displaying the progress verbosely (-v) and the numbers in human-readable format (-h):

$ sudo rsync -aHvh <source directory>/<sub-directory A> <target directory>/<sub-directory B>/​

to give:

<target directory>/<sub-directory B>/<sub-directory A>

The command can be used repeatedly to update the files in sub-directory A in the new location. If the source files have not been changed, no over-writing copying will be done. This would save time and is better than the cp command.

Options:

-a = archive mode (permissions, symlinks, etc.)

-A = preserve ACL permissions

-H = use hard links 

-X = preserve extended attributes

-v = verbose

--ignore-existing = skips files that already exist on the destination

--remove-source-files = remove from source

--dry-run = shows what would happen, but doesn’t actually copy.

--info=progress2 = gives a running count of files and progress

/A/B/   /C/D/

means rsync folders and files under B/ to under D/.

/A/B   /C/D/

means rsync B to under D/.

Update firmware

(section added, 15/7/2026)

The server may notify that "n devices have a firmware upgrade available. Run `fwupdmgr get-upgrades` for more information."

Check available upgrades:

$ sudo fwupdmgr get-upgrades

Apply the upgrades:

$ sudo fwupdmgr update

Reboot:

$ sudo reboot

Verify no more upgrades:

$ sudo fwupdmgr get-devices
$ sudo fwupdmgr get-upgrades

Note:

  • Backup important data before updating (rare risk of instability).
  • Keep using AC power while upgrading.
  • Do not interrupt the update process — forced shutdowns can affect hardware.
  • Some updates are staged and applied at the next reboot.
  • Check vendor support: not all devices publish firmware via LVFS; unsupported ones require manual vendor tools.
  • Logs: If something fails, check /var/log/fwupd.log for details.

Define time scheduled jobs

(section added, 18/7/2026)

Introduction:

  • A "cron" (Greek "chronos" = time) job executes commands or scripts automatically at specified times, dates, or intervals. If the computer is off at that time, the job is missed.
  • "crontab" = cron table.
  • "anacron" specifies which cron jobs will be followed up. If a specified cron job misses to run at the specified time, anacron will run it soon after reboot.

Basic crontab syntax:

minute hour day month weekday command
  • minute: 0–59
  • hour: 0–23
  • day: 1–31
  • month: 1–12 or Jan–Dec
  • weekday: 0–6 or Sun–Sat
  • command: The script or command to execute

Special Syntax Shortcuts (may vary by system):

  • @daily – once a day
  • @weekly – once a week
  • @reboot – at system startup

Cron example:

0 0 * * * /path/to/script.sh

means run the script at:

  • 0 = 0 minute
  • 0 = 0 hour
  • * = every day of month
  • * = every month
  • * = every day of week

Cron example:

*/5 * * * * /path/to/script.sh

means run the script every 5 minutes.

Anacron example:

1   5   cron.daily   run-parts /etc/cron.daily
7   10  cron.weekly  run-parts /etc/cron.weekly
30  15  cron.monthly run-parts /etc/cron.monthly
  • 1 = every 1 day
  • 5 = delay 5 minutes after boot
  • cron.daily = job name

List crontabs of different users:

$ sudo ls /var/spool/cron/crontabs

Find crontab of specific application:

$ ls /etc/cron.d | grep <key part of name of application, e.g. backintime>
(cron will run it)
$ ls /etc/cron.daily | grep <key part of name of application>
(anacron will run it too)

Inspect it:

$ sudo cat /etc/cron.d/<full name of application found>

View crontab:

$ crontab -l
(your own)
$ sudo crontab -l
(root's)
$ sudo crontab -u username -l
(another user's)

Show system‑wide cron jobs:

$ ls -l /etc/cron.d/
# cat /etc/cron.d/*

Show daily/weekly/monthly jobs (run via anacron):

$ ls -l /etc/cron.daily/
$ ls -l /etc/cron.weekly/
$ ls -l /etc/cron.monthly/

Show anacron configuration:

$ cat /etc/anacrontab

Do not edit the crontab files directly.

Edit crontab:

$ crontab -e
(your own)
$ sudo crontab -e
(root's)
$ sudo crontab -u username -e
(another user's)

Remove crontab:

$ crontab -r
(your own)
$ sudo crontab -r
(root's)
$ sudo crontab -u username -r
(another user's)

Replace your own crontab with a file:

$ crontab mycronfile

Save your current crontab to a file:

$ crontab -l > mycronfile

List users using cron or denied to use cron:

$ cat /etc/cron.allow
$ cat /etc/cron.deny

However, Ubuntu does not have those files, meaning that all users can use cron.

List to show users permitted to use cron:

$ ls -l /var/spool/cron/crontabs

To enable user crontab:

Check where the user and "crontab" are in groups:

$ groups

If not in, add user to the crontab group:

$ sudo usermod -aG crontab <user name>

Log out and back in (or reboot) to apply group membership.

Try again:

$ crontab -e

Enter as a simple test:

* * * * * echo "Cron test $(date)" >> ~/cron_test.log

Save and exit. Within a minute or two, you should see lines appearing in ~/cron_test.log. That proves the user crontab is active.

Add user, alternatively:

$ sudo touch /etc/cron.allow
$ echo <user name> | sudo tee -a /etc/cron.allow

Give a complete snapshot of all scheduled jobs on the system:

$ echo "=== User crontab ==="; crontab -l 2>/dev/null
$ echo "=== Root crontab ==="; sudo crontab -l
$ echo "=== /etc/cron.d ==="; sudo grep -r . /etc/cron.d/ 2>/dev/null
$ echo "=== cron.daily ==="; ls /etc/cron.daily
$ echo "=== cron.weekly ==="; ls /etc/cron.weekly
$ echo "=== cron.monthly ==="; ls /etc/cron.monthly
$ echo "=== anacrontab ==="; cat /etc/anacrontab

Show what is actually running:

journalctl -u cron
(or)
grep CRON /var/log/syslog

Install Chrony

(section added, 19/7/2026)

Chrony is a modern time synchronization service that keeps the server’s system clock accurate by using the Network Time Protocol (NTP).

It has not been properly installed when Ubuntu 26.4 is freshly installed. The error message appears only when the server is starting up and is only seen when the starting up messages roll up the screen.

The following can verify and rectify as necessary:

Make sure chrony is installed:

$ sudo apt update
$ sudo apt install chrony -y

Ensure the _chrony user/group exist:

$ sudo adduser --system --no-create-home --group --shell /usr/sbin/nologin _chrony

Fix ownership of chrony directories:

$ sudo chown -R _chrony:_chrony /var/lib/chrony
$ sudo mkdir -p /run/chrony
$ sudo chown _chrony:_chrony /run/chrony

(Optional) Fix or disable keyfile:

$ sudo chown root:_chrony /etc/chrony/chrony.keys
$ sudo chmod 640 /etc/chrony/chrony.keys

or comment out 'keyfile /etc/chrony/chrony.keys' in /etc/chrony/chrony.conf.

Reload systemd and restart chrony:

$ sudo systemctl daemon-reexec
$ sudo systemctl daemon-reload
$ sudo systemctl enable chrony
$ sudo systemctl restart chrony
$ sudo systemctl status chrony

Verify synchronization:

$ chronyc tracking
$ chronyc sources

End of Page