<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Linux Commands on Linuxize</title><link>https://linuxize.com/tags/linux-commands/</link><description>Recent content in Linux Commands on Linuxize</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><managingEditor>hello@linuxize.com (Linuxize)</managingEditor><webMaster>hello@linuxize.com (Linuxize)</webMaster><lastBuildDate>Fri, 05 Jun 2026 09:30:00 +0200</lastBuildDate><atom:link href="https://linuxize.com/tags/linux-commands/index.xml" rel="self" type="application/rss+xml"/><image><url>https://linuxize.com/icons/icon-512x512.png</url><title>Linuxize</title><link>https://linuxize.com/</link></image><item><title>npm Command: Install and Manage Node.js Packages</title><link>https://linuxize.com/post/npm-command/</link><pubDate>Fri, 05 Jun 2026 09:30:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/npm-command/</guid><category>nodejs</category><category>linux commands</category><description>This npm command guide covers project setup, local and global package installs, npm ci, updates, dependency removal, scripts, and one-off package runs.</description><content:encoded>&lt;p&gt;When you start or clone a Node.js project, one of the first things you usually do is install its packages. &lt;code&gt;npm&lt;/code&gt; is the default package manager that ships with Node.js, and it is the command you use to add, update, remove, and run project dependencies. It reads and writes the &lt;code&gt;package.json&lt;/code&gt; file that records what your project needs.&lt;/p&gt;
&lt;p&gt;This guide walks through the &lt;code&gt;npm&lt;/code&gt; commands you will use most often: starting a project, installing local and global packages, pinning versions, updating and removing dependencies, and running project scripts.&lt;/p&gt;
&lt;h2 id="syntax"&gt;Syntax &lt;a class="headline-link" href="#syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The general form of the command is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm &amp;lt;command&amp;gt; [args] [options]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;npm&lt;/code&gt; ships with Node.js, so installing Node.js installs &lt;code&gt;npm&lt;/code&gt; too. If you have not set up Node.js yet, see our guide on &lt;a href="https://linuxize.com/post/how-to-install-node-js-on-ubuntu-26-04/"&gt;installing Node.js on Ubuntu 26.04&lt;/a&gt;
. Before we run package commands, confirm both tools are available:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;node --version
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm --version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;v24.16.0
11.13.0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If &lt;code&gt;npm&lt;/code&gt; reports a version, you are ready to go.&lt;/p&gt;
&lt;h2 id="initialize-a-project"&gt;Initialize a Project &lt;a class="headline-link" href="#initialize-a-project" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Every npm project centers on a &lt;code&gt;package.json&lt;/code&gt; file. This file lists the project dependencies, scripts, package name, version, and other metadata. Create one in the current directory with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm init&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;npm&lt;/code&gt; asks a series of questions (name, version, entry point, and so on) and writes your answers to &lt;code&gt;package.json&lt;/code&gt;. To accept all the defaults without prompts, add the &lt;code&gt;-y&lt;/code&gt; flag:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm init -y&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is the usual starting point for a new project. Once &lt;code&gt;package.json&lt;/code&gt; exists, later &lt;code&gt;npm install&lt;/code&gt; commands have a file where they can record dependencies.&lt;/p&gt;
&lt;h2 id="install-packages"&gt;Install Packages &lt;a class="headline-link" href="#install-packages" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To add a package to your project, run &lt;code&gt;npm install&lt;/code&gt; with the package name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm install express&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This downloads &lt;code&gt;express&lt;/code&gt; into a &lt;code&gt;node_modules&lt;/code&gt; directory and records it under &lt;code&gt;dependencies&lt;/code&gt; in &lt;code&gt;package.json&lt;/code&gt;. npm also creates or updates &lt;code&gt;package-lock.json&lt;/code&gt;, which records the exact versions that were installed.&lt;/p&gt;
&lt;p&gt;For tools you only need while developing, such as test runners or linters, save them as development dependencies with &lt;code&gt;-D&lt;/code&gt; (short for &lt;code&gt;--save-dev&lt;/code&gt;):&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm install -D eslint&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;These land under &lt;code&gt;devDependencies&lt;/code&gt; and are skipped when a project is installed for production with &lt;code&gt;npm install --omit=dev&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;When you clone an existing project, you do not install each package by hand. Run &lt;code&gt;install&lt;/code&gt; with no arguments from the project directory:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm install&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;npm&lt;/code&gt; reads &lt;code&gt;package.json&lt;/code&gt; and the lock file, installs the missing packages, and updates &lt;code&gt;package-lock.json&lt;/code&gt; when dependency ranges need to be resolved. This is the command you usually run during local development.&lt;/p&gt;
&lt;p&gt;For CI jobs, clean deploys, and other repeatable installs, use &lt;code&gt;npm ci&lt;/code&gt; instead:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm ci&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;npm ci&lt;/code&gt; requires an existing &lt;code&gt;package-lock.json&lt;/code&gt;, removes any current &lt;code&gt;node_modules&lt;/code&gt; directory, and installs the exact dependency tree from the lock file without changing &lt;code&gt;package.json&lt;/code&gt; or &lt;code&gt;package-lock.json&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="install-global-packages"&gt;Install Global Packages &lt;a class="headline-link" href="#install-global-packages" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Some packages are command-line tools you may want available everywhere instead of tied to one project. Install them globally with &lt;code&gt;-g&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo npm install -g http-server&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The tool is then on your &lt;code&gt;PATH&lt;/code&gt; and can be run from any directory. Reserve global installs for command-line utilities. Project dependencies should stay local so each project controls its own versions.&lt;/p&gt;
&lt;div class="note callout callout-tip"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50"&gt;
&lt;path d="M25 6c-1.645 0-3 1.355-3 3v1.406c-1.945.457-3.645 1.36-4.953 2.676C15.094 15.055 14 17.848 14 21.062v7.801c0 1.836-1.004 4.164-2.04 5.89l-1.792 2.692a1.01 1.01 0 0 0-.05 1.028c.175.324.515.527.882.527h9c0 2.746 2.254 5 5 5s5-2.254 5-5h9c.367 0 .707-.203.883-.527a1.01 1.01 0 0 0-.051-1.028l-1.785-2.68-.004-.003C36.996 33.016 36 30.836 36 29v-7.8c0-5.368-3.195-9.524-8-10.759V9c0-1.645-1.355-3-3-3zm0 2c.555 0 1 .445 1 1v1.113c-.223-.02-.441-.043-.668-.05A1.064 1.064 0 0 0 25 10c-.11 0-.215.02-.316.059-.235.004-.457.027-.684.043V9c0-.555.445-1 1-1zM3.48 9.477C1.25 13.102 0 17.418 0 22s1.25 8.898 3.48 12.523l1.708-1.046C3.151 30.168 2 26.219 2 22s1.152-8.168 3.188-11.477zm43.04 0l-1.708 1.046C46.849 13.832 48 17.781 48 22s-1.152 8.168-3.188 11.477l1.708 1.046C48.75 30.898 50 26.582 50 22s-1.25-8.898-3.48-12.523zM25 12c5.512 0 9 3.668 9 9.2V29c0 2.512 1.203 4.918 2.328 6.797.012.012.02.027.027.039L37.13 37H12.87l.774-1.164c.007-.012.015-.027.027-.04C14.809 33.903 16 31.376 16 28.864v-7.8c0-2.766.914-5.004 2.469-6.57C20.019 12.925 22.239 12 25 12zm-17.184.14C5.996 15.083 5 18.356 5 22c0 3.672 1.129 7.047 2.809 9.848l1.714-1.032C8.008 28.286 7 25.262 7 22c0-3.29.871-6.148 2.516-8.809zm34.368 0l-1.7 1.051C42.13 15.851 43 18.711 43 22c0 3.262-1.008 6.285-2.527 8.816l1.718 1.032C43.871 29.047 45 25.672 45 22c0-3.645-.996-6.918-2.816-9.86zM22 39h6a3 3 0 0 1-6 0z"/&gt;
&lt;/svg&gt;
&lt;span class="callout-title"&gt;Tip&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;Using &lt;code&gt;sudo&lt;/code&gt; for global installs works but can create permission headaches. A cleaner approach is to manage Node.js with a version manager such as nvm, which installs global packages under your home directory and removes the need for &lt;code&gt;sudo&lt;/code&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="install-a-specific-version"&gt;Install a Specific Version &lt;a class="headline-link" href="#install-a-specific-version" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When a project needs a specific package release, append &lt;code&gt;@&lt;/code&gt; and the version number:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm install express@4.18.2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can also install by tag, such as &lt;code&gt;npm install express@latest&lt;/code&gt; for the newest release or &lt;code&gt;@next&lt;/code&gt; for a prerelease line. Pinning a specific version is useful when you need to match an application requirement or avoid a breaking change in a newer release.&lt;/p&gt;
&lt;h2 id="update-and-inspect-packages"&gt;Update and Inspect Packages &lt;a class="headline-link" href="#update-and-inspect-packages" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before updating packages, check what is currently installed and what newer versions are available:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm outdated&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Package Current Wanted Latest Location
express 4.18.0 4.18.2 4.19.2 node_modules/express&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;Wanted&lt;/code&gt; column is the newest version allowed by the range in &lt;code&gt;package.json&lt;/code&gt;, while &lt;code&gt;Latest&lt;/code&gt; is the newest published. Update packages to the wanted versions with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm update&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you want to move to a new major version beyond your declared range, install that version explicitly as shown above.&lt;/p&gt;
&lt;h2 id="remove-packages"&gt;Remove Packages &lt;a class="headline-link" href="#remove-packages" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When a dependency is no longer needed, uninstall it and remove it from &lt;code&gt;package.json&lt;/code&gt; with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm uninstall express&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;npm&lt;/code&gt; removes the package from &lt;code&gt;node_modules&lt;/code&gt; and updates both &lt;code&gt;package.json&lt;/code&gt; and the lock file. For a global package, add &lt;code&gt;-g&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo npm uninstall -g http-server&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="run-scripts"&gt;Run Scripts &lt;a class="headline-link" href="#run-scripts" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;scripts&lt;/code&gt; section of &lt;code&gt;package.json&lt;/code&gt; defines named commands for common project tasks. A typical file might include:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="json"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-300"&gt;json&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;scripts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;start&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;node index.js&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;test&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;jest&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Run a script with &lt;code&gt;npm run&lt;/code&gt; followed by its name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm run start&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;test&lt;/code&gt; names are special and can be run without &lt;code&gt;run&lt;/code&gt;, so &lt;code&gt;npm start&lt;/code&gt; and &lt;code&gt;npm test&lt;/code&gt; both work. Scripts are how most projects expose their build, test, lint, and development commands.&lt;/p&gt;
&lt;h2 id="list-installed-packages"&gt;List Installed Packages &lt;a class="headline-link" href="#list-installed-packages" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When you need to inspect what is installed in the current project, use:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm list&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;By default, recent npm versions show the top-level project and its direct dependencies. If you need to inspect the full nested tree, add &lt;code&gt;--all&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm list --all&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Add &lt;code&gt;-g&lt;/code&gt; to list globally installed packages instead.&lt;/p&gt;
&lt;h2 id="run-a-package-without-installing-it"&gt;Run a Package Without Installing It &lt;a class="headline-link" href="#run-a-package-without-installing-it" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;npx&lt;/code&gt; command, bundled with &lt;code&gt;npm&lt;/code&gt;, runs a package binary without a permanent global install. Use it when you need a one-off tool but do not want to add it to the project:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npx prettier@latest --check .&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;npx&lt;/code&gt; downloads the package if needed, runs it, and does not leave a global install behind. For project scaffolding, many packages also support the &lt;code&gt;npm create&lt;/code&gt; form. For example, to start a Vite React project, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm create vite@latest my-app -- --template react&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/npm/"&gt;npm cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Create package.json&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm init -y&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Install a package&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm install &amp;lt;pkg&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Install as dev dependency&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm install -D &amp;lt;pkg&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Install all dependencies&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm install&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clean install from lock file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm ci&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Install globally&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm install -g &amp;lt;pkg&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Install a specific version&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm install &amp;lt;pkg&amp;gt;@1.2.3&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Show outdated packages&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm outdated&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Update packages&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm update&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remove a package&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm uninstall &amp;lt;pkg&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Run a script&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm run &amp;lt;script&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List installed packages&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm list&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List full dependency tree&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm list --all&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Run without installing&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npx &amp;lt;pkg&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;EACCES: permission denied during a global install&lt;/strong&gt;&lt;br&gt;
A global install is trying to write to a system directory your user cannot modify. Either prefix the command with &lt;code&gt;sudo&lt;/code&gt;, or, better, manage Node.js with nvm so global packages install under your home directory without root permissions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A script exits with an npm error&lt;/strong&gt;&lt;br&gt;
The script ran but one of the commands inside it exited with an error. Scroll up to the actual command output above the npm error block; the underlying tool, not npm, is usually reporting the failure.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conflicting peer dependency errors on install&lt;/strong&gt;&lt;br&gt;
A package expects a different version of a shared dependency than what is installed. Resolve the version mismatch where possible, or, as a temporary measure, retry with &lt;code&gt;npm install --legacy-peer-deps&lt;/code&gt; while you sort out the conflict.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between dependencies and devDependencies?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;dependencies&lt;/code&gt; are packages your application needs to run. &lt;code&gt;devDependencies&lt;/code&gt; are needed only during development, such as test frameworks and linters, and are installed with &lt;code&gt;-D&lt;/code&gt;. Production installs can skip them with &lt;code&gt;--omit=dev&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What does package-lock.json do?&lt;/strong&gt;&lt;br&gt;
It records the exact version of every installed package, including nested dependencies. Commit it to version control, then use &lt;code&gt;npm ci&lt;/code&gt; when you need an exact lock-file install in CI or deployment.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between npm and npx?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;npm&lt;/code&gt; installs and manages packages, while &lt;code&gt;npx&lt;/code&gt; runs a package&amp;rsquo;s executable, downloading it temporarily if it is not installed. Use &lt;code&gt;npx&lt;/code&gt; for one-off commands and scaffolding tools.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I install a package without saving it to package.json?&lt;/strong&gt;&lt;br&gt;
Add the &lt;code&gt;--no-save&lt;/code&gt; flag, for example &lt;code&gt;npm install --no-save &amp;lt;pkg&amp;gt;&lt;/code&gt;. The package is installed into &lt;code&gt;node_modules&lt;/code&gt; but the change is not recorded in &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A small set of commands, &lt;code&gt;npm install&lt;/code&gt;, &lt;code&gt;npm ci&lt;/code&gt;, &lt;code&gt;npm update&lt;/code&gt;, &lt;code&gt;npm uninstall&lt;/code&gt;, and &lt;code&gt;npm run&lt;/code&gt;, covers nearly all package work in a Node.js project. Keep &lt;code&gt;package-lock.json&lt;/code&gt; committed, and use &lt;code&gt;npm ci&lt;/code&gt; whenever repeatable installs matter.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/npm-command/featured_hu_75a7c579e9d840cf.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>Fix "sudo: command not found" on Linux</title><link>https://linuxize.com/post/fix-sudo-command-not-found/</link><pubDate>Thu, 04 Jun 2026 09:35:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/fix-sudo-command-not-found/</guid><category>sudo</category><category>linux commands</category><description>How to fix the 'sudo: command not found' error on Linux by installing the sudo package, adding your user to the right group, and recovering from a broken PATH.</description><content:encoded>&lt;p&gt;You log in to a fresh server, try to install a package, and the shell answers with &lt;code&gt;sudo: command not found&lt;/code&gt;. It is a confusing message, because &lt;code&gt;sudo&lt;/code&gt; feels like a built-in part of Linux. In reality &lt;code&gt;sudo&lt;/code&gt; is a regular package that some minimal images and container base layers skip, and it is also one of the first commands to disappear when your shell environment is broken.&lt;/p&gt;
&lt;p&gt;This guide explains the three reasons the error shows up: &lt;code&gt;sudo&lt;/code&gt; is not installed, your user is not allowed to run it, or your &lt;code&gt;PATH&lt;/code&gt; no longer points to &lt;code&gt;/usr/bin&lt;/code&gt;. Each case has a clean fix.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What to check&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;What to do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Is sudo installed?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ls -l /usr/bin/sudo&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Install the &lt;code&gt;sudo&lt;/code&gt; package as root if the file is missing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Is your user allowed to use sudo?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;groups username&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Add the user to &lt;code&gt;sudo&lt;/code&gt; on Debian/Ubuntu or &lt;code&gt;wheel&lt;/code&gt; on Fedora/RHEL/Arch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Is PATH broken?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;echo $PATH&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Restore &lt;code&gt;/usr/bin&lt;/code&gt;, &lt;code&gt;/usr/sbin&lt;/code&gt;, &lt;code&gt;/bin&lt;/code&gt;, and &lt;code&gt;/sbin&lt;/code&gt; in your shell startup file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Does sudo work by absolute path?&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/usr/bin/sudo whoami&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fix the shell &lt;code&gt;PATH&lt;/code&gt; if this works but &lt;code&gt;sudo whoami&lt;/code&gt; fails&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="confirm-the-real-cause"&gt;Confirm the Real Cause &lt;a class="headline-link" href="#confirm-the-real-cause" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before installing anything, check whether the &lt;code&gt;sudo&lt;/code&gt; binary exists on the system:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls -l /usr/bin/sudo&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;-rwsr-xr-x 1 root root 277936 Jan 17 09:42 /usr/bin/sudo&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If the file is there with the SUID bit (&lt;code&gt;s&lt;/code&gt; in the owner permissions), &lt;code&gt;sudo&lt;/code&gt; is installed and the error is environmental. If the file is missing, you need to install the package as the root user. Pick the section below that matches your situation.&lt;/p&gt;
&lt;h2 id="install-sudo-on-debian-ubuntu-and-derivatives"&gt;Install sudo on Debian, Ubuntu, and Derivatives &lt;a class="headline-link" href="#install-sudo-on-debian-ubuntu-and-derivatives" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Minimal Debian installs and many Docker base images leave &lt;code&gt;sudo&lt;/code&gt; out. Switch to the root account first, because without &lt;code&gt;sudo&lt;/code&gt; you cannot escalate privileges from a normal user:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;su -&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Enter the root password, then install the package with &lt;code&gt;apt&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt install sudo&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If &lt;code&gt;su&lt;/code&gt; itself is rejected because root has no password (the default on Ubuntu desktop installs), boot into recovery mode or use a live USB to set a root password before retrying.&lt;/p&gt;
&lt;h2 id="install-sudo-on-fedora-rhel-and-derivatives"&gt;Install sudo on Fedora, RHEL, and Derivatives &lt;a class="headline-link" href="#install-sudo-on-fedora-rhel-and-derivatives" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;On Fedora, RHEL, Rocky Linux, and AlmaLinux, switch to root and install with &lt;code&gt;dnf&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;su -
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dnf install sudo&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On older Red Hat-family systems you may see &lt;code&gt;yum&lt;/code&gt; referenced in tutorials; &lt;code&gt;dnf&lt;/code&gt; is the current package manager and the right choice on every supported release.&lt;/p&gt;
&lt;h2 id="install-sudo-on-arch-linux"&gt;Install sudo on Arch Linux &lt;a class="headline-link" href="#install-sudo-on-arch-linux" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Arch ships a minimal base, and &lt;code&gt;sudo&lt;/code&gt; is a separate package:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;su -
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pacman -S sudo&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="install-sudo-on-alpine-linux"&gt;Install sudo on Alpine Linux &lt;a class="headline-link" href="#install-sudo-on-alpine-linux" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Alpine, which is common inside containers, uses &lt;code&gt;apk&lt;/code&gt;. Two options exist: the full &lt;code&gt;sudo&lt;/code&gt; package, or the lighter &lt;code&gt;doas&lt;/code&gt; replacement.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;su -
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apk add sudo&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you only need privilege escalation inside a container and want to keep the image small, &lt;code&gt;apk add doas&lt;/code&gt; followed by a one-line &lt;code&gt;/etc/doas.conf&lt;/code&gt; is often enough.&lt;/p&gt;
&lt;h2 id="add-your-user-to-the-sudo-group"&gt;Add Your User to the sudo Group &lt;a class="headline-link" href="#add-your-user-to-the-sudo-group" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Installing the package is only half the job. By default, only users that belong to a specific administrative group can run &lt;code&gt;sudo&lt;/code&gt;. The group name varies by distribution.&lt;/p&gt;
&lt;p&gt;On Debian and Ubuntu, the group is &lt;code&gt;sudo&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;usermod -aG sudo sara&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Fedora, RHEL, and Arch, the group is &lt;code&gt;wheel&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;usermod -aG wheel sara&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Group changes only take effect on a new login session. Log out and back in, then verify membership:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;groups sara&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;sara : sara sudo&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The presence of &lt;code&gt;sudo&lt;/code&gt; (or &lt;code&gt;wheel&lt;/code&gt;) in the list confirms the user can now run privileged commands.&lt;/p&gt;
&lt;h2 id="fix-a-broken-path"&gt;Fix a Broken PATH &lt;a class="headline-link" href="#fix-a-broken-path" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If &lt;code&gt;/usr/bin/sudo&lt;/code&gt; exists but the shell still reports &amp;ldquo;command not found&amp;rdquo;, the problem is your &lt;a href="https://linuxize.com/post/how-to-add-directory-to-path-in-linux/"&gt;&lt;code&gt;PATH&lt;/code&gt;&lt;/a&gt;
. A typo in &lt;code&gt;~/.bashrc&lt;/code&gt; or &lt;code&gt;~/.zshrc&lt;/code&gt; can wipe out the standard directories. Check the current value:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;/home/sara/bin:/home/sara/.local/bin&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When &lt;code&gt;/usr/bin&lt;/code&gt; and &lt;code&gt;/usr/local/bin&lt;/code&gt; are missing, the shell cannot find any of the system binaries. Restore a sane &lt;code&gt;PATH&lt;/code&gt; for the current session by calling &lt;code&gt;sudo&lt;/code&gt; with its absolute path:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/usr/bin/sudo apt update&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;That works as a one-off, but the durable fix is to repair the shell config. Open the file that broke the variable:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nano ~/.bashrc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;A safe baseline looks like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/.bashrc&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/bin:&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The key detail is keeping &lt;code&gt;$PATH&lt;/code&gt; itself in any line that extends it. A line like &lt;code&gt;export PATH=$HOME/bin&lt;/code&gt; (without &lt;code&gt;:$PATH&lt;/code&gt;) overwrites everything else and is the most common cause of this failure.&lt;/p&gt;
&lt;p&gt;Source the file and try again:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo whoami&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;root&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A &lt;code&gt;root&lt;/code&gt; response confirms &lt;code&gt;sudo&lt;/code&gt; is back on the path and working.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;sara is not in the sudoers file. This incident will be reported.&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The user exists but is not authorized. Switch to root and either add the user to the admin group (as shown above) or edit &lt;code&gt;/etc/sudoers&lt;/code&gt; with &lt;code&gt;visudo&lt;/code&gt; and add a line such as &lt;code&gt;sara ALL=(ALL:ALL) ALL&lt;/code&gt;. Never edit &lt;code&gt;/etc/sudoers&lt;/code&gt; directly; &lt;code&gt;visudo&lt;/code&gt; validates syntax and prevents lockout.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;No root password and no sudo&lt;/strong&gt;&lt;br&gt;
On Ubuntu, root is disabled by default. Boot into the GRUB recovery menu, drop to a root shell, and run &lt;code&gt;passwd root&lt;/code&gt; to set a password. Then install &lt;code&gt;sudo&lt;/code&gt; and add your user to the group as shown above.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;sudo: /etc/sudo.conf is owned by uid 1000, should be 0&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
File ownership in &lt;code&gt;/etc&lt;/code&gt; was changed by mistake. As root, restore it with &lt;code&gt;chown root:root /etc/sudo.conf /etc/sudoers&lt;/code&gt; and &lt;code&gt;chmod 440 /etc/sudoers&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Why does sudo work in one shell but not another?&lt;/strong&gt;&lt;br&gt;
The two shells likely load different startup files. Compare &lt;code&gt;echo $PATH&lt;/code&gt; in each, and check &lt;code&gt;~/.bashrc&lt;/code&gt;, &lt;code&gt;~/.bash_profile&lt;/code&gt;, &lt;code&gt;~/.profile&lt;/code&gt;, and &lt;code&gt;~/.zshrc&lt;/code&gt; for conflicting &lt;code&gt;PATH&lt;/code&gt; assignments.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does adding a user to the sudo group take effect right away?&lt;/strong&gt;&lt;br&gt;
No. Group membership is read at login. Log out and back in, or start a new login shell with &lt;code&gt;su - sara&lt;/code&gt; to pick up the change.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is doas a real replacement for sudo?&lt;/strong&gt;&lt;br&gt;
For single-user systems and most container images, yes. &lt;code&gt;doas&lt;/code&gt; is smaller and configured through a much shorter file. Multi-user servers with detailed access rules are still better served by &lt;code&gt;sudo&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &amp;ldquo;command not found&amp;rdquo; message points to one of three problems: a missing package, a missing group membership, or a broken &lt;code&gt;PATH&lt;/code&gt;. Walking through them in that order resolves the error on almost every Linux system.&lt;/p&gt;
&lt;p&gt;For follow-up reading, see our guides on &lt;a href="https://linuxize.com/post/how-to-create-a-sudo-user-on-ubuntu/"&gt;creating a sudo user&lt;/a&gt;
and the &lt;a href="https://linuxize.com/post/sudo-command-in-linux/"&gt;sudo command reference&lt;/a&gt;
.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/fix-sudo-command-not-found/featured_hu_3f612fff86459112.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>dpkg Command in Linux: Install and Manage Debian Packages</title><link>https://linuxize.com/post/dpkg-command-in-linux/</link><pubDate>Mon, 01 Jun 2026 10:20:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/dpkg-command-in-linux/</guid><category>linux commands</category><category>ubuntu</category><description>Use dpkg to install, remove, query, and inspect Debian packages on Ubuntu, Debian, and other Debian-based distributions.</description><content:encoded>&lt;p&gt;When you install software on Ubuntu or Debian with &lt;a href="https://linuxize.com/post/how-to-use-apt-command/"&gt;&lt;code&gt;apt&lt;/code&gt;&lt;/a&gt;
, the package manager quietly calls &lt;code&gt;dpkg&lt;/code&gt; in the background to do the actual work. &lt;code&gt;dpkg&lt;/code&gt; is the low-level tool that unpacks and installs &lt;code&gt;.deb&lt;/code&gt; files, maintains the package database, and handles removal and purging. Knowing how to use it directly is useful when you have a local &lt;code&gt;.deb&lt;/code&gt; file that is not in a repository, when you need to query what files a package installed, or when you want to find which package owns a specific file on your system.&lt;/p&gt;
&lt;h2 id="syntax"&gt;Syntax &lt;a class="headline-link" href="#syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dpkg [OPTIONS] COMMAND [ARGUMENTS]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Install, remove, purge, and configure operations require &lt;code&gt;sudo&lt;/code&gt; because they modify system directories and the package database. Query commands such as &lt;code&gt;dpkg -l&lt;/code&gt;, &lt;code&gt;dpkg -L&lt;/code&gt;, &lt;code&gt;dpkg -S&lt;/code&gt;, and &lt;code&gt;dpkg -s&lt;/code&gt; usually run without elevated privileges.&lt;/p&gt;
&lt;h2 id="install-a-package"&gt;Install a Package &lt;a class="headline-link" href="#install-a-package" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To install a local &lt;code&gt;.deb&lt;/code&gt; file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dpkg -i package.deb&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;dpkg&lt;/code&gt; unpacks the archive, runs the maintainer scripts, and registers the package in its database. If the package has unmet dependencies, the install fails with a dependency error. Fix it by running:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install -f&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;apt install -f&lt;/code&gt; (fix broken) resolves and installs any missing dependencies, then completes the pending dpkg installation.&lt;/p&gt;
&lt;p&gt;For most local &lt;code&gt;.deb&lt;/code&gt; installs, &lt;a href="https://linuxize.com/post/how-to-install-deb-packages-on-ubuntu/"&gt;&lt;code&gt;apt install ./package.deb&lt;/code&gt;&lt;/a&gt;
is easier because it can resolve dependencies in the same step. Use &lt;code&gt;dpkg -i&lt;/code&gt; when you specifically need the lower-level package operation.&lt;/p&gt;
&lt;h2 id="remove-a-package"&gt;Remove a Package &lt;a class="headline-link" href="#remove-a-package" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To uninstall a package while keeping its configuration files:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dpkg -r package-name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To uninstall a package and delete its configuration files at the same time (a full purge):&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dpkg -P package-name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Use &lt;code&gt;-P&lt;/code&gt; when you want a clean removal with no leftover config, or when you plan to reinstall with a fresh configuration.&lt;/p&gt;
&lt;h2 id="list-installed-packages"&gt;List Installed Packages &lt;a class="headline-link" href="#list-installed-packages" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To list every installed package with its version and status:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dpkg -l&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output is wide. Each package line starts with three status columns: desired action, current package status, and error state. The normal installed state appears as &lt;code&gt;ii&lt;/code&gt;, followed by the package name, version, architecture, and description:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-=============-============-=================================
ii curl 8.5.0 amd64 command line tool for transferring data
ii nginx 1.26.0 amd64 small, powerful, scalable web/proxy server&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first &lt;code&gt;i&lt;/code&gt; means the package is selected for installation, and the second &lt;code&gt;i&lt;/code&gt; means it is installed and configured. Filter by name to narrow the output:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dpkg -l &lt;span class="s1"&gt;&amp;#39;nginx*&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;ii nginx 1.26.0 amd64 small, powerful, scalable web/proxy server
ii nginx-common 1.26.0 all small, powerful, scalable web/proxy server (common files)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="list-files-installed-by-a-package"&gt;List Files Installed by a Package &lt;a class="headline-link" href="#list-files-installed-by-a-package" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To see every file a package placed on your system:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dpkg -L nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;/.
/etc
/etc/nginx
/etc/nginx/nginx.conf
/etc/nginx/sites-available
/etc/nginx/sites-enabled
/usr/sbin
/usr/sbin/nginx
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is useful when you need to find where a package installs its binary, config files, or documentation.&lt;/p&gt;
&lt;h2 id="find-which-package-owns-a-file"&gt;Find Which Package Owns a File &lt;a class="headline-link" href="#find-which-package-owns-a-file" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To identify which package installed a particular file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dpkg -S /usr/sbin/nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;nginx: /usr/sbin/nginx&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can also search by pattern:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dpkg -S &lt;span class="s1"&gt;&amp;#39;*/bin/curl&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;curl: /usr/bin/curl&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="show-package-details"&gt;Show Package Details &lt;a class="headline-link" href="#show-package-details" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To print the full metadata for an installed package including version, dependencies, and description:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dpkg -s nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Package: nginx
Status: install ok installed
Priority: optional
Section: web
Installed-Size: 47
Maintainer: Ubuntu Developers &amp;lt;ubuntu-devel-discuss@lists.ubuntu.com&amp;gt;
Architecture: amd64
Version: 1.26.0-1ubuntu1
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="inspect-a-deb-file-without-installing"&gt;Inspect a .deb File Without Installing &lt;a class="headline-link" href="#inspect-a-deb-file-without-installing" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To read the metadata of a &lt;code&gt;.deb&lt;/code&gt; file before installing it:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dpkg --info package.deb&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt; new Debian package, version 2.0.
size 1234567 bytes: control archive=2048 bytes.
...
Package: myapp
Version: 2.1.0
Architecture: amd64
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To list the files the package would install without actually installing it:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dpkg --contents package.deb&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="extract-a-package-without-installing"&gt;Extract a Package Without Installing &lt;a class="headline-link" href="#extract-a-package-without-installing" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To unpack the contents of a &lt;code&gt;.deb&lt;/code&gt; file into a directory for inspection:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dpkg -x package.deb /tmp/extracted&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The directory structure mirrors where files would be installed on the real system.&lt;/p&gt;
&lt;h2 id="export-and-restore-package-selections"&gt;Export and Restore Package Selections &lt;a class="headline-link" href="#export-and-restore-package-selections" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To export a list of all installed packages (useful for replicating a system):&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dpkg --get-selections &amp;gt; installed-packages.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To restore those selections on another machine:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dpkg --set-selections &amp;lt; installed-packages.txt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get dselect-upgrade&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="reconfigure-an-installed-package"&gt;Reconfigure an Installed Package &lt;a class="headline-link" href="#reconfigure-an-installed-package" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Some packages run interactive setup at install time. To run that setup again:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dpkg-reconfigure package-name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is commonly used to reconfigure &lt;code&gt;tzdata&lt;/code&gt; for timezone changes, &lt;code&gt;keyboard-configuration&lt;/code&gt;, or &lt;code&gt;locales&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="fix-broken-package-state"&gt;Fix Broken Package State &lt;a class="headline-link" href="#fix-broken-package-state" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If a system update or manual operation leaves packages in a half-installed or unconfigured state, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dpkg --configure -a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This processes any pending package configuration steps. Follow it with &lt;code&gt;sudo apt install -f&lt;/code&gt; if dependency issues remain.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;dpkg reports dependency problems&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;dpkg&lt;/code&gt; installs the package file you give it, but it does not download missing dependencies. Run &lt;code&gt;sudo apt install -f&lt;/code&gt; to install the required packages and finish the pending configuration.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A package operation was interrupted&lt;/strong&gt;&lt;br&gt;
If an update or install stopped before configuration finished, run &lt;code&gt;sudo dpkg --configure -a&lt;/code&gt;. This resumes pending package configuration scripts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;dpkg cannot find a package&lt;/strong&gt;&lt;br&gt;
Use the installed package name, not the &lt;code&gt;.deb&lt;/code&gt; filename. Run &lt;code&gt;dpkg -l 'pattern*'&lt;/code&gt; to find matching installed packages, then use that package name with commands such as &lt;code&gt;dpkg -L&lt;/code&gt;, &lt;code&gt;dpkg -s&lt;/code&gt;, or &lt;code&gt;sudo dpkg -r&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/dpkg/"&gt;dpkg cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dpkg -i pkg.deb&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Install a local .deb file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dpkg -r package&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Remove a package, keep config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dpkg -P package&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Purge a package and its config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dpkg -l&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List all installed packages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dpkg -l 'pattern*'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Filter installed packages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dpkg -L package&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List files installed by a package&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dpkg -S /path/to/file&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Find which package owns a file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dpkg -s package&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show package status and details&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dpkg --info pkg.deb&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inspect a .deb file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dpkg --contents pkg.deb&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List files in a .deb&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dpkg -x pkg.deb /dir&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Extract a .deb without installing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dpkg --get-selections&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Export installed package list&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dpkg-reconfigure package&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Re-run package configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dpkg --configure -a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fix incomplete installations&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;dpkg&lt;/code&gt; is the foundation of package management on Debian-based systems. For everyday installs and updates from repositories, &lt;code&gt;apt&lt;/code&gt; is the better tool because it resolves dependencies automatically. Reach for &lt;code&gt;dpkg&lt;/code&gt; directly when you need to install a &lt;code&gt;.deb&lt;/code&gt; file from disk, audit what a package installed, or diagnose a broken package state.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/dpkg-command-in-linux/featured_hu_869824d772a9010a.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>iptables Command in Linux: Manage Firewall Rules</title><link>https://linuxize.com/post/iptables-command-in-linux/</link><pubDate>Fri, 29 May 2026 09:30:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/iptables-command-in-linux/</guid><category>firewall</category><category>linux commands</category><description>Manage Linux firewall rules with iptables. This guide covers tables and chains, listing rules, allowing and blocking ports and IP addresses, setting default policies, and saving rules across reboots.</description><content:encoded>&lt;p&gt;When a packet arrives at a Linux machine, the kernel decides what to do with it based on a set of firewall rules. Those rules live in the kernel&amp;rsquo;s Netfilter framework, and for more than two decades the standard way to edit them from user space has been the &lt;code&gt;iptables&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;iptables&lt;/code&gt; controls packet filtering, network address translation, and packet mangling. Higher-level front ends such as &lt;a href="https://linuxize.com/post/how-to-setup-a-firewall-with-ufw-on-ubuntu-24-04/"&gt;&lt;code&gt;ufw&lt;/code&gt;&lt;/a&gt;
and &lt;code&gt;firewalld&lt;/code&gt; manage the same Netfilter firewall stack through simpler interfaces, although many modern systems use &lt;code&gt;nftables&lt;/code&gt; underneath. Understanding the underlying command is still valuable, especially when you inherit a server that was set up by someone else. This guide walks through the concepts and the commands you need to read, edit, and persist firewall rules.&lt;/p&gt;
&lt;h2 id="tables-and-chains"&gt;Tables and Chains &lt;a class="headline-link" href="#tables-and-chains" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before you write a rule, you need to know where it goes. &lt;code&gt;iptables&lt;/code&gt; is organized into tables, and each table contains chains.&lt;/p&gt;
&lt;p&gt;The three tables you will use most often are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;filter&lt;/code&gt; - the default table, used for allowing and blocking traffic&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nat&lt;/code&gt; - used for network address translation, such as port forwarding and masquerading&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mangle&lt;/code&gt; - used to alter packet headers, for example to set QoS marks&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each table has a set of built-in chains that correspond to moments in the life of a packet. In the &lt;code&gt;filter&lt;/code&gt; table:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;INPUT&lt;/code&gt; - packets destined for the local machine&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OUTPUT&lt;/code&gt; - packets originating from the local machine&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FORWARD&lt;/code&gt; - packets routed through the machine&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A rule says: for packets that enter this chain and match these criteria, take this action. The action is called a target and is usually &lt;code&gt;ACCEPT&lt;/code&gt;, &lt;code&gt;DROP&lt;/code&gt;, &lt;code&gt;REJECT&lt;/code&gt;, or the name of another chain.&lt;/p&gt;
&lt;h2 id="iptables-syntax"&gt;iptables Syntax &lt;a class="headline-link" href="#iptables-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The general form of the command is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;iptables [-t TABLE] COMMAND CHAIN [MATCH] [-j TARGET]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If &lt;code&gt;-t&lt;/code&gt; is omitted, &lt;code&gt;iptables&lt;/code&gt; uses the &lt;code&gt;filter&lt;/code&gt; table. Common commands include &lt;code&gt;-A&lt;/code&gt; (append a rule), &lt;code&gt;-I&lt;/code&gt; (insert), &lt;code&gt;-D&lt;/code&gt; (delete), &lt;code&gt;-L&lt;/code&gt; (list), &lt;code&gt;-F&lt;/code&gt; (flush), and &lt;code&gt;-P&lt;/code&gt; (set default policy).&lt;/p&gt;
&lt;p&gt;All commands that change the firewall require root privileges. Run them with &lt;code&gt;sudo&lt;/code&gt; or as root.&lt;/p&gt;
&lt;div class="note callout callout-warning"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"&gt;
&lt;path d="M10 20C4.477 20 0 15.523 0 10S4.477 0 10 0s10 4.477 10 10-4.477 10-10 10zm0-2c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm-.5-5h1c.276 0 .5.224.5.5v1c0 .276-.224.5-.5.5h-1c-.276 0-.5-.224-.5-.5v-1c0-.276.224-.5.5-.5zm0-8h1c.276 0 .5.224.5.5V8l-.5 3-1 .5L9 8V5.5c0-.276.224-.5.5-.5z"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;span class="callout-title"&gt;Warning&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;It is easy to lock yourself out of a remote server with a single wrong rule. Before you apply a restrictive ruleset over SSH, either test on a local machine first or use &lt;code&gt;iptables-apply&lt;/code&gt;, which rolls back automatically if you lose access.&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="list-rules"&gt;List Rules &lt;a class="headline-link" href="#list-rules" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To print every rule in the &lt;code&gt;filter&lt;/code&gt; table, use the &lt;code&gt;-L&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -L&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The default output shows service names, resolves IP addresses, and hides packet and byte counters. For real work, add &lt;code&gt;-n&lt;/code&gt; to keep numeric output and &lt;code&gt;-v&lt;/code&gt; to show counters and interface information:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -L -n -v&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
1234 98K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
0 0 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:23
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To list a single chain, append its name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -L INPUT -n -v&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To number the rules so you can reference them by index when deleting, add &lt;code&gt;--line-numbers&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -L INPUT -n -v --line-numbers&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="add-and-remove-rules"&gt;Add and Remove Rules &lt;a class="headline-link" href="#add-and-remove-rules" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;New rules are added to the end of a chain with &lt;code&gt;-A&lt;/code&gt; (append) or at a specific position with &lt;code&gt;-I&lt;/code&gt; (insert). The difference matters because &lt;code&gt;iptables&lt;/code&gt; evaluates rules top to bottom and stops at the first match.&lt;/p&gt;
&lt;p&gt;To allow incoming SSH connections:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -A INPUT -p tcp --dport &lt;span class="m"&gt;22&lt;/span&gt; -j ACCEPT&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To allow HTTP and HTTPS:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -A INPUT -p tcp --dport &lt;span class="m"&gt;80&lt;/span&gt; -j ACCEPT
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -A INPUT -p tcp --dport &lt;span class="m"&gt;443&lt;/span&gt; -j ACCEPT&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To insert a rule as the first one in the chain, use &lt;code&gt;-I CHAIN 1&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -I INPUT &lt;span class="m"&gt;1&lt;/span&gt; -p tcp --dport &lt;span class="m"&gt;22&lt;/span&gt; -j ACCEPT&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is important when you are working over SSH. If a broad &lt;code&gt;DROP&lt;/code&gt; rule already appears earlier in the chain, appending the accept rule after it would not help because the packet would be dropped first.&lt;/p&gt;
&lt;p&gt;To delete a rule, either repeat the exact specification with &lt;code&gt;-D&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -D INPUT -p tcp --dport &lt;span class="m"&gt;23&lt;/span&gt; -j DROP&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Or delete by line number, which is easier when the rule has many options:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -D INPUT &lt;span class="m"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="allow-and-block-specific-ips"&gt;Allow and Block Specific IPs &lt;a class="headline-link" href="#allow-and-block-specific-ips" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To block all traffic from a single IP address:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -A INPUT -s 203.0.113.10 -j DROP&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To block a range using CIDR notation:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -A INPUT -s 203.0.113.0/24 -j DROP&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To allow SSH only from a trusted subnet:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport &lt;span class="m"&gt;22&lt;/span&gt; -j ACCEPT
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -A INPUT -p tcp --dport &lt;span class="m"&gt;22&lt;/span&gt; -j DROP&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The first rule accepts SSH from the local subnet. The second drops SSH from everywhere else. Order matters: if you reversed the two lines, every SSH attempt would be dropped before the accept rule had a chance to match.&lt;/p&gt;
&lt;h2 id="allow-established-connections"&gt;Allow Established Connections &lt;a class="headline-link" href="#allow-established-connections" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Most firewall setups include a rule that accepts traffic belonging to an already established connection. This lets return traffic through without needing a matching rule for each outbound request:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Put this rule near the top of the &lt;code&gt;INPUT&lt;/code&gt; chain so it matches early. Without it, the default &lt;code&gt;DROP&lt;/code&gt; policy breaks outbound connections that expect responses.&lt;/p&gt;
&lt;h2 id="set-a-default-policy"&gt;Set a Default Policy &lt;a class="headline-link" href="#set-a-default-policy" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Each built-in chain has a default policy that applies when no rule matches. The &lt;code&gt;-P&lt;/code&gt; option changes it:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -P INPUT DROP
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -P FORWARD DROP
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -P OUTPUT ACCEPT&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Switching &lt;code&gt;INPUT&lt;/code&gt; to &lt;code&gt;DROP&lt;/code&gt; is the foundation of a deny-by-default firewall: nothing gets in unless an explicit rule allows it. Before you flip the policy, make sure you have already added the rules that allow SSH, established connections, and anything else you need.&lt;/p&gt;
&lt;h2 id="flush-rules"&gt;Flush Rules &lt;a class="headline-link" href="#flush-rules" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To remove every rule from every chain in the current table:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -F&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To flush a specific chain only:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -F INPUT&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Flushing does not reset the default policies. If you have set &lt;code&gt;INPUT&lt;/code&gt; to &lt;code&gt;DROP&lt;/code&gt;, flushing will leave it at &lt;code&gt;DROP&lt;/code&gt; with no rules, which blocks all inbound traffic. Reset the policy to &lt;code&gt;ACCEPT&lt;/code&gt; first if that is not what you want:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -P INPUT ACCEPT
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -F&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="save-and-restore-rules"&gt;Save and Restore Rules &lt;a class="headline-link" href="#save-and-restore-rules" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Rules added with &lt;code&gt;iptables&lt;/code&gt; live in kernel memory only. They disappear on reboot unless you save them.&lt;/p&gt;
&lt;p&gt;On Ubuntu, Debian, and Derivatives, the &lt;code&gt;iptables-persistent&lt;/code&gt; package saves rules to &lt;code&gt;/etc/iptables/rules.v4&lt;/code&gt; and reloads them at boot:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install iptables-persistent&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The installer asks whether to save the current rules. To update the saved copy later:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo netfilter-persistent save&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Fedora, RHEL, and Derivatives, the equivalent service is &lt;code&gt;iptables-services&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install iptables-services
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; --now iptables
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo service iptables save&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Independent of the distribution, you can dump and restore rules manually with &lt;code&gt;iptables-save&lt;/code&gt; and &lt;code&gt;iptables-restore&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables-save -f /etc/iptables/rules.v4
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables-restore /etc/iptables/rules.v4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is also the recommended way to edit a large ruleset: save to a file, edit the file, then restore it atomically.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Rules disappear after a reboot&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;iptables&lt;/code&gt; rules are not persistent by default. Install &lt;code&gt;iptables-persistent&lt;/code&gt; on Debian-based systems or &lt;code&gt;iptables-services&lt;/code&gt; on RHEL-based ones, and save the ruleset.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SSH stops working after setting a DROP policy&lt;/strong&gt;&lt;br&gt;
You switched &lt;code&gt;INPUT&lt;/code&gt; to &lt;code&gt;DROP&lt;/code&gt; without an ACCEPT rule for port 22, or the ACCEPT rule is positioned after a more general DROP rule. Connect through the console, add the rule with &lt;code&gt;-I INPUT 1&lt;/code&gt;, and save.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A rule looks correct but does not match&lt;/strong&gt;&lt;br&gt;
Check the order. &lt;code&gt;iptables&lt;/code&gt; walks the chain top to bottom and stops at the first match, so an earlier accept or drop may be catching the packet first. Use &lt;code&gt;iptables -L INPUT -n -v --line-numbers&lt;/code&gt; to inspect the order.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes are silently ignored&lt;/strong&gt;&lt;br&gt;
You may be editing the wrong table. A rule in &lt;code&gt;filter&lt;/code&gt; does not affect NAT, and vice versa. Pass &lt;code&gt;-t TABLE&lt;/code&gt; explicitly when you are not working in &lt;code&gt;filter&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;iptables: command not found&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
On some modern distributions, only &lt;code&gt;nftables&lt;/code&gt; is installed by default. Install &lt;code&gt;iptables&lt;/code&gt; with your package manager, or use &lt;code&gt;nft&lt;/code&gt; directly.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/iptables/"&gt;iptables cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;List rules (verbose, numeric)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;iptables -L -n -v --line-numbers&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Allow port&lt;/td&gt;
&lt;td&gt;&lt;code&gt;iptables -A INPUT -p tcp --dport PORT -j ACCEPT&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Block IP&lt;/td&gt;
&lt;td&gt;&lt;code&gt;iptables -A INPUT -s IP -j DROP&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Allow established connections&lt;/td&gt;
&lt;td&gt;&lt;code&gt;iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Insert rule at top&lt;/td&gt;
&lt;td&gt;&lt;code&gt;iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete rule by number&lt;/td&gt;
&lt;td&gt;&lt;code&gt;iptables -D INPUT N&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Set default policy&lt;/td&gt;
&lt;td&gt;&lt;code&gt;iptables -P INPUT DROP&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flush all rules&lt;/td&gt;
&lt;td&gt;&lt;code&gt;iptables -F&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Save rules&lt;/td&gt;
&lt;td&gt;&lt;code&gt;iptables-save -f /etc/iptables/rules.v4&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Restore rules&lt;/td&gt;
&lt;td&gt;&lt;code&gt;iptables-restore /etc/iptables/rules.v4&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Is iptables still relevant in 2026?&lt;/strong&gt;&lt;br&gt;
It is still installed and widely used, but it is being replaced by &lt;code&gt;nftables&lt;/code&gt;, which offers a cleaner syntax and better performance. On recent distributions, the &lt;code&gt;iptables&lt;/code&gt; command is often a compatibility front end that writes &lt;code&gt;nftables&lt;/code&gt; rules underneath.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Should I use iptables, ufw, or firewalld?&lt;/strong&gt;&lt;br&gt;
If you are managing rules by hand on Debian or Ubuntu, &lt;a href="https://linuxize.com/post/how-to-setup-a-firewall-with-ufw-on-ubuntu-24-04/"&gt;ufw&lt;/a&gt;
is simpler and covers most cases. On Fedora and RHEL, &lt;code&gt;firewalld&lt;/code&gt; is the default. Reach for raw &lt;code&gt;iptables&lt;/code&gt; when you need fine-grained control that the front ends do not expose, or when you are troubleshooting an existing ruleset.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between DROP and REJECT?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;DROP&lt;/code&gt; silently discards the packet; the sender sees a timeout. &lt;code&gt;REJECT&lt;/code&gt; sends an ICMP error back (or a TCP reset for TCP), so the sender gets immediate feedback. &lt;code&gt;DROP&lt;/code&gt; is often preferred on public interfaces because it does not confirm that the port exists.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I block a country or a list of IPs?&lt;/strong&gt;&lt;br&gt;
For a handful of addresses, add one &lt;code&gt;-s&lt;/code&gt; rule per entry. For larger lists, use the &lt;code&gt;ipset&lt;/code&gt; tool to manage the addresses and reference the set from a single &lt;code&gt;iptables&lt;/code&gt; rule.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does iptables handle IPv6?&lt;/strong&gt;&lt;br&gt;
No. Use &lt;code&gt;ip6tables&lt;/code&gt; for IPv6 rules. It has the same syntax and the same tables and chains, but operates on a separate rule set.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;iptables&lt;/code&gt; is a low-level but reliable way to read and shape the Linux firewall. Once you have a working ruleset, save it with &lt;code&gt;iptables-save&lt;/code&gt; and commit the file so the next person to touch the server has a clear starting point.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/iptables-command-in-linux/featured_hu_c7e35177340aebc3.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>ripgrep Command in Linux: Fast Recursive Search</title><link>https://linuxize.com/post/ripgrep-in-linux/</link><pubDate>Tue, 26 May 2026 09:30:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/ripgrep-in-linux/</guid><category>grep</category><category>linux commands</category><description>The ripgrep command searches directories recursively while respecting ignore files. This guide explains rg syntax, file type filters, context lines, replacement previews, and config defaults.</description><content:encoded>&lt;p&gt;Searching through a large codebase or a directory full of log files with &lt;code&gt;grep&lt;/code&gt; often means adding &lt;code&gt;-r&lt;/code&gt; for recursion, &lt;code&gt;-n&lt;/code&gt; for line numbers, and &lt;code&gt;--include&lt;/code&gt; or &lt;code&gt;--exclude&lt;/code&gt; rules to avoid unrelated files. In a Git repository, you may also need extra excludes for build directories, vendor files, and binary output.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ripgrep&lt;/code&gt; (&lt;code&gt;rg&lt;/code&gt;) handles the common case with better defaults. It searches directories recursively, respects &lt;code&gt;.gitignore&lt;/code&gt;, &lt;code&gt;.ignore&lt;/code&gt;, and &lt;code&gt;.rgignore&lt;/code&gt; rules, skips hidden and binary files during recursive searches, and shows friendly interactive output. It is also much faster than traditional recursive &lt;code&gt;grep&lt;/code&gt; on many large file trees because it uses Rust&amp;rsquo;s regex engine and parallel directory traversal.&lt;/p&gt;
&lt;p&gt;This guide explains how to use the &lt;code&gt;ripgrep&lt;/code&gt; command in Linux, from basic searches to file type filters, context lines, replacement previews, and config defaults.&lt;/p&gt;
&lt;h2 id="installing-ripgrep"&gt;Installing ripgrep &lt;a class="headline-link" href="#installing-ripgrep" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;On Ubuntu, Debian, and Derivatives, install the &lt;code&gt;ripgrep&lt;/code&gt; package with &lt;code&gt;apt&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install ripgrep&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Fedora, RHEL, and Derivatives, use &lt;code&gt;dnf&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install ripgrep&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Arch Linux, install it from the official repositories:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo pacman -S ripgrep&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Verify the installation with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg --version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output shows the installed version:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;ripgrep 15.1.0 (rev af60c2de9d)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Your distribution may ship a different version, but the examples in this guide use common options available in current &lt;code&gt;ripgrep&lt;/code&gt; releases.&lt;/p&gt;
&lt;h2 id="syntax"&gt;Syntax &lt;a class="headline-link" href="#syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The basic syntax for the &lt;code&gt;rg&lt;/code&gt; command is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg [OPTIONS] PATTERN [PATH ...]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;PATTERN&lt;/code&gt; argument is the text or regular expression to search for. If you omit &lt;code&gt;PATH&lt;/code&gt;, &lt;code&gt;rg&lt;/code&gt; searches recursively from the current directory.&lt;/p&gt;
&lt;p&gt;For example, &lt;code&gt;rg &amp;quot;error&amp;quot;&lt;/code&gt; searches the current directory tree, while &lt;code&gt;rg &amp;quot;error&amp;quot; logs/&lt;/code&gt; limits the search to the &lt;code&gt;logs&lt;/code&gt; directory.&lt;/p&gt;
&lt;h2 id="basic-search"&gt;Basic Search &lt;a class="headline-link" href="#basic-search" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Search for a pattern in all files under the current directory:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg &lt;span class="s2"&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Example output:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;logs/app.log:42:error: connection refused
logs/app.log:78:error: timeout after 30s
src/main.py:114:raise ValueError(&amp;#34;error parsing config&amp;#34;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output shows the filename, line number, and matching line. In an interactive terminal, &lt;code&gt;rg&lt;/code&gt; also uses color by default, so you do not need the usual recursive &lt;code&gt;grep&lt;/code&gt; flags for the common code-search workflow.&lt;/p&gt;
&lt;p&gt;To search in a specific file, pass the filename after the pattern:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg &lt;span class="s2"&gt;&amp;#34;error&amp;#34;&lt;/span&gt; logs/app.log&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To search in a specific directory, pass the directory path:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg &lt;span class="s2"&gt;&amp;#34;error&amp;#34;&lt;/span&gt; logs/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="filtering-by-file-type"&gt;Filtering by File Type &lt;a class="headline-link" href="#filtering-by-file-type" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;-t&lt;/code&gt; to restrict the search to a known file type:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg -t py &lt;span class="s2"&gt;&amp;#34;import os&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This searches only Python files. &lt;code&gt;ripgrep&lt;/code&gt; includes built-in definitions for many file types. To see the full list, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg --type-list&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To exclude a file type, use &lt;code&gt;-T&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg -T js &lt;span class="s2"&gt;&amp;#34;TODO&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can also use glob patterns with &lt;code&gt;-g&lt;/code&gt; to match or exclude specific filenames. Quote glob patterns so the shell does not expand them before &lt;code&gt;rg&lt;/code&gt; receives them:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg -g &lt;span class="s1"&gt;&amp;#39;*.log&amp;#39;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Use a leading &lt;code&gt;!&lt;/code&gt; to exclude matching paths:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg -g &lt;span class="s1"&gt;&amp;#39;!*.min.js&amp;#39;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;console.log&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;!&lt;/code&gt; prefix belongs to &lt;code&gt;rg&lt;/code&gt;, so quoting is especially useful in shells where &lt;code&gt;!&lt;/code&gt; can trigger history expansion.&lt;/p&gt;
&lt;h2 id="case-insensitive-search"&gt;Case-Insensitive Search &lt;a class="headline-link" href="#case-insensitive-search" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Add &lt;code&gt;-i&lt;/code&gt; to ignore letter case:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg -i &lt;span class="s2"&gt;&amp;#34;warning&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This matches &lt;code&gt;warning&lt;/code&gt;, &lt;code&gt;Warning&lt;/code&gt;, &lt;code&gt;WARNING&lt;/code&gt;, and other case variants.&lt;/p&gt;
&lt;p&gt;For a more flexible default, use &lt;code&gt;-S&lt;/code&gt; or &lt;code&gt;--smart-case&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg -S &lt;span class="s2"&gt;&amp;#34;warning&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;With smart case, an all-lowercase pattern is case-insensitive, but a pattern with any uppercase letter is case-sensitive. For example, &lt;code&gt;rg -S &amp;quot;warning&amp;quot;&lt;/code&gt; matches &lt;code&gt;Warning&lt;/code&gt;, while &lt;code&gt;rg -S &amp;quot;Warning&amp;quot;&lt;/code&gt; searches for that exact capitalization.&lt;/p&gt;
&lt;h2 id="fixed-string-search"&gt;Fixed String Search &lt;a class="headline-link" href="#fixed-string-search" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;rg&lt;/code&gt; treats the pattern as a regular expression. Use &lt;code&gt;-F&lt;/code&gt; to search for a literal string instead, which is useful when the pattern contains regex characters:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg -F &lt;span class="s2"&gt;&amp;#34;price[0]&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Without &lt;code&gt;-F&lt;/code&gt;, &lt;code&gt;[0]&lt;/code&gt; would be interpreted as a character class. With &lt;code&gt;-F&lt;/code&gt;, &lt;code&gt;rg&lt;/code&gt; searches for the literal text &lt;code&gt;price[0]&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="counting-and-listing-matches"&gt;Counting and Listing Matches &lt;a class="headline-link" href="#counting-and-listing-matches" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To count matching lines per file instead of printing the matching lines, use &lt;code&gt;-c&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg -c &lt;span class="s2"&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Example output:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;logs/app.log:14
logs/nginx/access.log:3&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The count is the number of matching lines, not the total number of matching words or strings.&lt;/p&gt;
&lt;p&gt;To print only filenames that contain at least one match, use &lt;code&gt;-l&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg -l &lt;span class="s2"&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To print only filenames that contain no matches, use &lt;code&gt;--files-without-match&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg --files-without-match &lt;span class="s2"&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is different from combining &lt;code&gt;-v&lt;/code&gt; with &lt;code&gt;-l&lt;/code&gt;. The &lt;code&gt;--files-without-match&lt;/code&gt; option checks whether a file has zero matching lines.&lt;/p&gt;
&lt;h2 id="context-lines"&gt;Context Lines &lt;a class="headline-link" href="#context-lines" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When a matching line alone is not enough to understand the surrounding code, add context with &lt;code&gt;-C&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg -C &lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;panic&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This prints three lines before and three lines after each match.&lt;/p&gt;
&lt;p&gt;Use &lt;code&gt;-A&lt;/code&gt; for lines after the match only:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg -A &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;def connect&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Use &lt;code&gt;-B&lt;/code&gt; for lines before the match only:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg -B &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;def connect&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Context output is useful when you want to inspect the code around a function, error message, or configuration value without opening each file.&lt;/p&gt;
&lt;h2 id="multiple-patterns"&gt;Multiple Patterns &lt;a class="headline-link" href="#multiple-patterns" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;-e&lt;/code&gt; to search for more than one pattern in a single pass:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg -e &lt;span class="s2"&gt;&amp;#34;error&amp;#34;&lt;/span&gt; -e &lt;span class="s2"&gt;&amp;#34;warning&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This matches any line containing either word. It is equivalent to the regex &lt;code&gt;error|warning&lt;/code&gt;, but repeated &lt;code&gt;-e&lt;/code&gt; options are easier to read when patterns become longer.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;-e&lt;/code&gt; option is also useful when a pattern begins with a dash:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg -e &lt;span class="s2"&gt;&amp;#34;--force&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Without &lt;code&gt;-e&lt;/code&gt;, &lt;code&gt;rg&lt;/code&gt; would try to interpret &lt;code&gt;--force&lt;/code&gt; as an option.&lt;/p&gt;
&lt;h2 id="whole-word-match"&gt;Whole-Word Match &lt;a class="headline-link" href="#whole-word-match" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;-w&lt;/code&gt; flag restricts matches to whole words. This is useful when you want to find a variable name without matching it inside a longer name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg -w &lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This matches &lt;code&gt;id&lt;/code&gt;, but not &lt;code&gt;uid&lt;/code&gt; or &lt;code&gt;invalid&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="invert-match"&gt;Invert Match &lt;a class="headline-link" href="#invert-match" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;-v&lt;/code&gt; flag prints lines that do not match the pattern:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg -v &lt;span class="s2"&gt;&amp;#34;^#&amp;#34;&lt;/span&gt; config.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This shows all lines in &lt;code&gt;config.txt&lt;/code&gt; that do not begin with &lt;code&gt;#&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you want filenames that do not contain a pattern at all, use &lt;code&gt;--files-without-match&lt;/code&gt; instead:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg --files-without-match &lt;span class="s2"&gt;&amp;#34;version&amp;#34;&lt;/span&gt; -g &lt;span class="s1"&gt;&amp;#39;*.json&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="searching-hidden-files-and-ignoring-gitignore"&gt;Searching Hidden Files and Ignoring .gitignore &lt;a class="headline-link" href="#searching-hidden-files-and-ignoring-gitignore" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, recursive &lt;code&gt;rg&lt;/code&gt; searches skip hidden files and directories, and respect &lt;code&gt;.gitignore&lt;/code&gt;, &lt;code&gt;.ignore&lt;/code&gt;, and &lt;code&gt;.rgignore&lt;/code&gt; files. This is usually what you want in a source tree.&lt;/p&gt;
&lt;p&gt;To include hidden files and directories, use &lt;code&gt;--hidden&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg --hidden &lt;span class="s2"&gt;&amp;#34;api_key&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To ignore &lt;code&gt;.gitignore&lt;/code&gt;, &lt;code&gt;.ignore&lt;/code&gt;, and &lt;code&gt;.rgignore&lt;/code&gt; rules, use &lt;code&gt;--no-ignore&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg --no-ignore &lt;span class="s2"&gt;&amp;#34;TODO&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;--no-ignore&lt;/code&gt; option does not include hidden files by itself. To search hidden files and ignored files in the same search, combine both options:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg --hidden --no-ignore &lt;span class="s2"&gt;&amp;#34;password&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="note callout callout-warning"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"&gt;
&lt;path d="M10 20C4.477 20 0 15.523 0 10S4.477 0 10 0s10 4.477 10 10-4.477 10-10 10zm0-2c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm-.5-5h1c.276 0 .5.224.5.5v1c0 .276-.224.5-.5.5h-1c-.276 0-.5-.224-.5-.5v-1c0-.276.224-.5.5-.5zm0-8h1c.276 0 .5.224.5.5V8l-.5 3-1 .5L9 8V5.5c0-.276.224-.5.5-.5z"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;span class="callout-title"&gt;Warning&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;Searching with &lt;code&gt;--hidden --no-ignore&lt;/code&gt; can include build artifacts, dependency directories, cache folders, and other large trees. It is much slower and can produce noisy results, so use it only when you have a specific reason to search outside the normal project files.&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="replacing-output"&gt;Replacing Output &lt;a class="headline-link" href="#replacing-output" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;-r&lt;/code&gt; option rewrites matching text in the output to show what a replacement would look like. It does not modify any files:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg &lt;span class="s2"&gt;&amp;#34;foo&amp;#34;&lt;/span&gt; -r &lt;span class="s2"&gt;&amp;#34;bar&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Example output:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;src/config.py:5:bar = get_setting(&amp;#34;bar&amp;#34;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output shows the line as it would look after replacing &lt;code&gt;foo&lt;/code&gt; with &lt;code&gt;bar&lt;/code&gt;. This is useful for previewing a project-wide rename before using &lt;a href="https://linuxize.com/post/how-to-use-sed-to-find-and-replace-string-in-files/"&gt;&lt;code&gt;sed&lt;/code&gt;&lt;/a&gt;
or a text editor&amp;rsquo;s find-and-replace feature.&lt;/p&gt;
&lt;p&gt;For capture groups in replacements, wrap the command in single quotes so the shell does not expand &lt;code&gt;$1&lt;/code&gt;, &lt;code&gt;$name&lt;/code&gt;, or similar replacement references before &lt;code&gt;rg&lt;/code&gt; runs.&lt;/p&gt;
&lt;h2 id="showing-only-the-match"&gt;Showing Only the Match &lt;a class="headline-link" href="#showing-only-the-match" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;rg&lt;/code&gt; prints the full line containing the match. Use &lt;code&gt;-o&lt;/code&gt; to print only the matched text:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rg -o &lt;span class="s1"&gt;&amp;#39;v[0-9]+\.[0-9]+\.[0-9]+&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Example output:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;package.json:4:v1.4.2
package-lock.json:8:v1.4.2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is useful when you want to extract values from files rather than inspect matching lines in context.&lt;/p&gt;
&lt;h2 id="ripgrep-configuration-file"&gt;ripgrep Configuration File &lt;a class="headline-link" href="#ripgrep-configuration-file" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;ripgrep&lt;/code&gt; can read default options from a configuration file, but it does not automatically look in &lt;code&gt;~/.config/ripgrep/&lt;/code&gt; or any other fixed path. You must point &lt;code&gt;RIPGREP_CONFIG_PATH&lt;/code&gt; to the file you want &lt;code&gt;rg&lt;/code&gt; to read.&lt;/p&gt;
&lt;p&gt;For example, create a config file named &lt;code&gt;~/.ripgreprc&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/.ripgreprc&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;--smart-case
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;--hidden
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;--glob=!.git/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Then export the environment variable:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;RIPGREP_CONFIG_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.ripgreprc&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Add that &lt;code&gt;export&lt;/code&gt; line to your shell startup file, such as &lt;code&gt;~/.bashrc&lt;/code&gt; or &lt;code&gt;~/.zshrc&lt;/code&gt;, if you want the setting to apply in new terminal sessions.&lt;/p&gt;
&lt;p&gt;Each config file line is passed to &lt;code&gt;rg&lt;/code&gt; as one command-line argument. For options with values, use either &lt;code&gt;--option=value&lt;/code&gt; on one line or put the option and its value on separate lines.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;rg does not find a file you expected&lt;/strong&gt;&lt;br&gt;
The file may be hidden, ignored by &lt;code&gt;.gitignore&lt;/code&gt;, ignored by &lt;code&gt;.ignore&lt;/code&gt; or &lt;code&gt;.rgignore&lt;/code&gt;, or detected as binary. Start with &lt;code&gt;rg --debug &amp;quot;pattern&amp;quot;&lt;/code&gt; to see why paths were skipped, then add &lt;code&gt;--hidden&lt;/code&gt;, &lt;code&gt;--no-ignore&lt;/code&gt;, or both only when needed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A glob pattern does not work as expected&lt;/strong&gt;&lt;br&gt;
Quote glob patterns, such as &lt;code&gt;rg -g '*.conf' &amp;quot;server&amp;quot;&lt;/code&gt; and &lt;code&gt;rg -g '!*.min.js' &amp;quot;console.log&amp;quot;&lt;/code&gt;. Without quotes, your shell may expand &lt;code&gt;*&lt;/code&gt; before &lt;code&gt;rg&lt;/code&gt; sees the pattern.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A pattern starting with - is treated as an option&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;-e&lt;/code&gt; before the pattern, for example &lt;code&gt;rg -e &amp;quot;--force&amp;quot;&lt;/code&gt;. You can also use &lt;code&gt;--&lt;/code&gt; to stop option parsing, as in &lt;code&gt;rg -- &amp;quot;--force&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="options-reference"&gt;Options Reference &lt;a class="headline-link" href="#options-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-t TYPE&lt;/code&gt; - Search only files of the given type.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-T TYPE&lt;/code&gt; - Exclude files of the given type.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-g GLOB&lt;/code&gt; - Include or exclude files by glob. A &lt;code&gt;!&lt;/code&gt; prefix excludes paths.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-i&lt;/code&gt; - Search case-insensitively.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-F&lt;/code&gt; - Treat the pattern as a fixed string, not a regex.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-c&lt;/code&gt; - Count matching lines per file.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-l&lt;/code&gt; - List only filenames with matches.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--files-without-match&lt;/code&gt; - List only filenames without matches.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-C N&lt;/code&gt; - Show N lines of context around each match.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-A N&lt;/code&gt; - Show N lines after each match.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-B N&lt;/code&gt; - Show N lines before each match.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-e PATTERN&lt;/code&gt; - Add a search pattern. Repeat it to search for multiple patterns.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-w&lt;/code&gt; - Match whole words only.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-v&lt;/code&gt; - Invert the match and print non-matching lines.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-o&lt;/code&gt; - Print only the matched text, not the full line.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-r REPLACEMENT&lt;/code&gt; - Show output with matches replaced. This is a preview only.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-n&lt;/code&gt; - Show line numbers. This is enabled by default in interactive terminal output.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--hidden&lt;/code&gt; - Search hidden files and directories.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--no-ignore&lt;/code&gt; - Do not respect &lt;code&gt;.gitignore&lt;/code&gt;, &lt;code&gt;.ignore&lt;/code&gt;, and &lt;code&gt;.rgignore&lt;/code&gt; rules.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-S&lt;/code&gt;, &lt;code&gt;--smart-case&lt;/code&gt; - Search case-insensitively when the pattern is lowercase, and case-sensitively when it contains uppercase.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--stats&lt;/code&gt; - Print a summary of the search at the end.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-M N&lt;/code&gt; - Omit lines longer than N bytes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/ripgrep/"&gt;ripgrep cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Search recursively from the current directory&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg &amp;quot;pattern&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search in a specific file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg &amp;quot;pattern&amp;quot; file.txt&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search in a specific directory&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg &amp;quot;pattern&amp;quot; logs/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search only Python files&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg -t py &amp;quot;pattern&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exclude JavaScript files&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg -T js &amp;quot;pattern&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search by glob&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg -g '*.log' &amp;quot;pattern&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exclude by glob&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg -g '!*.min.js' &amp;quot;pattern&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search case-insensitively&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg -i &amp;quot;pattern&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use smart case&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg -S &amp;quot;pattern&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search for a fixed string&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg -F &amp;quot;price[0]&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Count matching lines per file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg -c &amp;quot;pattern&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List matching filenames&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg -l &amp;quot;pattern&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List filenames without matches&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg --files-without-match &amp;quot;pattern&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Show three lines of context&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg -C 3 &amp;quot;pattern&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search multiple patterns&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg -e &amp;quot;foo&amp;quot; -e &amp;quot;bar&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Match a whole word&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg -w &amp;quot;id&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Invert line matches&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg -v &amp;quot;pattern&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Include hidden files&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg --hidden &amp;quot;pattern&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ignore ignore files&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg --no-ignore &amp;quot;pattern&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Include hidden and ignored files&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg --hidden --no-ignore &amp;quot;pattern&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Preview replacement output&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg &amp;quot;old&amp;quot; -r &amp;quot;new&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Print only matched text&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rg -o &amp;quot;pattern&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;ripgrep&lt;/code&gt; covers the same ground as &lt;a href="https://linuxize.com/post/how-to-use-grep-command-to-search-files-in-linux/"&gt;&lt;code&gt;grep&lt;/code&gt;&lt;/a&gt;
, but its recursive search, file filtering, and ignore-file support make it a better default for many code and log searches. For path-based file finding, pair it with &lt;a href="https://linuxize.com/post/how-to-find-files-in-linux-using-the-command-line/"&gt;&lt;code&gt;find&lt;/code&gt;&lt;/a&gt;
, or use &lt;code&gt;rg -l&lt;/code&gt; when you need a list of files that contain a specific pattern.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/ripgrep-in-linux/featured_hu_95063e1cb004cfc3.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>whois Command in Linux: Query Domain Registration Info</title><link>https://linuxize.com/post/whois-command-in-linux/</link><pubDate>Mon, 25 May 2026 11:30:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/whois-command-in-linux/</guid><category>dns</category><category>linux commands</category><description>The whois command looks up domain registration, registrar, name server, expiry, IP allocation, and AS number details from Linux.</description><content:encoded>&lt;p&gt;When you need to know who owns a domain, when it expires, which registrar handles it, or which organization holds a particular IP block, the &lt;code&gt;whois&lt;/code&gt; command is the fastest route. It queries the registry databases that record this information and returns a plain-text response you can scan in a terminal. The output format varies by registry, but the questions you can answer are consistent: registrar, name servers, registration and expiry dates, and contact info (where privacy rules allow).&lt;/p&gt;
&lt;p&gt;This guide explains how to use &lt;code&gt;whois&lt;/code&gt; in Linux to look up domains, IP addresses, and AS numbers, how to target a specific server, and how to parse the output for the fields you actually care about.&lt;/p&gt;
&lt;h2 id="whois-syntax"&gt;whois Syntax &lt;a class="headline-link" href="#whois-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The general form is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;whois [OPTIONS] OBJECT&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;OBJECT&lt;/code&gt; is the domain, IP address, or AS number you want information about. With no options, &lt;code&gt;whois&lt;/code&gt; picks the right registry automatically based on the type of query.&lt;/p&gt;
&lt;h2 id="install-whois"&gt;Install whois &lt;a class="headline-link" href="#install-whois" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;whois&lt;/code&gt; is not always installed by default. On Ubuntu, Debian, and Derivatives:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install whois&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Fedora, RHEL, and Derivatives:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install whois&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Confirm it is in place:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;whois --version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Version 5.6.6.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The Debian-family &lt;code&gt;whois&lt;/code&gt; is an actively maintained client with built-in routing logic that knows which registry to ask for each TLD.&lt;/p&gt;
&lt;h2 id="look-up-a-domain"&gt;Look Up a Domain &lt;a class="headline-link" href="#look-up-a-domain" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The most common use is checking a domain:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;whois example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt; Domain Name: EXAMPLE.COM
Registry Domain ID: 2336799_DOMAIN_COM-VRSN
Registrar WHOIS Server: whois.iana.org
Registrar URL: http://res-dom.iana.org
Updated Date: 2026-01-16T18:26:50Z
Creation Date: 1995-08-14T04:00:00Z
Registry Expiry Date: 2026-08-13T04:00:00Z
Registrar: RESERVED-Internet Assigned Numbers Authority
Registrar IANA ID: 376
Name Server: ELLIOTT.NS.CLOUDFLARE.COM
Name Server: HERA.NS.CLOUDFLARE.COM
DNSSEC: signedDelegation
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The fields that matter most for everyday questions are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Registrar&lt;/code&gt;, the company managing the registration.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Creation Date&lt;/code&gt; and &lt;code&gt;Registry Expiry Date&lt;/code&gt;, which tell you how old the domain is and when it needs renewing.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Name Server&lt;/code&gt;, which lists the DNS servers authoritative for the domain.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DNSSEC&lt;/code&gt;, which shows whether the domain is cryptographically signed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For ccTLDs (&lt;code&gt;.de&lt;/code&gt;, &lt;code&gt;.uk&lt;/code&gt;, &lt;code&gt;.jp&lt;/code&gt;), the format differs because each country runs its own registry. The information is similar; the field names and order change.&lt;/p&gt;
&lt;h2 id="look-up-an-ip-address"&gt;Look Up an IP Address &lt;a class="headline-link" href="#look-up-an-ip-address" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;whois&lt;/code&gt; on an IP returns the network allocation, not the domain:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;whois 93.184.216.34&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;inetnum: 93.184.216.0 - 93.184.216.255
netname: EDGECAST-NETBLK-03
descr: NETBLK-03-EU-93-184-216-0-24
country: EU
admin-c: DS7892-RIPE
tech-c: DS7892-RIPE
status: ASSIGNED PA
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This kind of query is the right tool for &amp;ldquo;who owns this IP that has been hitting my server&amp;rdquo; investigations. The output names the network block, maintainer, and abuse contact details when the registry publishes them.&lt;/p&gt;
&lt;h2 id="look-up-an-as-number"&gt;Look Up an AS Number &lt;a class="headline-link" href="#look-up-an-as-number" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Pass an autonomous system number with the &lt;code&gt;AS&lt;/code&gt; prefix:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;whois AS15169&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;ASNumber: 15169
ASName: GOOGLE
ASHandle: AS15169
RegDate: 2000-03-30
Updated: 2012-02-24
Ref: https://rdap.arin.net/registry/autnum/15169&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;AS lookups are useful when you trace a route with &lt;code&gt;mtr&lt;/code&gt; or &lt;code&gt;traceroute&lt;/code&gt; and want to know which network each hop belongs to.&lt;/p&gt;
&lt;h2 id="pick-a-specific-whois-server"&gt;Pick a Specific WHOIS Server &lt;a class="headline-link" href="#pick-a-specific-whois-server" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The default routing finds the right server for most TLDs, but you can force a query against a specific server with &lt;code&gt;-h&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;whois -h whois.arin.net 8.8.8.8&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The flag is the right tool for two situations: when the default routing picks the wrong upstream (rare but happens for some legacy TLDs), and when you want to compare answers between regional registries (ARIN, RIPE, APNIC, AFRINIC, LACNIC).&lt;/p&gt;
&lt;h2 id="limit-the-recursion"&gt;Limit the Recursion &lt;a class="headline-link" href="#limit-the-recursion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Most modern &lt;code&gt;whois&lt;/code&gt; clients follow a referral chain: query IANA, follow the pointer to the TLD registry, follow the pointer to the registrar, and return the most specific answer. To stop registry-to-registrar recursion, pass &lt;code&gt;--no-recursion&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;whois --no-recursion example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The flag is most useful when you specifically want the registry data and not the registrar&amp;rsquo;s slightly different format.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;-H&lt;/code&gt; option has a different purpose. It hides legal disclaimers from the output, which can make short lookups easier to read:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;whois -H example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="filter-the-output"&gt;Filter the Output &lt;a class="headline-link" href="#filter-the-output" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Real &lt;code&gt;whois&lt;/code&gt; responses are dozens of lines long with legal disclaimers and template text. To extract one field, pipe through &lt;code&gt;grep&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;whois example.com &lt;span class="p"&gt;|&lt;/span&gt; grep -E &lt;span class="s2"&gt;&amp;#34;Registrar:|Expiry Date:&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt; Registry Expiry Date: 2026-08-13T04:00:00Z
Registrar: RESERVED-Internet Assigned Numbers Authority&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For a name-server list:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;whois example.com &lt;span class="p"&gt;|&lt;/span&gt; awk &lt;span class="s1"&gt;&amp;#39;/Name Server:/ {print $NF}&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;ELLIOTT.NS.CLOUDFLARE.COM
HERA.NS.CLOUDFLARE.COM&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These short patterns work for monitoring scripts that watch for domain expirations or DNSSEC status changes.&lt;/p&gt;
&lt;h2 id="check-domain-availability"&gt;Check Domain Availability &lt;a class="headline-link" href="#check-domain-availability" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If the domain is not registered, the response says so explicitly. The exact wording depends on the registry:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;whois never-existed-domain-xyzzy.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;No match for domain &amp;#34;NEVER-EXISTED-DOMAIN-XYZZY.COM&amp;#34;.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Some registries (notably &lt;code&gt;.io&lt;/code&gt;, &lt;code&gt;.co&lt;/code&gt;, and several ccTLDs) return an empty or near-empty response for unregistered domains. Two heuristics that work in scripts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For &lt;code&gt;.com&lt;/code&gt;/&lt;code&gt;.net&lt;/code&gt;/&lt;code&gt;.org&lt;/code&gt;, grep for &lt;code&gt;No match for&lt;/code&gt; or &lt;code&gt;Domain Name:&lt;/code&gt; in the output.&lt;/li&gt;
&lt;li&gt;For ccTLDs, grep for &lt;code&gt;Domain not found&lt;/code&gt; or check whether the registration fields exist.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="rate-limits-and-etiquette"&gt;Rate Limits and Etiquette &lt;a class="headline-link" href="#rate-limits-and-etiquette" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Registries rate-limit &lt;code&gt;whois&lt;/code&gt; queries. Hammering them with a script is the fastest way to get blocked. If you query many domains, add a &lt;code&gt;sleep&lt;/code&gt; between calls and cache the result locally. For bulk lookups, use the registry&amp;rsquo;s RDAP service directly or pay for a commercial WHOIS API.&lt;/p&gt;
&lt;p&gt;A simple polite pattern:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;read&lt;/span&gt; -r domain&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; whois &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$domain&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; sleep &lt;span class="m"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt; &amp;lt; domains.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Two seconds between queries is a sane starting point; raise it if you see throttling responses.&lt;/p&gt;
&lt;h2 id="privacy-and-redacted-output"&gt;Privacy and Redacted Output &lt;a class="headline-link" href="#privacy-and-redacted-output" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Since GDPR took effect, most TLDs redact personal contact information for individual registrants. The response usually contains placeholders like &lt;code&gt;REDACTED FOR PRIVACY&lt;/code&gt; or &lt;code&gt;Data Protected, Not Disclosed&lt;/code&gt;. For organizations and legal entities, the contact information often stays visible.&lt;/p&gt;
&lt;p&gt;This is not a defect in &lt;code&gt;whois&lt;/code&gt;; the underlying registry data is simply less detailed than it used to be. For account-takeover prevention and abuse handling, focus on the registrar field and the abuse contact email, which remain published.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Look up a domain&lt;/td&gt;
&lt;td&gt;&lt;code&gt;whois example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Look up an IP address&lt;/td&gt;
&lt;td&gt;&lt;code&gt;whois 93.184.216.34&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Look up an AS number&lt;/td&gt;
&lt;td&gt;&lt;code&gt;whois AS15169&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Query a specific server&lt;/td&gt;
&lt;td&gt;&lt;code&gt;whois -h whois.arin.net 8.8.8.8&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stop registry-to-registrar recursion&lt;/td&gt;
&lt;td&gt;&lt;code&gt;whois --no-recursion example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hide legal disclaimers&lt;/td&gt;
&lt;td&gt;&lt;code&gt;whois -H example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extract registrar and expiry fields&lt;/td&gt;
&lt;td&gt;&lt;code&gt;whois example.com | grep -E &amp;ldquo;Registrar:|Expiry Date:&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List name servers&lt;/td&gt;
&lt;td&gt;&lt;code&gt;whois example.com | awk &amp;lsquo;/Name Server:/ {print $NF}&amp;rsquo;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;whois: command not found&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
Install the package: &lt;code&gt;sudo apt install whois&lt;/code&gt; on Ubuntu, Debian, and Derivatives, or &lt;code&gt;sudo dnf install whois&lt;/code&gt; on Fedora, RHEL, and Derivatives. The package is small and adds no significant dependencies.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Output says &amp;ldquo;fgets: Connection reset by peer&amp;rdquo;&lt;/strong&gt;&lt;br&gt;
The registry rate-limited or blocked your IP. Wait a few minutes and retry, slow your script down, or query through a different network.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Response is in a different language or alphabet&lt;/strong&gt;&lt;br&gt;
Some ccTLD registries return data in the local language. Look for the English section (usually further down), or pipe through &lt;code&gt;iconv&lt;/code&gt; if the encoding makes the response unreadable in your terminal.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between WHOIS and RDAP?&lt;/strong&gt;&lt;br&gt;
RDAP (Registration Data Access Protocol) is the modern replacement for WHOIS. It returns structured JSON instead of free-text and supports authentication and access controls. Most registries now serve both, and RDAP is usually the better choice for scripts that need predictable fields.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why does the data for the same domain look different between two &lt;code&gt;whois&lt;/code&gt; runs?&lt;/strong&gt;&lt;br&gt;
Different clients and servers can follow the referral chain differently. One response may come from the registry, while another may include data from the registrar&amp;rsquo;s WHOIS server. Use &lt;code&gt;--no-recursion&lt;/code&gt; when you want to stop at the registry answer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I run my own WHOIS server?&lt;/strong&gt;&lt;br&gt;
Yes, but only registrars and registries have authoritative data. Self-hosted WHOIS servers are useful for internal directories (IP allocation in a large network), not for public domain lookups.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;whois&lt;/code&gt; is the answer to &amp;ldquo;who owns this&amp;rdquo;, whether the &amp;ldquo;this&amp;rdquo; is a domain, an IP, or an AS number. The output is plain text, the flags are short, and a handful of &lt;code&gt;grep&lt;/code&gt;/&lt;code&gt;awk&lt;/code&gt; patterns turn it into a script-friendly data source. For bulk work, slow the queries down and respect the rate limits the registries publish.&lt;/p&gt;
&lt;p&gt;For related reading, see our guides on &lt;a href="https://linuxize.com/post/how-to-use-dig-command-to-query-dns-in-linux/"&gt;the dig command&lt;/a&gt;
and &lt;a href="https://linuxize.com/post/nslookup-command-in-linux/"&gt;the nslookup command&lt;/a&gt;
.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/whois-command-in-linux/featured_hu_e63e30c7626fc6a5.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>Bash Arithmetic: Integer and Floating-Point Math</title><link>https://linuxize.com/post/bash-arithmetic/</link><pubDate>Fri, 22 May 2026 14:41:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/bash-arithmetic/</guid><category>bash</category><category>linux commands</category><description>How to do arithmetic in Bash with the (( )) operator, $(( )) expansion, the let builtin, and bc or awk for floating-point math the shell cannot do natively.</description><content:encoded>&lt;p&gt;Bash treats everything as a string by default, which catches many people out the first time they write &lt;code&gt;total=$count+1&lt;/code&gt; and end up with the literal text &lt;code&gt;5+1&lt;/code&gt; instead of &lt;code&gt;6&lt;/code&gt;. The shell has dedicated arithmetic forms that evaluate numeric expressions properly, but they only handle integers; for floating-point math you reach for &lt;code&gt;bc&lt;/code&gt; or &lt;code&gt;awk&lt;/code&gt;. Once you know which form to use where, the math is short and predictable.&lt;/p&gt;
&lt;p&gt;This guide explains how Bash arithmetic works, the differences between &lt;code&gt;(( ))&lt;/code&gt;, &lt;code&gt;$(( ))&lt;/code&gt;, and &lt;code&gt;let&lt;/code&gt;, and how to combine them with external tools when you need decimals.&lt;/p&gt;
&lt;h2 id="why-plain-assignment-does-not-add"&gt;Why Plain Assignment Does Not Add &lt;a class="headline-link" href="#why-plain-assignment-does-not-add" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A first attempt at incrementing a variable usually looks like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;total&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$count&lt;/span&gt;+1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$total&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;5+1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The shell sees &lt;code&gt;$count&lt;/code&gt; as the string &lt;code&gt;5&lt;/code&gt;, joins it with &lt;code&gt;+1&lt;/code&gt;, and assigns the result. To force numeric evaluation, use one of the arithmetic forms below.&lt;/p&gt;
&lt;h2 id="the---compound-command"&gt;The (( )) Compound Command &lt;a class="headline-link" href="#the---compound-command" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Wrap an expression in double parentheses to evaluate it as integer math:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;((&lt;/span&gt; &lt;span class="nv"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; count + &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$count&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;6&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Inside &lt;code&gt;(( ))&lt;/code&gt;, variable names work without &lt;code&gt;$&lt;/code&gt;, the C-style operators are available (&lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;/&lt;/code&gt;, &lt;code&gt;%&lt;/code&gt;, &lt;code&gt;**&lt;/code&gt;, &lt;code&gt;++&lt;/code&gt;, &lt;code&gt;--&lt;/code&gt;, &lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;amp;&lt;/code&gt;, &lt;code&gt;|&lt;/code&gt;, &lt;code&gt;^&lt;/code&gt;, &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;, &lt;code&gt;||&lt;/code&gt;), and the exit status of the whole expression is non-zero when the result is &lt;code&gt;0&lt;/code&gt;, which means you can use arithmetic in &lt;code&gt;if&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt; count &amp;gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;count is above 5&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;count is above 5&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The shortcut increment and decrement operators read cleanly in loops:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0&lt;span class="p"&gt;;&lt;/span&gt; i &amp;lt; 3&lt;span class="p"&gt;;&lt;/span&gt; i++ &lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;i=&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;i=0
i=1
i=2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;(( ))&lt;/code&gt; is the right form when you assign back to a variable or use the result for control flow. It does not print anything to standard output.&lt;/p&gt;
&lt;h2 id="the---expansion"&gt;The $(( )) Expansion &lt;a class="headline-link" href="#the---expansion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When you want the value of an expression rather than the side effect, use the &lt;code&gt;$(( ))&lt;/code&gt; arithmetic expansion. The result is substituted into the surrounding command like any other expansion:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Next: &lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt; count &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="k"&gt;))&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Next: 6&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;$(( ))&lt;/code&gt; is the right form for inline math inside &lt;code&gt;echo&lt;/code&gt;, assignments to other variables, command arguments, and &lt;code&gt;printf&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;files&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;42&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Average: &lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt; files &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt; &lt;span class="k"&gt;))&lt;/span&gt;&lt;span class="s2"&gt; per day&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Average: 6 per day&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Notice that the division truncates: &lt;code&gt;42 / 7&lt;/code&gt; happens to be exact, but &lt;code&gt;43 / 7&lt;/code&gt; would yield &lt;code&gt;6&lt;/code&gt;, not &lt;code&gt;6.14&lt;/code&gt;. Bash arithmetic is integer-only; the decimal part is silently discarded.&lt;/p&gt;
&lt;h2 id="the-let-builtin"&gt;The let Builtin &lt;a class="headline-link" href="#the-let-builtin" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;let&lt;/code&gt; is the older builtin for arithmetic. It evaluates each argument as an expression:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;let&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;count = 5 + 1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$count&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;6&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;let&lt;/code&gt; is mostly historical at this point. &lt;code&gt;(( ))&lt;/code&gt; does the same work without the quoting trap (&lt;code&gt;let count=*&lt;/code&gt; would expand the &lt;code&gt;*&lt;/code&gt; as a glob unless quoted) and reads more cleanly. New scripts should prefer &lt;code&gt;(( ))&lt;/code&gt;; &lt;code&gt;let&lt;/code&gt; is worth recognizing in code you inherit.&lt;/p&gt;
&lt;h2 id="operators-you-will-actually-use"&gt;Operators You Will Actually Use &lt;a class="headline-link" href="#operators-you-will-actually-use" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bash supports a wide list of arithmetic operators. These are the ones that come up in everyday scripts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;/&lt;/code&gt;, &lt;code&gt;%&lt;/code&gt; - Standard arithmetic and remainder.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;**&lt;/code&gt; - Exponentiation.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;++&lt;/code&gt;, &lt;code&gt;--&lt;/code&gt; - Increment and decrement, prefix or postfix.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;+=&lt;/code&gt;, &lt;code&gt;-=&lt;/code&gt;, &lt;code&gt;*=&lt;/code&gt;, &lt;code&gt;/=&lt;/code&gt;, &lt;code&gt;%=&lt;/code&gt; - Compound assignment.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;==&lt;/code&gt;, &lt;code&gt;!=&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;lt;=&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;gt;=&lt;/code&gt; - Numeric comparison (inside &lt;code&gt;(( ))&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;, &lt;code&gt;||&lt;/code&gt;, &lt;code&gt;!&lt;/code&gt; - Logical AND, OR, NOT.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;amp;&lt;/code&gt;, &lt;code&gt;|&lt;/code&gt;, &lt;code&gt;^&lt;/code&gt;, &lt;code&gt;~&lt;/code&gt; - Bitwise shifts and operations.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A small example that uses several:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1024&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt; size &amp;gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; size % &lt;span class="nv"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Power of two? &lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;size &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;size &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;&lt;span class="s2"&gt; == 0 ? 1 : 0 ))&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Power of two? 1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The ternary operator (&lt;code&gt;? :&lt;/code&gt;) works inside arithmetic contexts, which keeps short branches readable without nesting &lt;code&gt;if&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="number-bases"&gt;Number Bases &lt;a class="headline-link" href="#number-bases" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bash arithmetic supports several integer bases. Prefix a number to declare its base:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0xNN&lt;/code&gt; for hexadecimal.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0NN&lt;/code&gt; for octal.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BASE#NNN&lt;/code&gt; for any base from 2 to 64.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Examples:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;xff &lt;span class="k"&gt;))&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt; &lt;span class="m"&gt;0755&lt;/span&gt; &lt;span class="k"&gt;))&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt; &lt;span class="m"&gt;2#1010&lt;/span&gt; &lt;span class="k"&gt;))&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;255
493
10&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Watch out for leading zeros: &lt;code&gt;08&lt;/code&gt; is interpreted as octal and rejected because &lt;code&gt;8&lt;/code&gt; is not a valid octal digit. If user input may include leading zeros (HTTP status codes parsed from a string, timestamps), strip them before arithmetic with &lt;code&gt;${var#0}&lt;/code&gt; or use the explicit &lt;code&gt;10#&lt;/code&gt; base prefix:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;08&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt; &lt;span class="m"&gt;10#&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt; &lt;span class="k"&gt;))&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;8&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="floating-point-math-with-bc"&gt;Floating-Point Math with bc &lt;a class="headline-link" href="#floating-point-math-with-bc" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bash itself cannot do decimal math, but it is happy to call out to a tool that can. &lt;code&gt;bc&lt;/code&gt; is the arbitrary-precision calculator that ships with most distributions:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;scale=2; 43 / 7&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; bc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;6.14&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;scale=2&lt;/code&gt; directive sets two decimal places of precision. Without it, &lt;code&gt;bc&lt;/code&gt; truncates the division the same way Bash does. Use a higher scale for currency or scientific work:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;scale=10; 4*a(1)&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; bc -l&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;3.1415926532&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;-l&lt;/code&gt; flag loads the math library, which gives you &lt;code&gt;s&lt;/code&gt; (sine), &lt;code&gt;c&lt;/code&gt; (cosine), &lt;code&gt;a&lt;/code&gt; (arctangent), &lt;code&gt;l&lt;/code&gt; (natural log), &lt;code&gt;e&lt;/code&gt; (exponential), and &lt;code&gt;sqrt&lt;/code&gt;. The expression above computes pi from &lt;code&gt;4 * arctan(1)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To capture the result into a variable:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;pi&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;scale=4; 4*a(1)&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; bc -l&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;pi = &lt;/span&gt;&lt;span class="nv"&gt;$pi&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;pi = 3.1415&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;bc&lt;/code&gt; is the right tool when you need genuine decimals and do not want a heavyweight dependency. For one-off interactive calculations, run &lt;code&gt;bc -l&lt;/code&gt; and type expressions at its prompt.&lt;/p&gt;
&lt;h2 id="floating-point-math-with-awk"&gt;Floating-Point Math with awk &lt;a class="headline-link" href="#floating-point-math-with-awk" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;awk&lt;/code&gt; is the other obvious choice and is often faster because it does not start a separate calculator process. Use &lt;code&gt;awk&lt;/code&gt; for inline expressions inside scripts:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;rate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;awk &lt;span class="s1"&gt;&amp;#39;BEGIN { printf &amp;#34;%.2f\n&amp;#34;, 43 / 7 }&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;rate = &lt;/span&gt;&lt;span class="nv"&gt;$rate&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;rate = 6.14&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;printf&lt;/code&gt; inside &lt;code&gt;awk&lt;/code&gt; works the same way as the C function, with &lt;code&gt;%.2f&lt;/code&gt; controlling the number of decimal places. For a percentage:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;pct&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;awk -v &lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;23&lt;/span&gt; -v &lt;span class="nv"&gt;b&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;89&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;BEGIN { printf &amp;#34;%.1f%%\n&amp;#34;, (a / b) * 100 }&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;pct = &lt;/span&gt;&lt;span class="nv"&gt;$pct&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;pct = 25.8%&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Pass values into &lt;code&gt;awk&lt;/code&gt; with &lt;code&gt;-v name=value&lt;/code&gt; rather than building the expression by string concatenation; the &lt;code&gt;-v&lt;/code&gt; form avoids quoting headaches and shell-injection issues when the inputs come from user data.&lt;/p&gt;
&lt;h2 id="increment-counters-in-a-loop"&gt;Increment Counters in a Loop &lt;a class="headline-link" href="#increment-counters-in-a-loop" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Counter loops are the bread and butter of arithmetic in scripts, and they lean on the &lt;a href="https://linuxize.com/post/bash-increment-decrement-variable/"&gt;increment and decrement operators&lt;/a&gt;
. Two equivalent forms work; pick the one that reads best:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;read&lt;/span&gt; -r line&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;((&lt;/span&gt; count++ &lt;span class="o"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt; &amp;lt; input.txt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Lines: &lt;/span&gt;&lt;span class="nv"&gt;$count&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;read&lt;/span&gt; -r line&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt; count &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="k"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt; &amp;lt; input.txt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Lines: &lt;/span&gt;&lt;span class="nv"&gt;$count&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;(( count++ ))&lt;/code&gt; form is shorter and is what most authors prefer. Both produce the same result and run at the same speed.&lt;/p&gt;
&lt;p&gt;If the script uses &lt;code&gt;set -e&lt;/code&gt;, avoid &lt;code&gt;(( count++ ))&lt;/code&gt; when &lt;code&gt;count&lt;/code&gt; may start at zero. The arithmetic command returns a failure status when the expression evaluates to &lt;code&gt;0&lt;/code&gt;, so the first increment can stop the script. Use pre-increment or assignment instead:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;((&lt;/span&gt; ++count &lt;span class="o"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;((&lt;/span&gt; &lt;span class="nv"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;syntax error in expression&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
A variable that should hold a number contains non-numeric characters (often a leading or trailing space from &lt;code&gt;read&lt;/code&gt;, or a stray letter). Inside &lt;code&gt;(( ))&lt;/code&gt; and &lt;code&gt;$(( ))&lt;/code&gt;, Bash reports a syntax error on the offending token. Trim the input with &lt;code&gt;${var//[[:space:]]/}&lt;/code&gt; or validate it before the arithmetic line.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;division by 0&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
A divisor evaluated to zero, often because the variable was empty and Bash treated it as &lt;code&gt;0&lt;/code&gt;. Quote the expansion in your check (&lt;code&gt;if [ -n &amp;quot;$divisor&amp;quot; ]&lt;/code&gt;) before the divide, and either skip the operation or substitute a default with &lt;code&gt;${divisor:-1}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Result is &lt;code&gt;0&lt;/code&gt; when it should be a fraction&lt;/strong&gt;&lt;br&gt;
Bash arithmetic is integer-only. Switch to &lt;code&gt;bc&lt;/code&gt; with an explicit &lt;code&gt;scale=&lt;/code&gt; or to &lt;code&gt;awk&lt;/code&gt; with &lt;code&gt;%.Nf&lt;/code&gt; formatting for decimal output.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;When should I use &lt;code&gt;(( ))&lt;/code&gt; versus &lt;code&gt;$(( ))&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;(( ))&lt;/code&gt; for assignments and control flow (&lt;code&gt;if&lt;/code&gt;, &lt;code&gt;while&lt;/code&gt;, &lt;code&gt;for&lt;/code&gt;). Use &lt;code&gt;$(( ))&lt;/code&gt; when you want the value substituted into a surrounding command. They share the same expression syntax.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I do floating-point math without an external tool?&lt;/strong&gt;&lt;br&gt;
Not in Bash. &lt;code&gt;ksh93&lt;/code&gt; and &lt;code&gt;zsh&lt;/code&gt; support floating-point in their arithmetic contexts; Bash does not. For Bash, route decimals through &lt;code&gt;bc&lt;/code&gt; or &lt;code&gt;awk&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is there a performance difference between &lt;code&gt;bc&lt;/code&gt; and &lt;code&gt;awk&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;awk&lt;/code&gt; is usually faster because it runs entirely inside a single process and does not communicate over a pipe. For one-off calculations the difference is negligible; in a tight loop, prefer &lt;code&gt;awk&lt;/code&gt; or precompute the values with a single &lt;code&gt;awk&lt;/code&gt; call instead of running &lt;code&gt;bc&lt;/code&gt; per iteration.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Reach for &lt;code&gt;(( ))&lt;/code&gt; and &lt;code&gt;$(( ))&lt;/code&gt; whenever a script needs counters, conditions, or quick integer math, and switch to &lt;code&gt;bc&lt;/code&gt; or &lt;code&gt;awk&lt;/code&gt; the moment decimals enter the picture. Pair that habit with &lt;a href="https://linuxize.com/post/bash-strict-mode/"&gt;Bash strict mode&lt;/a&gt;
and the patterns in our &lt;a href="https://linuxize.com/post/bash-best-practices/"&gt;Bash best practices&lt;/a&gt;
guide so numeric code keeps working even when the inputs do not.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/bash-arithmetic/featured_hu_37a9db326c6daf78.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>How to Install Podman on Ubuntu: Rootless Container Alternative to Docker</title><link>https://linuxize.com/post/how-to-install-podman-on-ubuntu/</link><pubDate>Tue, 19 May 2026 09:40:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-install-podman-on-ubuntu/</guid><category>podman</category><category>ubuntu</category><category>linux commands</category><description>Step-by-step instructions for installing Podman on Ubuntu, running rootless containers, building images with Buildah, and switching from Docker.</description><content:encoded>&lt;p&gt;Podman is a daemonless container engine that runs OCI containers without a long-lived root process. Each container is started as a regular user-owned process, which removes the privileged daemon that Docker relies on and makes containers safer to run on shared servers. The command-line surface mirrors Docker almost exactly, so most Dockerfiles, image references, and &lt;code&gt;docker run&lt;/code&gt; patterns work with little to no change.&lt;/p&gt;
&lt;p&gt;This guide explains how to install Podman on Ubuntu, configure rootless mode, run your first container, and use Podman as a drop-in replacement for the Docker CLI.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/podman/"&gt;Podman cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Install Podman&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo apt install podman&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Run a container&lt;/td&gt;
&lt;td&gt;&lt;code&gt;podman run -d --name web -p 8080:80 nginx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List containers&lt;/td&gt;
&lt;td&gt;&lt;code&gt;podman ps -a&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build an image&lt;/td&gt;
&lt;td&gt;&lt;code&gt;podman build -t myimage .&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List images&lt;/td&gt;
&lt;td&gt;&lt;code&gt;podman images&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pull an image&lt;/td&gt;
&lt;td&gt;&lt;code&gt;podman pull alpine:latest&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stop and remove&lt;/td&gt;
&lt;td&gt;&lt;code&gt;podman rm -f web&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inspect rootless setup&lt;/td&gt;
&lt;td&gt;&lt;code&gt;podman info&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="install-podman"&gt;Install Podman &lt;a class="headline-link" href="#install-podman" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Podman has been part of the Ubuntu universe repository since 20.10, so on every supported release you can install it through &lt;code&gt;apt&lt;/code&gt; without adding a third-party PPA.&lt;/p&gt;
&lt;p&gt;Update the package index, then install:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install podman&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Confirm the version:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;podman --version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;podman version 5.7.0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ubuntu 26.04 ships Podman 5.7 from the universe repository. Ubuntu 24.04 ships the 4.9 series, while Ubuntu 22.04 ships the 3.4 series, so the exact version depends on the Ubuntu release you are using.&lt;/p&gt;
&lt;h2 id="verify-the-rootless-setup"&gt;Verify the Rootless Setup &lt;a class="headline-link" href="#verify-the-rootless-setup" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Podman supports both root and rootless modes, and the rootless mode is the one most users want. Run &lt;code&gt;podman info&lt;/code&gt; as your regular user and look for &lt;code&gt;rootless: true&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;podman info &lt;span class="p"&gt;|&lt;/span&gt; head -20&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;host:
arch: amd64
cgroupManager: systemd
...
security:
rootless: true&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Two pieces have to be in place for rootless containers to work: subordinate UID/GID mappings, and a user namespace. Ubuntu sets both up automatically on first run, but you can confirm with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat /etc/subuid /etc/subgid&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;sara:100000:65536
sara:100000:65536&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Each user gets a range of 65,536 subordinate UIDs and GIDs that Podman uses to map container processes to non-overlapping host IDs. If the file is missing your user, add an entry with &lt;code&gt;sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 sara&lt;/code&gt; and run &lt;code&gt;podman system migrate&lt;/code&gt; to apply the change.&lt;/p&gt;
&lt;h2 id="run-your-first-container"&gt;Run Your First Container &lt;a class="headline-link" href="#run-your-first-container" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Pull and run an Nginx container in detached mode, exposing port &lt;code&gt;8080&lt;/code&gt; on the host:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;podman run -d --name web -p 8080:80 nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Resolved &amp;#34;nginx&amp;#34; as an alias (/etc/containers/registries.conf.d/shortnames.conf)
Trying to pull docker.io/library/nginx:latest...
Getting image source signatures
Copying blob sha256:...
Writing manifest to image destination
Storing signatures
2b9bd4e1f3...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Check that the container is running:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;podman ps&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2b9bd4e1f3a8 docker.io/library/nginx:latest nginx -g daemon o... 10 seconds ago Up 10 seconds 0.0.0.0:8080-&amp;gt;80/tcp web&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Hit the published port from the host:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -I http://localhost:8080&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;HTTP/1.1 200 OK
Server: nginx/1.27.4&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The response confirms that the user-mode network stack forwarded the request into the container correctly. Stop and remove the container with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;podman rm -f web&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="configure-registries"&gt;Configure Registries &lt;a class="headline-link" href="#configure-registries" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default Podman searches a configured list of registries when you run &lt;code&gt;podman pull nginx&lt;/code&gt; (without a registry prefix). The list lives in &lt;code&gt;/etc/containers/registries.conf&lt;/code&gt;. To prefer Docker Hub, edit the file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nano /etc/containers/registries.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Set the unqualified-search registries:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="toml"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/containers/registries.conf&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-orange-100 text-orange-700 dark:bg-orange-900 dark:text-orange-300"&gt;toml&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;unqualified-search-registries&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;docker.io&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;quay.io&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Save and exit. From now on &lt;code&gt;podman pull alpine&lt;/code&gt; resolves to &lt;code&gt;docker.io/library/alpine:latest&lt;/code&gt;, which matches Docker&amp;rsquo;s default behavior. Save yourself confusion by always pulling with the full reference (&lt;code&gt;podman pull docker.io/library/alpine&lt;/code&gt;) in scripts and CI pipelines.&lt;/p&gt;
&lt;h2 id="use-podman-as-a-docker-replacement"&gt;Use Podman as a Docker Replacement &lt;a class="headline-link" href="#use-podman-as-a-docker-replacement" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you already have shell history, Makefiles, or scripts that call &lt;code&gt;docker&lt;/code&gt;, install the alias package and keep them working:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install podman-docker&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The package adds a &lt;code&gt;/usr/bin/docker&lt;/code&gt; symlink that points to &lt;code&gt;podman&lt;/code&gt;, plus a stub that suppresses the daemon-not-running warning. Test it:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run --rm hello-world&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Hello from Docker!&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Behind the scenes, &lt;code&gt;docker run&lt;/code&gt; invoked &lt;code&gt;podman run&lt;/code&gt;. Most everyday commands (&lt;code&gt;build&lt;/code&gt;, &lt;code&gt;pull&lt;/code&gt;, &lt;code&gt;push&lt;/code&gt;, &lt;code&gt;images&lt;/code&gt;, &lt;code&gt;ps&lt;/code&gt;, &lt;code&gt;logs&lt;/code&gt;, &lt;code&gt;exec&lt;/code&gt;) work identically. The differences show up around Docker Compose and the daemon socket; Podman 4 ships its own socket that Docker Compose can target by setting &lt;code&gt;DOCKER_HOST&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="build-an-image-with-a-dockerfile"&gt;Build an Image with a Dockerfile &lt;a class="headline-link" href="#build-an-image-with-a-dockerfile" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Podman builds OCI images from a standard Dockerfile, no changes required. Create a small Flask app to demonstrate:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir hello-podman &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; hello-podman
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nano app.py&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="py"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;app.py&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-300"&gt;py&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Hello from Podman!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;0.0.0.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Write the Dockerfile:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="dockerfile"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Dockerfile&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-sky-100 text-sky-700 dark:bg-sky-900 dark:text-sky-300"&gt;dockerfile&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dockerfile" data-lang="dockerfile"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;python:3.12-slim&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/app&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; pip install --no-cache-dir flask&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; app.py .&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;5000&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CMD&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;python&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;app.py&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Build the image:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;podman build -t hello-podman .&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;STEP 1/6: FROM python:3.12-slim
STEP 2/6: WORKDIR /app
...
Successfully tagged localhost/hello-podman:latest&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Run a container from the new image:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;podman run -d --name hello -p 5000:5000 hello-podman
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl http://localhost:5000&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Hello from Podman!&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The image and container both live in the user&amp;rsquo;s storage (&lt;code&gt;~/.local/share/containers&lt;/code&gt;), so no &lt;code&gt;sudo&lt;/code&gt; is involved at any step.&lt;/p&gt;
&lt;h2 id="run-pods-of-containers"&gt;Run Pods of Containers &lt;a class="headline-link" href="#run-pods-of-containers" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The name &amp;ldquo;Podman&amp;rdquo; comes from its support for Kubernetes-style pods: groups of containers that share a network namespace. Create an empty pod, then add containers to it:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;podman pod create --name webapp -p 8080:80
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;podman run -d --pod webapp --name redis redis:7
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;podman run -d --pod webapp --name nginx nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Inside the pod, &lt;code&gt;nginx&lt;/code&gt; can reach Redis at &lt;code&gt;localhost:6379&lt;/code&gt; because they share the network namespace. List pods with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;podman pod ps&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;POD ID NAME STATUS CREATED INFRA ID # OF CONTAINERS
8f4d7b8c0e1f webapp Running 20 seconds ago c2a8f9b1d3e4 3&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The count of three includes an &lt;code&gt;infra&lt;/code&gt; container that holds the shared namespaces.&lt;/p&gt;
&lt;h2 id="run-podman-as-a-systemd-service"&gt;Run Podman as a systemd Service &lt;a class="headline-link" href="#run-podman-as-a-systemd-service" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To start a container at boot in rootless mode, use a Quadlet container unit. Quadlet is Podman&amp;rsquo;s current systemd integration method and keeps the container definition in a small, readable file.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir -p ~/.config/containers/systemd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nano ~/.config/containers/systemd/web.container&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Add the container definition:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/.config/containers/systemd/web.container&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Rootless Nginx container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Container]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;docker.io/library/nginx:latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ContainerName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;web&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;PublishPort&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;8080:80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;always&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Install]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;default.target&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Reload the user systemd manager, then start the generated service:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl --user daemon-reload
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl --user start web.service&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Enable lingering so the user services keep running after logout:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo loginctl enable-linger sara&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;[Install]&lt;/code&gt; section tells the Podman systemd generator to attach the service to the user&amp;rsquo;s default target. The container now starts without root or a system-wide daemon.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Error: short-name &amp;quot;nginx&amp;quot; did not resolve to an alias&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The &lt;code&gt;unqualified-search-registries&lt;/code&gt; list is empty. Edit &lt;code&gt;/etc/containers/registries.conf&lt;/code&gt; and add at least &lt;code&gt;docker.io&lt;/code&gt;, or pull with the full reference (&lt;code&gt;podman pull docker.io/library/nginx&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;ERRO[0000] cannot find UID/GID for user&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The current user has no entry in &lt;code&gt;/etc/subuid&lt;/code&gt; or &lt;code&gt;/etc/subgid&lt;/code&gt;. Run &lt;code&gt;sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER&lt;/code&gt;, then &lt;code&gt;podman system migrate&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ports under 1024 refuse to bind in rootless mode&lt;/strong&gt;&lt;br&gt;
The kernel restricts low ports for non-root users. Either publish to a high port (&lt;code&gt;-p 8080:80&lt;/code&gt;), or allow your user to bind low ports with &lt;code&gt;sudo sysctl net.ipv4.ip_unprivileged_port_start=80&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Is Podman a drop-in Docker replacement?&lt;/strong&gt;&lt;br&gt;
For everyday &lt;code&gt;run&lt;/code&gt;, &lt;code&gt;build&lt;/code&gt;, &lt;code&gt;pull&lt;/code&gt;, &lt;code&gt;push&lt;/code&gt;, and &lt;code&gt;exec&lt;/code&gt; workflows, yes. Compose and the long-lived socket need extra setup. Most CI jobs only need the CLI and switch over without changes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does Podman work with Docker Compose?&lt;/strong&gt;&lt;br&gt;
Yes. Start the Podman socket with &lt;code&gt;systemctl --user enable --now podman.socket&lt;/code&gt;, export &lt;code&gt;DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock&lt;/code&gt;, and run &lt;code&gt;docker compose up&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Are Podman images compatible with Docker?&lt;/strong&gt;&lt;br&gt;
Yes. Both produce OCI-compliant images, so an image built with &lt;code&gt;podman build&lt;/code&gt; runs unchanged under Docker, and vice versa.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Podman gives you the Docker workflow without the daemon and without root, which is often what you want on a multi-user server or a developer workstation. Install it from &lt;code&gt;apt&lt;/code&gt;, alias &lt;code&gt;docker&lt;/code&gt; if you have existing scripts, and the rest of the CLI feels familiar.&lt;/p&gt;
&lt;p&gt;For follow-up reading, see our guides on &lt;a href="https://linuxize.com/post/how-to-install-docker-on-ubuntu-26-04/"&gt;installing Docker on Ubuntu 26.04&lt;/a&gt;
and &lt;a href="https://linuxize.com/post/how-to-build-docker-images-with-dockerfile/"&gt;building Docker images with a Dockerfile&lt;/a&gt;
.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-install-podman-on-ubuntu/featured_hu_dc1b76c2fbf72420.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>nmcli Command in Linux: NetworkManager CLI Reference</title><link>https://linuxize.com/post/nmcli-command-in-linux/</link><pubDate>Sun, 17 May 2026 09:15:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/nmcli-command-in-linux/</guid><category>networking</category><category>linux commands</category><description>The nmcli command manages NetworkManager from the terminal. This guide covers device status, Wi-Fi connections, static IP configuration, DNS settings, and scripting-friendly output.</description><content:encoded>&lt;p&gt;When a Linux system needs a network change from a terminal, &lt;code&gt;nmcli&lt;/code&gt; is usually the cleanest way to make it. It controls NetworkManager, the service that handles wired, wireless, VPN, and other connection profiles on many Linux desktops and servers.&lt;/p&gt;
&lt;p&gt;This guide explains how to inspect device status, list and edit connections, join Wi-Fi networks, assign a static IP address, and get script-friendly output with &lt;code&gt;nmcli&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="before-you-begin"&gt;Before You Begin &lt;a class="headline-link" href="#before-you-begin" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before changing network settings, confirm that NetworkManager is installed and running:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl status NetworkManager&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On distributions that use a different network stack, install NetworkManager from the package manager and enable the service before continuing. Most Ubuntu, Fedora, and Arch desktops have it preinstalled.&lt;/p&gt;
&lt;p&gt;If you are connected over &lt;a href="https://linuxize.com/post/ssh-command-in-linux/"&gt;SSH&lt;/a&gt;
, be careful with commands that disconnect an interface, change an address, or bring a profile down. A wrong gateway, IP address, or device name can drop the remote session.&lt;/p&gt;
&lt;h2 id="nmcli-syntax"&gt;nmcli Syntax &lt;a class="headline-link" href="#nmcli-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The general &lt;code&gt;nmcli&lt;/code&gt; syntax is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli [OPTIONS] OBJECT { COMMAND | help }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;OBJECT&lt;/code&gt; is the part of NetworkManager you want to inspect or change. The most common objects are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;general&lt;/code&gt; - show overall NetworkManager status and hostname settings&lt;/li&gt;
&lt;li&gt;&lt;code&gt;networking&lt;/code&gt; - enable, disable, or check networking&lt;/li&gt;
&lt;li&gt;&lt;code&gt;radio&lt;/code&gt; - control Wi-Fi and WWAN radio switches&lt;/li&gt;
&lt;li&gt;&lt;code&gt;device&lt;/code&gt; - show and manage network interfaces&lt;/li&gt;
&lt;li&gt;&lt;code&gt;connection&lt;/code&gt; - show and manage saved connection profiles&lt;/li&gt;
&lt;li&gt;&lt;code&gt;monitor&lt;/code&gt; - watch NetworkManager events in real time&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can abbreviate most objects, for example &lt;code&gt;nmcli con show&lt;/code&gt; instead of &lt;code&gt;nmcli connection show&lt;/code&gt;, but the full form is clearer in scripts and documentation.&lt;/p&gt;
&lt;h2 id="show-general-status"&gt;Show General Status &lt;a class="headline-link" href="#show-general-status" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;general&lt;/code&gt; subcommand reports the overall NetworkManager state, the hostname, and whether networking is enabled:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli general status&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;STATE CONNECTIVITY WIFI-HW WIFI WWAN-HW WWAN
connected full enabled enabled enabled enabled&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Read or change the system hostname through the same subcommand:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli general hostname
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli general hostname server01&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The second form writes the new hostname to &lt;code&gt;/etc/hostname&lt;/code&gt; and updates the kernel value without a reboot. For more hostname options, see the guide on &lt;a href="https://linuxize.com/post/how-to-change-hostname-in-linux/"&gt;changing the hostname in Linux&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="manage-devices"&gt;Manage Devices &lt;a class="headline-link" href="#manage-devices" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A device in NetworkManager is a physical or virtual interface, for example &lt;code&gt;eth0&lt;/code&gt;, &lt;code&gt;wlan0&lt;/code&gt;, or &lt;code&gt;wg0&lt;/code&gt;. List every known device with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli device status&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;DEVICE TYPE STATE CONNECTION
eth0 ethernet connected Wired connection 1
wlan0 wifi connected home-wifi
lo loopback unmanaged --&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Show detailed properties of a single device, including the MAC address, driver, and current IP configuration:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli device show eth0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Bring an interface up or down without changing the underlying connection profile:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli device connect eth0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli device disconnect eth0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;disconnect&lt;/code&gt; stops the connection but keeps the profile available for the next &lt;code&gt;connect&lt;/code&gt; call. Do not disconnect the device that carries your current SSH session unless you have another access path.&lt;/p&gt;
&lt;h2 id="manage-connection-profiles"&gt;Manage Connection Profiles &lt;a class="headline-link" href="#manage-connection-profiles" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;NetworkManager stores each network as a connection profile under &lt;code&gt;/etc/NetworkManager/system-connections/&lt;/code&gt;. List every profile:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli connection show&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;NAME UUID TYPE DEVICE
Wired connection 1 3f4e... ethernet eth0
home-wifi 7a92... wifi wlan0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Activate a saved profile by name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli connection up &lt;span class="s2"&gt;&amp;#34;home-wifi&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Deactivate it without deleting the profile:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli connection down &lt;span class="s2"&gt;&amp;#34;home-wifi&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Delete a profile when it is no longer needed:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli connection delete &lt;span class="s2"&gt;&amp;#34;home-wifi&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Deleting a profile removes the saved NetworkManager configuration. If you only want to stop using it for the moment, bring it down instead.&lt;/p&gt;
&lt;h2 id="connect-to-a-wi-fi-network"&gt;Connect to a Wi-Fi Network &lt;a class="headline-link" href="#connect-to-a-wi-fi-network" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Scan for available networks. The radio must be on for the scan to return results:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli device wifi list&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Join an open or WPA2 network in one call. NetworkManager creates a new profile and stores the password in the system keyring:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli device wifi connect &lt;span class="s2"&gt;&amp;#34;home-wifi&amp;#34;&lt;/span&gt; password &lt;span class="s2"&gt;&amp;#34;secret-passphrase&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Avoid putting real Wi-Fi passwords in shell history, shared scripts, or configuration repositories. For interactive use, run &lt;code&gt;sudo nmcli --ask device wifi connect &amp;quot;home-wifi&amp;quot;&lt;/code&gt; so &lt;code&gt;nmcli&lt;/code&gt; prompts for the password instead.&lt;/p&gt;
&lt;p&gt;For hidden networks, add the &lt;code&gt;hidden yes&lt;/code&gt; flag so NetworkManager probes the SSID directly:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli device wifi connect &lt;span class="s2"&gt;&amp;#34;office-hidden&amp;#34;&lt;/span&gt; password &lt;span class="s2"&gt;&amp;#34;secret-passphrase&amp;#34;&lt;/span&gt; hidden yes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Turn the radio on or off without removing saved profiles:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli radio wifi off
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli radio wifi on&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="configure-a-static-ip-address"&gt;Configure a Static IP Address &lt;a class="headline-link" href="#configure-a-static-ip-address" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Static addressing is one of the most common scripted changes on a server. The example below sets a static IPv4 address, gateway, and DNS servers on the existing &lt;code&gt;Wired connection 1&lt;/code&gt; profile:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli connection modify &lt;span class="s2"&gt;&amp;#34;Wired connection 1&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ipv4.method manual &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ipv4.addresses 192.168.1.50/24 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ipv4.gateway 192.168.1.1 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ipv4.dns &lt;span class="s2"&gt;&amp;#34;1.1.1.1 9.9.9.9&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Apply the change by reactivating the profile:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli connection up &lt;span class="s2"&gt;&amp;#34;Wired connection 1&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you are changing a remote machine, confirm the address, prefix, gateway, and DNS values before running &lt;code&gt;connection up&lt;/code&gt;. A wrong value can make the host unreachable. On Ubuntu systems that use Netplan instead, see the guide on &lt;a href="https://linuxize.com/post/how-to-configure-static-ip-address-on-ubuntu-20-04/"&gt;configuring a static IP address on Ubuntu&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;Switch back to DHCP at any point with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli connection modify &lt;span class="s2"&gt;&amp;#34;Wired connection 1&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ipv4.method auto &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ipv4.addresses &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ipv4.gateway &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ipv4.dns &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli connection up &lt;span class="s2"&gt;&amp;#34;Wired connection 1&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The empty values clear the manual entries that would otherwise stay on the profile.&lt;/p&gt;
&lt;h2 id="add-a-new-wired-connection"&gt;Add a New Wired Connection &lt;a class="headline-link" href="#add-a-new-wired-connection" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When the default profile is missing or has been deleted, create a fresh ethernet profile:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli connection add &lt;span class="nb"&gt;type&lt;/span&gt; ethernet ifname eth0 con-name &lt;span class="s2"&gt;&amp;#34;wired-static&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ipv4.method manual &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ipv4.addresses 192.168.1.50/24 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ipv4.gateway 192.168.1.1 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ipv4.dns 1.1.1.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli connection up &lt;span class="s2"&gt;&amp;#34;wired-static&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This pattern works well in provisioning scripts when you first check whether the profile exists, or when you intentionally replace a known profile. If you only need to change an existing profile, use &lt;code&gt;connection modify&lt;/code&gt; instead of deleting and recreating it.&lt;/p&gt;
&lt;h2 id="set-dns-servers"&gt;Set DNS Servers &lt;a class="headline-link" href="#set-dns-servers" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can change DNS servers without changing the IP address method. For example, to set Cloudflare and Quad9 DNS on a wired profile:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli connection modify &lt;span class="s2"&gt;&amp;#34;Wired connection 1&amp;#34;&lt;/span&gt; ipv4.dns &lt;span class="s2"&gt;&amp;#34;1.1.1.1 9.9.9.9&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli connection up &lt;span class="s2"&gt;&amp;#34;Wired connection 1&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To append another DNS server instead of replacing the whole list, prefix the property with &lt;code&gt;+&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli connection modify &lt;span class="s2"&gt;&amp;#34;Wired connection 1&amp;#34;&lt;/span&gt; +ipv4.dns 8.8.8.8&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;After changing DNS, verify name resolution with a lookup tool such as &lt;a href="https://linuxize.com/post/how-to-use-dig-command-to-query-dns-in-linux/"&gt;&lt;code&gt;dig&lt;/code&gt;&lt;/a&gt;
or &lt;a href="https://linuxize.com/post/nslookup-command-in-linux/"&gt;&lt;code&gt;nslookup&lt;/code&gt;&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="common-examples"&gt;Common Examples &lt;a class="headline-link" href="#common-examples" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Show only the active connections in a parseable format. The &lt;code&gt;-t&lt;/code&gt; flag enables terse output and &lt;code&gt;-f&lt;/code&gt; selects fields:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli -t -f NAME,DEVICE connection show --active&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Watch interface events in real time, useful when a connection drops during a remote session:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli monitor&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Reload all profile files from disk after editing them by hand:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli connection reload&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For low-level interface and route inspection outside NetworkManager, pair &lt;code&gt;nmcli&lt;/code&gt; with the &lt;a href="https://linuxize.com/post/linux-ip-command/"&gt;&lt;code&gt;ip&lt;/code&gt; command&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/nmcli/"&gt;nmcli cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Show overall status&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nmcli general status&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Show syntax help&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nmcli OBJECT help&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List devices&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nmcli device status&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List connection profiles&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nmcli connection show&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Activate a profile&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo nmcli connection up &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deactivate a profile&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo nmcli connection down &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scan Wi-Fi networks&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nmcli device wifi list&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Join a Wi-Fi network&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo nmcli device wifi connect &amp;lt;ssid&amp;gt; password &amp;lt;pwd&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prompt for Wi-Fi password&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo nmcli --ask device wifi connect &amp;lt;ssid&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Set static IPv4&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo nmcli connection modify &amp;lt;name&amp;gt; ipv4.method manual ipv4.addresses &amp;lt;ip/cidr&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Set DNS servers&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo nmcli connection modify &amp;lt;name&amp;gt; ipv4.dns &amp;quot;&amp;lt;a&amp;gt; &amp;lt;b&amp;gt;&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Switch back to DHCP&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo nmcli connection modify &amp;lt;name&amp;gt; ipv4.method auto ipv4.addresses &amp;quot;&amp;quot; ipv4.gateway &amp;quot;&amp;quot; ipv4.dns &amp;quot;&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reload profile files&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo nmcli connection reload&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Watch events&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nmcli monitor&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Error: NetworkManager is not running&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
Start the service with &lt;code&gt;sudo systemctl start NetworkManager&lt;/code&gt; and enable it at boot with &lt;code&gt;sudo systemctl enable NetworkManager&lt;/code&gt;. On a fresh server install, the package may not be present yet.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wi-Fi list is empty after &lt;code&gt;nmcli device wifi list&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The radio is most likely off. Run &lt;code&gt;sudo nmcli radio wifi on&lt;/code&gt;, and check that no rfkill switch is blocking the device with &lt;code&gt;rfkill list&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A new static IP does not take effect&lt;/strong&gt;&lt;br&gt;
NetworkManager applies the change only after the connection is reactivated. Run &lt;code&gt;sudo nmcli connection up &amp;lt;name&amp;gt;&lt;/code&gt; after &lt;code&gt;connection modify&lt;/code&gt;. If a stale DHCP lease is still in place, run &lt;code&gt;sudo nmcli connection down &amp;lt;name&amp;gt;&lt;/code&gt; first.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Not authorized to control networking&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The operation requires administrator privileges or a PolicyKit rule that allows the current user. Run the command with &lt;code&gt;sudo&lt;/code&gt;, or ask the system administrator to grant the needed NetworkManager permissions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A profile keeps reverting to DHCP after reboot&lt;/strong&gt;&lt;br&gt;
A second profile or a cloud-init configuration may be overwriting it. Check &lt;code&gt;/etc/NetworkManager/system-connections/&lt;/code&gt; and &lt;code&gt;/etc/netplan/&lt;/code&gt; for conflicting files.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;nmcli&lt;/code&gt; gives you a scriptable way to inspect NetworkManager state, activate profiles, join Wi-Fi networks, and make persistent IP and DNS changes. For deeper network troubleshooting, use it alongside &lt;code&gt;ip&lt;/code&gt;, &lt;code&gt;ss&lt;/code&gt;, &lt;code&gt;dig&lt;/code&gt;, and the system logs so you can see both the saved profile and the live kernel state.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/nmcli-command-in-linux/featured_hu_4548a0e35d8fbbde.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>timedatectl Command in Linux: Manage Time, Date, and Time Zone</title><link>https://linuxize.com/post/timedatectl-command-in-linux/</link><pubDate>Sat, 16 May 2026 09:20:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/timedatectl-command-in-linux/</guid><category>linux commands</category><description>Use timedatectl to check system time, change the time zone, control NTP synchronization, set the clock manually, and inspect RTC settings on Linux.</description><content:encoded>&lt;p&gt;Wrong system time can break TLS checks, make cron jobs run at the wrong hour, and leave logs with misleading timestamps. On systemd-based Linux systems, &lt;code&gt;timedatectl&lt;/code&gt; is the standard tool for checking and changing time settings.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;timedatectl&lt;/code&gt; is part of systemd and is available on most systemd-based distributions. It handles time zones, NTP synchronization, RTC settings, and manual time adjustments from the command line. This guide explains how to use it with practical examples.&lt;/p&gt;
&lt;h2 id="syntax"&gt;Syntax &lt;a class="headline-link" href="#syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;timedatectl [OPTIONS] COMMAND&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When called without any arguments, &lt;code&gt;timedatectl&lt;/code&gt; shows the current status, which is the same as running &lt;code&gt;timedatectl status&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="check-current-time-and-date"&gt;Check Current Time and Date &lt;a class="headline-link" href="#check-current-time-and-date" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Run &lt;code&gt;timedatectl&lt;/code&gt; with no arguments to see the full time status:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;timedatectl&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt; Local time: Tue 2026-04-14 12:00:00 CEST
Universal time: Tue 2026-04-14 10:00:00 UTC
RTC time: Tue 2026-04-14 10:00:00
Time zone: Europe/Berlin (CEST, +0200)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output shows the local time in your configured time zone, the same moment in UTC, and the hardware clock (RTC) time. &lt;code&gt;System clock synchronized: yes&lt;/code&gt; means NTP has synced the clock recently. &lt;code&gt;NTP service: active&lt;/code&gt; means &lt;code&gt;systemd-timesyncd&lt;/code&gt; (or another NTP daemon) is running and managing synchronization.&lt;/p&gt;
&lt;p&gt;If &lt;code&gt;RTC in local TZ&lt;/code&gt; shows &lt;code&gt;yes&lt;/code&gt;, the hardware clock is set to local time rather than UTC. Most Linux systems keep the hardware clock in UTC, which avoids daylight saving time complications when rebooting.&lt;/p&gt;
&lt;h2 id="set-the-time-zone"&gt;Set the Time Zone &lt;a class="headline-link" href="#set-the-time-zone" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To set the system time zone, use &lt;code&gt;set-timezone&lt;/code&gt; followed by a time zone identifier:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo timedatectl set-timezone America/New_York&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;After running this, &lt;code&gt;timedatectl&lt;/code&gt; shows the new time zone immediately. The change persists across reboots.&lt;/p&gt;
&lt;p&gt;If you do not know the exact time zone identifier, use &lt;code&gt;list-timezones&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;timedatectl list-timezones&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The list is long, so pipe it through &lt;code&gt;grep&lt;/code&gt; to filter by region:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;timedatectl list-timezones &lt;span class="p"&gt;|&lt;/span&gt; grep America&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;America/Adak
America/Anchorage
America/Anguilla
America/Antigua
America/Araguaina
America/Argentina/Buenos_Aires
...
America/New_York
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Time zone identifiers follow the &lt;code&gt;Region/City&lt;/code&gt; format, such as &lt;code&gt;Europe/Paris&lt;/code&gt;, &lt;code&gt;Asia/Tokyo&lt;/code&gt;, or &lt;code&gt;Australia/Sydney&lt;/code&gt;. For a step-by-step walkthrough, see the guide on &lt;a href="https://linuxize.com/post/how-to-set-or-change-timezone-in-linux/"&gt;how to set or change the time zone in Linux&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="enable-and-disable-ntp-synchronization"&gt;Enable and Disable NTP Synchronization &lt;a class="headline-link" href="#enable-and-disable-ntp-synchronization" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;NTP (Network Time Protocol) keeps the system clock accurate by periodically syncing it against internet time servers. &lt;code&gt;timedatectl&lt;/code&gt; can enable or disable NTP management:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo timedatectl set-ntp true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo timedatectl set-ntp false&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;After enabling NTP, run &lt;code&gt;timedatectl&lt;/code&gt; to confirm &lt;code&gt;NTP service: active&lt;/code&gt; appears in the output.&lt;/p&gt;
&lt;p&gt;Turn off NTP before setting the time manually. If NTP is active, &lt;code&gt;timedatectl&lt;/code&gt; rejects direct clock changes.&lt;/p&gt;
&lt;h2 id="set-the-time-and-date-manually"&gt;Set the Time and Date Manually &lt;a class="headline-link" href="#set-the-time-and-date-manually" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To set the clock manually, you must first disable NTP synchronization:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo timedatectl set-ntp false&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Then set the time and date using the &lt;code&gt;set-time&lt;/code&gt; subcommand. You can provide a full timestamp:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo timedatectl set-time &lt;span class="s1"&gt;&amp;#39;2026-04-15 14:30:00&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To set only the time and keep the current date:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo timedatectl set-time &lt;span class="s1"&gt;&amp;#39;14:30:00&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To set only the date and keep the current time:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo timedatectl set-time &lt;span class="s1"&gt;&amp;#39;2026-04-15&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;After setting the time, you can re-enable NTP to let the system sync automatically afterward:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo timedatectl set-ntp true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="set-the-hardware-clock-mode"&gt;Set the Hardware Clock Mode &lt;a class="headline-link" href="#set-the-hardware-clock-mode" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The RTC, or hardware clock, can store time in UTC or in local time. Linux systems should normally keep the RTC in UTC because it avoids daylight saving time issues and works better on servers.&lt;/p&gt;
&lt;p&gt;To make sure the hardware clock uses UTC, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo timedatectl set-local-rtc &lt;span class="m"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you dual-boot with an operating system that expects the hardware clock to use local time, you can switch the RTC to local time:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo timedatectl set-local-rtc &lt;span class="m"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;After changing the RTC mode, run &lt;code&gt;timedatectl&lt;/code&gt; again and check the &lt;code&gt;RTC in local TZ&lt;/code&gt; line. Use local RTC only when another operating system on the same machine requires it.&lt;/p&gt;
&lt;h2 id="check-ntp-synchronization-status"&gt;Check NTP Synchronization Status &lt;a class="headline-link" href="#check-ntp-synchronization-status" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For more detail about the NTP sync, use &lt;code&gt;timesync-status&lt;/code&gt;. This subcommand is provided by &lt;code&gt;systemd-timesyncd&lt;/code&gt; and shows the current server, offset, and polling interval:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;timedatectl timesync-status&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt; Server: 185.125.190.56 (ntp.ubuntu.com)
Poll interval: 34min 8s (min: 32s; max 34min 8s)
Leap: normal
Version: 4
Stratum: 2
Reference: 17.253.52.253
Precision: 1us (-19)
Root distance: 19.455ms (max: 5s)
Offset: -2.408ms
Delay: 29.124ms
Jitter: 5.716ms
Packet count: 5&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Offset&lt;/code&gt; is how far your system clock drifted before the last sync. A small offset, under a few hundred milliseconds, is normal. A large offset can point to network problems or a misconfigured time source.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;timesync-status&lt;/code&gt; only works when &lt;code&gt;systemd-timesyncd&lt;/code&gt; is handling NTP. If your system uses a different NTP daemon such as &lt;code&gt;chrony&lt;/code&gt; or &lt;code&gt;ntpd&lt;/code&gt;, check its own status commands instead.&lt;/p&gt;
&lt;h2 id="machine-parseable-output"&gt;Machine-Parseable Output &lt;a class="headline-link" href="#machine-parseable-output" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;show&lt;/code&gt; subcommand prints the same information as &lt;code&gt;status&lt;/code&gt; in a key-value format that is easier to parse in scripts:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;timedatectl show&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Timezone=Europe/Berlin
LocalRTC=no
CanNTP=yes
NTP=yes
NTPSynchronized=yes
TimeUSec=Tue 2026-04-14 10:00:00 UTC
RTCTimeUSec=Tue 2026-04-14 10:00:00 UTC&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Pass &lt;code&gt;--property&lt;/code&gt; to extract a single value:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;timedatectl show --property&lt;span class="o"&gt;=&lt;/span&gt;Timezone --value&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Europe/Berlin&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is useful in automation and configuration management scripts where you need to check the current time zone without parsing the human-readable &lt;code&gt;status&lt;/code&gt; output.&lt;/p&gt;
&lt;p&gt;For timesync details in key-value format, use &lt;code&gt;show-timesync&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;timedatectl show-timesync&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This gives scripts access to &lt;code&gt;systemd-timesyncd&lt;/code&gt; properties such as the current server name, poll interval, and root distance.&lt;/p&gt;
&lt;h2 id="timedatectl-options"&gt;timedatectl Options &lt;a class="headline-link" href="#timedatectl-options" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--no-ask-password&lt;/code&gt; - Do not prompt for authentication; use the invoking user&amp;rsquo;s credentials&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--adjust-system-clock&lt;/code&gt; - When setting the RTC, also adjust the system clock accordingly&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--no-pager&lt;/code&gt; - Print output without piping through a pager&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-p NAME&lt;/code&gt;, &lt;code&gt;--property=NAME&lt;/code&gt; - Show one named property from &lt;code&gt;show&lt;/code&gt; output&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-H ADDR&lt;/code&gt;, &lt;code&gt;--host=ADDR&lt;/code&gt; - Execute the command on a remote host over SSH&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-M MACHINE&lt;/code&gt;, &lt;code&gt;--machine=MACHINE&lt;/code&gt; - Execute the command inside a local container&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/timedatectl/"&gt;timedatectl cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;timedatectl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show current time, time zone, and NTP status&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;timedatectl show&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show status in key-value format (script-friendly)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;timedatectl list-timezones&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List all available time zone identifiers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo timedatectl set-timezone TZ&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Set the time zone (e.g., &lt;code&gt;America/New_York&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo timedatectl set-ntp true&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Enable NTP synchronization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo timedatectl set-ntp false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Disable NTP synchronization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo timedatectl set-time 'YYYY-MM-DD HH:MM:SS'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Set time and date manually (NTP must be off)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo timedatectl set-local-rtc 0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Store the hardware clock in UTC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;timedatectl timesync-status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show NTP sync detail from systemd-timesyncd&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;timedatectl show-timesync&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show NTP sync detail in key-value format&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;timedatectl show --property=Timezone --value&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Print the current time zone name only&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Failed to set time: Automatic time synchronization is enabled&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
NTP is active and has locked the clock. Disable NTP first with &lt;code&gt;sudo timedatectl set-ntp false&lt;/code&gt;, then run your &lt;code&gt;set-time&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Failed to set time: Access denied&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
You need administrator privileges. Prepend &lt;code&gt;sudo&lt;/code&gt; to the command.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Failed to connect to bus: No such file or directory&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;timedatectl&lt;/code&gt; communicates with &lt;code&gt;systemd-logind&lt;/code&gt; over D-Bus. This error usually appears in minimal containers or chroot environments where systemd is not running. In those cases, set the time directly with the &lt;a href="https://linuxize.com/post/linux-date-command/"&gt;&lt;code&gt;date&lt;/code&gt;&lt;/a&gt;
command: &lt;code&gt;sudo date -s '2026-04-15 14:30:00'&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;timesync-status&lt;/code&gt; returns &lt;code&gt;Failed to query server: Unit dbus-org.freedesktop.timesync1.service not found&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;systemd-timesyncd&lt;/code&gt; is not installed or not running. If your system uses &lt;code&gt;chrony&lt;/code&gt; or &lt;code&gt;ntpd&lt;/code&gt; instead, check their status with &lt;code&gt;chronyc tracking&lt;/code&gt; or &lt;code&gt;ntpq -p&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;timedatectl&lt;/code&gt; and the &lt;code&gt;date&lt;/code&gt; command?&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://linuxize.com/post/linux-date-command/"&gt;&lt;code&gt;date&lt;/code&gt;&lt;/a&gt;
reads and formats timestamps, and it can set the system clock with &lt;code&gt;sudo date -s&lt;/code&gt;. &lt;code&gt;timedatectl&lt;/code&gt; is the systemd tool that also manages time zones, the RTC, and NTP synchronization. On systemd-based systems, use &lt;code&gt;timedatectl&lt;/code&gt; for time configuration and &lt;code&gt;date&lt;/code&gt; for formatting timestamps.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does &lt;code&gt;timedatectl&lt;/code&gt; work on non-systemd distributions?&lt;/strong&gt;&lt;br&gt;
No. &lt;code&gt;timedatectl&lt;/code&gt; is part of systemd and requires &lt;code&gt;systemd-logind&lt;/code&gt; and D-Bus to be running. On systems without systemd (such as Alpine Linux with OpenRC), use the &lt;code&gt;date&lt;/code&gt; command and edit &lt;code&gt;/etc/localtime&lt;/code&gt; or &lt;code&gt;/etc/timezone&lt;/code&gt; directly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I check which NTP servers the system is using?&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;timedatectl timesync-status&lt;/code&gt; to see the current NTP server. To see the full list of configured servers, check &lt;code&gt;/etc/systemd/timesyncd.conf&lt;/code&gt;. The &lt;code&gt;NTP=&lt;/code&gt; and &lt;code&gt;FallbackNTP=&lt;/code&gt; lines list the configured time servers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I view historical time changes in system logs?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;timedatectl&lt;/code&gt; itself does not keep a history, but the system journal does. Search for time-related events with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -u systemd-timesyncd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For more on reading system logs, see the &lt;a href="https://linuxize.com/post/journalctl-command-in-linux/"&gt;journalctl guide&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For day-to-day administration, &lt;code&gt;timedatectl&lt;/code&gt; is usually enough to check the current time settings, switch time zones, toggle NTP, and inspect RTC behavior. If you need distribution-specific time zone steps, see the guide on &lt;a href="https://linuxize.com/post/how-to-set-or-change-timezone-in-linux/"&gt;how to set or change the time zone in Linux&lt;/a&gt;
.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/timedatectl-command-in-linux/featured_hu_2b65c1d0d3240571.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>How to Check CPU Usage in Linux</title><link>https://linuxize.com/post/how-to-check-cpu-usage-in-linux/</link><pubDate>Fri, 15 May 2026 09:40:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-check-cpu-usage-in-linux/</guid><category>monitoring</category><category>linux commands</category><description>This guide explains how to check CPU usage in Linux with top, htop, mpstat, vmstat, sar, ps, uptime, and per-core load tools.</description><content:encoded>&lt;p&gt;A Linux server tells you what its CPUs are doing through several built-in tools, each with a different angle. &lt;code&gt;top&lt;/code&gt; and &lt;code&gt;htop&lt;/code&gt; show the live picture. &lt;code&gt;mpstat&lt;/code&gt;, &lt;code&gt;vmstat&lt;/code&gt;, and &lt;code&gt;sar&lt;/code&gt; from the &lt;code&gt;sysstat&lt;/code&gt; package report numeric samples that suit scripts and dashboards. &lt;code&gt;ps&lt;/code&gt; attributes usage to specific processes, and &lt;code&gt;uptime&lt;/code&gt; summarizes the load over the last fifteen minutes.&lt;/p&gt;
&lt;p&gt;This guide explains how to read CPU usage from each of those tools, which one to reach for in which situation, and how to interpret common output fields.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;top&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Live snapshot, sort by CPU&lt;/td&gt;
&lt;td&gt;&lt;code&gt;top&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;htop&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Interactive, per-core view&lt;/td&gt;
&lt;td&gt;&lt;code&gt;htop&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mpstat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Per-core sampling for scripts&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mpstat -P ALL 1 5&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vmstat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;System-wide CPU and memory&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vmstat -y 1 5&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sar&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Current or saved CPU samples&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sar -u 1 5&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ps&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Per-process attribution&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ps -eo pid,user,%cpu,comm --sort=-%cpu | head&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uptime&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Load average summary&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uptime&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;nproc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Logical core count&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nproc&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lscpu&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CPU topology details&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lscpu&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="method-1-top"&gt;Method 1: top &lt;a class="headline-link" href="#method-1-top" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;a href="https://linuxize.com/post/top-command-in-linux/"&gt;&lt;code&gt;top&lt;/code&gt; command&lt;/a&gt;
is available on most Linux systems without any extra packages. Run it without arguments to open the live view:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;top&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The header summarizes the CPU lines:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;%Cpu(s): 4.2 us, 1.3 sy, 0.0 ni, 93.8 id, 0.5 wa, 0.0 hi, 0.2 si, 0.0 st&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The fields tell you where CPU time goes. &lt;code&gt;us&lt;/code&gt; is user-space code, &lt;code&gt;sy&lt;/code&gt; is kernel code, &lt;code&gt;id&lt;/code&gt; is idle, &lt;code&gt;wa&lt;/code&gt; is time waiting for I/O, and &lt;code&gt;st&lt;/code&gt; is time stolen by the hypervisor on a virtual machine. A high &lt;code&gt;wa&lt;/code&gt; value points at slow disks rather than a CPU bottleneck.&lt;/p&gt;
&lt;p&gt;Press &lt;code&gt;1&lt;/code&gt; while &lt;code&gt;top&lt;/code&gt; is open to switch from the aggregate line to one row per logical CPU. Press &lt;code&gt;P&lt;/code&gt; to sort processes by CPU usage, &lt;code&gt;M&lt;/code&gt; to sort by memory, and &lt;code&gt;q&lt;/code&gt; to quit.&lt;/p&gt;
&lt;h2 id="method-2-htop"&gt;Method 2: htop &lt;a class="headline-link" href="#method-2-htop" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://linuxize.com/post/htop-command-in-linux/"&gt;htop&lt;/a&gt;
is an interactive replacement for &lt;code&gt;top&lt;/code&gt;. It is available in the default repositories of most Linux distributions, but it may not be installed by default.&lt;/p&gt;
&lt;p&gt;On Ubuntu, Debian, and Derivatives:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install htop&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Fedora, RHEL, and Derivatives:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install htop&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Run it the same way:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;htop&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;htop&lt;/code&gt; shows a colored bar per CPU at the top, a memory and swap bar, and a sortable process table below. Click a column header or use the function keys to sort. Search for a process with &lt;code&gt;F3&lt;/code&gt;, filter with &lt;code&gt;F4&lt;/code&gt;, and send a signal to a selected process with &lt;code&gt;F9&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="method-3-mpstat"&gt;Method 3: mpstat &lt;a class="headline-link" href="#method-3-mpstat" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;mpstat&lt;/code&gt; is part of the &lt;code&gt;sysstat&lt;/code&gt; package and is the right tool when you need numeric CPU samples per core. Install it once before using &lt;code&gt;mpstat&lt;/code&gt; or &lt;code&gt;sar&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On Ubuntu, Debian, and Derivatives:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install sysstat&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Fedora, RHEL, and Derivatives:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install sysstat&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Sample all cores at one-second intervals five times:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mpstat -P ALL &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;03:14:00 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
03:14:01 PM all 3.27 0.00 0.75 0.00 0.00 0.00 0.00 0.00 0.00 95.98
03:14:01 PM 0 4.95 0.00 0.99 0.00 0.00 0.00 0.00 0.00 0.00 94.06
03:14:01 PM 1 1.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 98.00&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;all&lt;/code&gt; row is the aggregate. Each numbered row is a single logical CPU. Use this output when one core is pinned at 100 percent and the others are idle, which can happen when an application is single-threaded.&lt;/p&gt;
&lt;h2 id="method-4-vmstat"&gt;Method 4: vmstat &lt;a class="headline-link" href="#method-4-vmstat" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;vmstat&lt;/code&gt; is part of &lt;code&gt;procps&lt;/code&gt; and combines CPU usage with memory, swap, and I/O. The first report normally shows averages since boot, so use &lt;code&gt;-y&lt;/code&gt; when you want only interval samples. The columns at the right are the CPU summary:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;vmstat -y &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 7430080 311288 1843264 0 0 8 18 148 263 3 1 96 0 0
0 0 0 7430080 311288 1843264 0 0 0 0 127 226 1 0 99 0 0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;r&lt;/code&gt; is the run queue length, which is how many processes are ready to use a CPU. A run queue consistently larger than the number of CPUs is a sign of CPU pressure. The &lt;code&gt;cpu&lt;/code&gt; columns mirror the meaning of the &lt;code&gt;top&lt;/code&gt; header.&lt;/p&gt;
&lt;h2 id="method-5-sar"&gt;Method 5: sar &lt;a class="headline-link" href="#method-5-sar" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;sar&lt;/code&gt;, also from &lt;code&gt;sysstat&lt;/code&gt;, can print current samples and read saved activity logs. On Ubuntu and Debian, enable history collection after installing &lt;code&gt;sysstat&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo sed -i &lt;span class="s1"&gt;&amp;#39;s/^ENABLED=&amp;#34;false&amp;#34;/ENABLED=&amp;#34;true&amp;#34;/&amp;#39;&lt;/span&gt; /etc/default/sysstat
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; --now sysstat&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The collector setup differs between distributions. If &lt;code&gt;sar&lt;/code&gt; shows no saved history, check your distribution&amp;rsquo;s &lt;code&gt;sysstat&lt;/code&gt; service or timer configuration.&lt;/p&gt;
&lt;p&gt;Show current CPU samples:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sar -u &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;03:15:01 PM CPU %user %nice %system %iowait %steal %idle
03:15:02 PM all 2.34 0.00 0.71 0.05 0.00 96.90
03:15:03 PM all 2.18 0.00 0.69 0.04 0.00 97.09&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Each row is a sample interval. Combine with &lt;code&gt;-f&lt;/code&gt; to read an older log, for example &lt;code&gt;sar -u -f /var/log/sysstat/sa10&lt;/code&gt; for the tenth of the month on systems that store logs in &lt;code&gt;/var/log/sysstat/&lt;/code&gt;. This is the right tool when you need to confirm that a slowdown reported yesterday lined up with a CPU spike.&lt;/p&gt;
&lt;h2 id="method-6-ps"&gt;Method 6: ps &lt;a class="headline-link" href="#method-6-ps" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;a href="https://linuxize.com/post/ps-command-in-linux/"&gt;&lt;code&gt;ps&lt;/code&gt; command&lt;/a&gt;
lists every process and lets you sort by CPU percentage. The pattern most admins reach for is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ps -eo pid,user,%cpu,%mem,comm --sort&lt;span class="o"&gt;=&lt;/span&gt;-%cpu &lt;span class="p"&gt;|&lt;/span&gt; head&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt; PID USER %CPU %MEM COMMAND
1437 dejan 23.5 4.2 firefox
2049 dejan 11.2 2.8 node
1102 root 4.7 0.9 systemd-journal&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output is a snapshot at the moment &lt;code&gt;ps&lt;/code&gt; ran. The &lt;code&gt;%CPU&lt;/code&gt; value is the average CPU usage over the lifetime of the process, not an instantaneous reading. For a live view, repeat the command with &lt;code&gt;watch&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;watch -n &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;ps -eo pid,user,%cpu,%mem,comm --sort=-%cpu | head&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;watch&lt;/code&gt; reruns the command every two seconds, which gives you a refreshing top-five view without leaving the shell.&lt;/p&gt;
&lt;h2 id="method-7-uptime-and-load-averages"&gt;Method 7: uptime and Load Averages &lt;a class="headline-link" href="#method-7-uptime-and-load-averages" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;a href="https://linuxize.com/post/linux-uptime-command/"&gt;&lt;code&gt;uptime&lt;/code&gt; command&lt;/a&gt;
is the smallest of the lot. Without arguments it prints the system uptime and the load average:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uptime&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt; 15:04:23 up 3:17, 2 users, load average: 0.42, 0.35, 0.31&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The three numbers are the average number of processes that are runnable or in uninterruptible sleep over the last 1, 5, and 15 minutes. Compare them with &lt;code&gt;nproc&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nproc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;8&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A load average that stays below the core count is healthy. A load average well above the core count means processes are queueing for CPU time. The 15-minute value is the trend; the 1-minute value reacts to short spikes.&lt;/p&gt;
&lt;h2 id="method-8-capacity-context"&gt;Method 8: Capacity Context &lt;a class="headline-link" href="#method-8-capacity-context" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before you read CPU usage, know what the host has. &lt;code&gt;lscpu&lt;/code&gt; summarizes the CPU model, sockets, cores, and threads. For a deeper hardware view, see the guide on &lt;a href="https://linuxize.com/post/get-cpu-information-on-linux/"&gt;checking CPU information in Linux&lt;/a&gt;
.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lscpu&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Address sizes: 46 bits physical, 48 bits virtual
Byte Order: Little Endian
CPU(s): 8
On-line CPU(s) list: 0-7
Vendor ID: GenuineIntel
Model name: Intel(R) Core(TM) i7-9700K CPU @ 3.60 GHz
Thread(s) per core: 1
Core(s) per socket: 8
Socket(s): 1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Thread(s) per core: 1&lt;/code&gt; means hyper-threading is disabled or not present, so each logical CPU is a physical core. A high CPU usage on a chip with eight physical cores is different from the same number on a four-core chip with hyper-threading.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;mpstat: command not found&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The &lt;code&gt;sysstat&lt;/code&gt; package is not installed. Install it with &lt;code&gt;sudo apt install sysstat&lt;/code&gt; on Ubuntu, Debian, and Derivatives, or &lt;code&gt;sudo dnf install sysstat&lt;/code&gt; on Fedora, RHEL, and Derivatives.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;sar&lt;/code&gt; reports &lt;code&gt;Cannot open /var/log/sysstat/&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
Sample collection is not enabled. Set &lt;code&gt;ENABLED=&amp;quot;true&amp;quot;&lt;/code&gt; in &lt;code&gt;/etc/default/sysstat&lt;/code&gt; and restart the service with &lt;code&gt;sudo systemctl restart sysstat&lt;/code&gt;. Wait at least one collection interval before rerunning &lt;code&gt;sar&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;top&lt;/code&gt; shows more than 100% CPU for one process&lt;/strong&gt;&lt;br&gt;
The default mode shows percentage relative to a single CPU, so a multi-threaded process can exceed 100 percent. Press &lt;code&gt;Shift+I&lt;/code&gt; to toggle Irix mode off, and the value normalizes across all CPUs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Load average looks high but no process consumes CPU&lt;/strong&gt;&lt;br&gt;
Load includes processes in &lt;code&gt;D&lt;/code&gt; state, which is uninterruptible sleep. Check &lt;code&gt;ps -eo state,pid,comm | awk '$1 ~ /D/'&lt;/code&gt; to find processes blocked on I/O. The cause is usually a slow or stalled disk.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Per-core view in &lt;code&gt;htop&lt;/code&gt; is empty&lt;/strong&gt;&lt;br&gt;
Old terminal sizes hide the CPU bar. Resize the window or set &lt;code&gt;Display&lt;/code&gt; options inside &lt;code&gt;htop&lt;/code&gt; with &lt;code&gt;F2&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Which tool should I check first?&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;top&lt;/code&gt; or &lt;code&gt;htop&lt;/code&gt; for a live picture, then drop to &lt;code&gt;mpstat&lt;/code&gt; and &lt;code&gt;sar&lt;/code&gt; when you need numbers or history. &lt;code&gt;ps&lt;/code&gt; answers the per-process question once you know there is a problem.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What does &lt;code&gt;%steal&lt;/code&gt; mean?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;%steal&lt;/code&gt; is the time the hypervisor took from the guest VM to run something else. A consistent non-zero &lt;code&gt;%steal&lt;/code&gt; value on a VM means the host is over-committed and the guest cannot get the CPU it asked for.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I count CPUs from a script?&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;nproc&lt;/code&gt; for the logical CPU count, or &lt;code&gt;nproc --all&lt;/code&gt; to include offline CPUs. Both return a single integer and are stable across distributions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is high CPU always bad?&lt;/strong&gt;&lt;br&gt;
No. A batch job that finishes faster on a CPU running at full capacity is healthier than the same job spread thinly over a long period. CPU is bad when the load average exceeds the core count for sustained periods or when interactive workloads time out.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Pick the tool that matches the question. &lt;code&gt;top&lt;/code&gt; and &lt;code&gt;htop&lt;/code&gt; answer &amp;ldquo;what is happening right now&amp;rdquo;. &lt;code&gt;mpstat&lt;/code&gt; and &lt;code&gt;vmstat&lt;/code&gt; answer &amp;ldquo;is the load even across cores&amp;rdquo;. &lt;code&gt;sar&lt;/code&gt; answers &amp;ldquo;what happened last night&amp;rdquo;. Treat load averages as a trend, not a verdict, and always read CPU numbers in the context of the core count from &lt;code&gt;nproc&lt;/code&gt;.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-check-cpu-usage-in-linux/featured_hu_7fd4237466751cce.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>systemctl Command in Linux: Start, Stop, and Manage Services</title><link>https://linuxize.com/post/systemctl-command-in-linux/</link><pubDate>Thu, 14 May 2026 10:30:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/systemctl-command-in-linux/</guid><category>linux commands</category><description>Manage services on systemd-based Linux distributions with systemctl. This guide explains how to start, stop, restart, enable, and disable services, reload unit files, and inspect service status.</description><content:encoded>&lt;p&gt;Every modern Linux distribution runs a handful of services in the background at any given moment: an SSH daemon, a cron daemon, a web server, a database, a firewall. On systemd-based systems, the one tool you use to control all of them is &lt;code&gt;systemctl&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;systemctl&lt;/code&gt; is the command-line front end for systemd. It starts and stops services, enables them at boot, reloads unit files after an edit, and reports the status of each one. This guide walks through the commands you will reach for most often when managing services on a running system.&lt;/p&gt;
&lt;h2 id="systemctl-syntax"&gt;systemctl Syntax &lt;a class="headline-link" href="#systemctl-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The general syntax of the command is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl [OPTIONS] COMMAND [UNIT...]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;A &lt;code&gt;UNIT&lt;/code&gt; is usually a service name such as &lt;code&gt;nginx.service&lt;/code&gt; or &lt;code&gt;cron.service&lt;/code&gt;. The &lt;code&gt;.service&lt;/code&gt; suffix is optional when the unit type is unambiguous, so &lt;code&gt;systemctl start nginx&lt;/code&gt; and &lt;code&gt;systemctl start nginx.service&lt;/code&gt; do the same thing.&lt;/p&gt;
&lt;p&gt;Most commands that change state (start, stop, enable, disable) require root privileges. Run them with &lt;code&gt;sudo&lt;/code&gt; or as root.&lt;/p&gt;
&lt;h2 id="check-the-status-of-a-service"&gt;Check the Status of a Service &lt;a class="headline-link" href="#check-the-status-of-a-service" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before you touch a service, check what it is doing. The &lt;code&gt;status&lt;/code&gt; command prints the current state, recent log lines, the PID of the main process, and the path of the unit file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl status nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)
Active: active (running) since Mon 2026-04-13 09:12:04 CEST; 2h 3min ago
Docs: man:nginx(8)
Main PID: 1591 (nginx)
Tasks: 3 (limit: 4612)
Memory: 6.2M
CPU: 112ms
CGroup: /system.slice/nginx.service
├─1591 &amp;#34;nginx: master process /usr/sbin/nginx -g daemon on; master_process on;&amp;#34;
└─1592 &amp;#34;nginx: worker process&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The two lines to read first are &lt;code&gt;Loaded&lt;/code&gt; and &lt;code&gt;Active&lt;/code&gt;. &lt;code&gt;Loaded&lt;/code&gt; tells you whether the unit file was found and whether it is set to start at boot (&lt;code&gt;enabled&lt;/code&gt;, &lt;code&gt;disabled&lt;/code&gt;, &lt;code&gt;masked&lt;/code&gt;, or &lt;code&gt;static&lt;/code&gt;). &lt;code&gt;Active&lt;/code&gt; tells you what the service is doing right now (&lt;code&gt;active (running)&lt;/code&gt;, &lt;code&gt;inactive (dead)&lt;/code&gt;, &lt;code&gt;failed&lt;/code&gt;, and so on).&lt;/p&gt;
&lt;h2 id="start-and-stop-services"&gt;Start and Stop Services &lt;a class="headline-link" href="#start-and-stop-services" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To start a service that is not running:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl start nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The command returns silently when the service starts. Run &lt;code&gt;systemctl status nginx&lt;/code&gt; afterwards to confirm.&lt;/p&gt;
&lt;p&gt;To stop a running service:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl stop nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Stopping a service only affects the current session. If the service is enabled at boot, it will come back the next time the system starts.&lt;/p&gt;
&lt;h2 id="restart-and-reload"&gt;Restart and Reload &lt;a class="headline-link" href="#restart-and-reload" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A restart fully stops the service and starts it again, which terminates all active connections. This is the command you use after a binary upgrade or any change that the service cannot pick up on its own:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;A reload asks the service to re-read its configuration without dropping active connections. Whether this works depends on the service itself. Web servers such as Nginx and Apache support it well; some services do not define a reload action.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl reload nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the unit file supports it, &lt;code&gt;reload-or-restart&lt;/code&gt; is a safer combination: it tries &lt;code&gt;reload&lt;/code&gt; first and falls back to a full restart if the service does not handle reload signals.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl reload-or-restart nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="enable-and-disable-at-boot"&gt;Enable and Disable at Boot &lt;a class="headline-link" href="#enable-and-disable-at-boot" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Starting a service with &lt;code&gt;start&lt;/code&gt; does not persist across a reboot. To make a service launch automatically at boot, use &lt;code&gt;enable&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /lib/systemd/system/nginx.service.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output hints at what is happening behind the scenes. Enabling a service creates a symlink in one of the &lt;code&gt;*.wants&lt;/code&gt; directories so that the appropriate boot target pulls the unit in.&lt;/p&gt;
&lt;p&gt;To disable a service so that it no longer starts at boot:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl disable nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;enable&lt;/code&gt; and &lt;code&gt;disable&lt;/code&gt; only change the boot behavior. To start or stop the service in the current session as well, add the &lt;code&gt;--now&lt;/code&gt; flag:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; --now nginx
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl disable --now nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To check whether a service is currently enabled at boot:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl is-enabled nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="mask-and-unmask"&gt;Mask and Unmask &lt;a class="headline-link" href="#mask-and-unmask" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Disabling a service prevents it from starting at boot, but another service, socket, or admin can still start it manually. &lt;code&gt;mask&lt;/code&gt; is the stronger option. It links the unit file to &lt;code&gt;/dev/null&lt;/code&gt; so that every attempt to start it fails, whether from the command line, from another unit, or from a boot target.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl mask apache2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To undo this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl unmask apache2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Masking is useful when two services conflict over the same port (for example, Nginx and Apache both wanting port 80) and you want to make sure the one you are not using cannot come back.&lt;/p&gt;
&lt;h2 id="reload-systemd-after-unit-file-changes"&gt;Reload systemd After Unit File Changes &lt;a class="headline-link" href="#reload-systemd-after-unit-file-changes" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When you add a new unit file or edit an existing one, systemd does not pick up the changes automatically. Tell it to reload its configuration with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl daemon-reload&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Run this command after:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creating a new &lt;code&gt;.service&lt;/code&gt; file under &lt;code&gt;/etc/systemd/system/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Editing a unit file (either directly or via &lt;code&gt;systemctl edit&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Installing a package that ships a new unit file&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After &lt;code&gt;daemon-reload&lt;/code&gt;, restart the affected service if it was already running, so it starts under the new definition.&lt;/p&gt;
&lt;h2 id="list-services"&gt;List Services &lt;a class="headline-link" href="#list-services" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;systemctl&lt;/code&gt; can list every unit it knows about, which is useful when you want to see what is active, what is failing, or what is simply installed. Because the listing commands have several useful variations, they have their own dedicated guide: see &lt;a href="https://linuxize.com/post/systemctl-list/"&gt;listing Linux services with systemctl&lt;/a&gt;
for filtering by state, showing inactive units, and listing unit files.&lt;/p&gt;
&lt;p&gt;The quickest view is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl --failed&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;It prints every service that has failed since boot, which is usually the first thing you want to know on a box you do not fully trust yet.&lt;/p&gt;
&lt;h2 id="view-service-logs"&gt;View Service Logs &lt;a class="headline-link" href="#view-service-logs" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;systemd stores service logs in the journal, which you query with &lt;code&gt;journalctl&lt;/code&gt;. To follow the log for a single service:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo journalctl -u nginx -f&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;-u&lt;/code&gt; flag filters by unit, and &lt;code&gt;-f&lt;/code&gt; follows new entries as they are written. For a full walkthrough of the journal, see the &lt;a href="https://linuxize.com/post/journalctl-command-in-linux/"&gt;journalctl command&lt;/a&gt;
guide.&lt;/p&gt;
&lt;h2 id="reboot-power-off-and-suspend"&gt;Reboot, Power Off, and Suspend &lt;a class="headline-link" href="#reboot-power-off-and-suspend" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;systemctl also controls system power state. These commands do not require a service name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl reboot
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl poweroff
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;suspend&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl hibernate&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;They are equivalent to the older &lt;code&gt;reboot&lt;/code&gt;, &lt;code&gt;poweroff&lt;/code&gt;, and &lt;code&gt;halt&lt;/code&gt; commands, and they go through systemd so that services shut down cleanly.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Unit nginx.service could not be found.&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The service is not installed, or the unit file is in a location systemd does not scan. Install the package, or run &lt;code&gt;sudo systemctl daemon-reload&lt;/code&gt; if you just added a unit file manually.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Failed to start nginx.service: Unit is masked.&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The unit has been masked. Run &lt;code&gt;sudo systemctl unmask nginx&lt;/code&gt; and try again.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Service keeps failing after a config change&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;systemctl status SERVICE&lt;/code&gt; and &lt;code&gt;journalctl -u SERVICE -n 50&lt;/code&gt; to read the most recent log lines. Configuration syntax errors are the most common cause.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes to the unit file are ignored&lt;/strong&gt;&lt;br&gt;
You forgot &lt;code&gt;sudo systemctl daemon-reload&lt;/code&gt;. systemd caches unit files in memory and needs to be told to reread them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Permission denied&lt;/strong&gt;&lt;br&gt;
Most state-changing commands require root. Prefix the command with &lt;code&gt;sudo&lt;/code&gt;, or switch to the root user.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/systemctl/"&gt;systemctl cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Show service status&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl status nginx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Start a service&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl start nginx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stop a service&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl stop nginx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Restart a service&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl restart nginx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reload configuration&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl reload nginx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enable at boot&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl enable nginx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enable and start now&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl enable --now nginx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Disable at boot&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl disable nginx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check boot status&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl is-enabled nginx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reload unit files&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl daemon-reload&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Show failed units&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl --failed&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Follow service logs&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo journalctl -u nginx -f&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;enable&lt;/code&gt; and &lt;code&gt;start&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;start&lt;/code&gt; launches the service in the current session only. &lt;code&gt;enable&lt;/code&gt; creates the symlinks that make systemd start the service at every boot. The two are independent, which is why &lt;code&gt;--now&lt;/code&gt; exists to do both in one command.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;disable&lt;/code&gt; and &lt;code&gt;mask&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;disable&lt;/code&gt; removes the service from boot targets, but it can still be started manually or pulled in by another unit. &lt;code&gt;mask&lt;/code&gt; links the unit file to &lt;code&gt;/dev/null&lt;/code&gt; so every start attempt fails.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I know if my system uses systemd?&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;ps -p 1 -o comm=&lt;/code&gt;. If the output is &lt;code&gt;systemd&lt;/code&gt;, your init system is systemd and &lt;code&gt;systemctl&lt;/code&gt; applies. Virtually every mainstream distribution has used systemd as the default since around 2015.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does &lt;code&gt;reload&lt;/code&gt; work for every service?&lt;/strong&gt;&lt;br&gt;
No. It depends on whether the unit file defines an &lt;code&gt;ExecReload&lt;/code&gt; command and whether the service itself supports reloading. If you are unsure, use &lt;code&gt;reload-or-restart&lt;/code&gt;, which falls back to &lt;code&gt;restart&lt;/code&gt; when &lt;code&gt;reload&lt;/code&gt; is not available.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What happens to running connections when I &lt;code&gt;restart&lt;/code&gt; a service?&lt;/strong&gt;&lt;br&gt;
They are dropped. A full restart kills the process and starts a new one, so anything holding a connection will see it close. Use &lt;code&gt;reload&lt;/code&gt; or &lt;code&gt;reload-or-restart&lt;/code&gt; when the service supports it.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Most day-to-day work with &lt;code&gt;systemctl&lt;/code&gt; comes down to &lt;code&gt;status&lt;/code&gt;, &lt;code&gt;start&lt;/code&gt;, &lt;code&gt;stop&lt;/code&gt;, &lt;code&gt;restart&lt;/code&gt;, &lt;code&gt;enable&lt;/code&gt;, and &lt;code&gt;disable&lt;/code&gt;. Keep &lt;code&gt;daemon-reload&lt;/code&gt; in mind whenever you edit a unit file, and pair &lt;code&gt;systemctl&lt;/code&gt; with &lt;a href="https://linuxize.com/post/journalctl-command-in-linux/"&gt;journalctl&lt;/a&gt;
when something fails to start.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/systemctl-command-in-linux/featured_hu_53012176f0ed0bfa.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>Bash Best Practices: Writing Safer, Cleaner Scripts</title><link>https://linuxize.com/post/bash-best-practices/</link><pubDate>Wed, 13 May 2026 10:00:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/bash-best-practices/</guid><category>bash</category><category>linux commands</category><description>Practical Bash best practices for writing safer and more predictable scripts, covering strict mode, quoting, error handling, and everyday patterns.</description><content:encoded>&lt;p&gt;Bash scripts tend to start small and grow over time. A helper you wrote in five minutes to copy a few files can end up running in a cron job, a deployment pipeline, or a server startup script. When that happens, small oversights such as an unquoted variable or an ignored error become real outages.&lt;/p&gt;
&lt;p&gt;This guide covers practical Bash best practices that keep scripts predictable, safe to re-run, and easy for other people to read.&lt;/p&gt;
&lt;h2 id="start-with-a-clear-shebang"&gt;Start With a Clear Shebang &lt;a class="headline-link" href="#start-with-a-clear-shebang" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Every Bash script should begin with a proper shebang line. The portable choice for Bash is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/script.sh&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#!/usr/bin/env bash&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Using &lt;code&gt;/usr/bin/env bash&lt;/code&gt; lets the script find Bash through the &lt;code&gt;PATH&lt;/code&gt;, which matters on systems where Bash is installed outside &lt;code&gt;/bin&lt;/code&gt;, such as macOS with Homebrew. If you rely on features that exist only in Bash, do not use &lt;code&gt;#!/bin/sh&lt;/code&gt;. On many distributions &lt;code&gt;/bin/sh&lt;/code&gt; points to &lt;code&gt;dash&lt;/code&gt; or another minimal shell, and arrays, &lt;code&gt;[[ ]]&lt;/code&gt;, and &lt;code&gt;local&lt;/code&gt; will not behave the same way.&lt;/p&gt;
&lt;h2 id="enable-strict-mode"&gt;Enable Strict Mode &lt;a class="headline-link" href="#enable-strict-mode" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, Bash ignores many errors. A command can fail, a variable can be unset, and the script will keep running as if nothing happened. Enabling strict mode at the top of the script changes that behavior.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/script.sh&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; -euo pipefail&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Here is what each flag does:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-e&lt;/code&gt; - Exit immediately if any command returns a non-zero status.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-u&lt;/code&gt; - Treat unset variables as an error and exit.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-o pipefail&lt;/code&gt; - Make a pipeline fail if any command in it fails, not only the last one.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A common extra is &lt;code&gt;IFS=$'\n\t'&lt;/code&gt;, which prevents word splitting on spaces and avoids surprises when iterating over filenames that contain spaces.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/script.sh&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; -euo pipefail
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;$&amp;#39;\n\t&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Strict mode is not magic. It will not catch logic errors, and in some scripts you will need to opt out locally with &lt;code&gt;|| true&lt;/code&gt; for commands that are allowed to fail. The point is to flip the default from &amp;ldquo;keep going on errors&amp;rdquo; to &amp;ldquo;stop on errors&amp;rdquo;, which is almost always the safer choice. For a closer look at each option on its own, see our &lt;a href="https://linuxize.com/post/bash-set-command/"&gt;bash set command&lt;/a&gt;
guide.&lt;/p&gt;
&lt;h2 id="always-quote-your-variables"&gt;Always Quote Your Variables &lt;a class="headline-link" href="#always-quote-your-variables" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Unquoted variables in Bash are expanded and then word-split. If a variable contains spaces, wildcards, or is empty, the result may be very different from what you expect.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;My Report.txt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;lt;%s&amp;gt;\n&amp;#39;&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Because &lt;code&gt;$file&lt;/code&gt; is not quoted, Bash passes two arguments to &lt;code&gt;printf&lt;/code&gt;: &lt;code&gt;My&lt;/code&gt; and &lt;code&gt;Report.txt&lt;/code&gt;. Quoting fixes it and keeps the filename as one value:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;lt;%s&amp;gt;\n&amp;#39;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The same rule applies inside tests, loops, and command substitutions. When in doubt, quote. The only common case where you intentionally leave a variable unquoted is when you want word splitting, which should be rare and deliberate.&lt;/p&gt;
&lt;h2 id="prefer---over--"&gt;Prefer [[ ]] Over [ ] &lt;a class="headline-link" href="#prefer---over--" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bash supports two test constructs: the older &lt;code&gt;[ ]&lt;/code&gt; (a synonym for the &lt;code&gt;test&lt;/code&gt; command) and the newer &lt;code&gt;[[ ]]&lt;/code&gt; keyword. For Bash scripts, prefer &lt;code&gt;[[ ]]&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; -f &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$config&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$env&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;production&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Loading production config&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;[[ ]]&lt;/code&gt; handles empty variables safely even without quotes, supports pattern matching with &lt;code&gt;==&lt;/code&gt; and regex with &lt;code&gt;=~&lt;/code&gt;, and allows logical operators such as &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; and &lt;code&gt;||&lt;/code&gt; inside the test. Only fall back to &lt;code&gt;[ ]&lt;/code&gt; when writing a portable POSIX script that must run under &lt;code&gt;sh&lt;/code&gt; or &lt;code&gt;dash&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="use-functions-for-repeated-logic"&gt;Use Functions for Repeated Logic &lt;a class="headline-link" href="#use-functions-for-repeated-logic" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Once a script has more than a couple of steps, group related commands into functions. Functions make scripts easier to read, test, and refactor.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/backup.sh&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;log&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;[%s] %s\n&amp;#39;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;date +&lt;span class="s1"&gt;&amp;#39;%F %T&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$*&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;backup_dir&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;local&lt;/span&gt; &lt;span class="nv"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;local&lt;/span&gt; &lt;span class="nv"&gt;dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; log &lt;span class="s2"&gt;&amp;#34;Backing up &lt;/span&gt;&lt;span class="nv"&gt;$src&lt;/span&gt;&lt;span class="s2"&gt; to &lt;/span&gt;&lt;span class="nv"&gt;$dst&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; rsync -a &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$src&lt;/span&gt;&lt;span class="s2"&gt;/&amp;#34;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$dst&lt;/span&gt;&lt;span class="s2"&gt;/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;backup_dir &lt;span class="s2"&gt;&amp;#34;/var/www&amp;#34;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/backup/www&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Declare variables inside functions with &lt;code&gt;local&lt;/code&gt; so they do not leak into the rest of the script. Pass input as positional parameters, and return output via &lt;code&gt;echo&lt;/code&gt; or &lt;code&gt;printf&lt;/code&gt; rather than global variables when possible.&lt;/p&gt;
&lt;p&gt;See &lt;a href="https://linuxize.com/post/bash-functions/"&gt;Bash functions&lt;/a&gt;
for more details on arguments, return values, and scoping.&lt;/p&gt;
&lt;h2 id="handle-errors-explicitly"&gt;Handle Errors Explicitly &lt;a class="headline-link" href="#handle-errors-explicitly" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Strict mode stops the script on errors, but it does not tell the user what went wrong. Adding a &lt;code&gt;trap&lt;/code&gt; on &lt;code&gt;ERR&lt;/code&gt; gives you a single place to log failures.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/script.sh&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; -Eeuo pipefail
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;on_error&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;local&lt;/span&gt; &lt;span class="nv"&gt;exit_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;local&lt;/span&gt; &lt;span class="nv"&gt;line&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Error on line &lt;/span&gt;&lt;span class="nv"&gt;$line&lt;/span&gt;&lt;span class="s2"&gt; (exit code &lt;/span&gt;&lt;span class="nv"&gt;$exit_code&lt;/span&gt;&lt;span class="s2"&gt;)&amp;#34;&lt;/span&gt; &amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$exit_code&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;trap&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;on_error $LINENO&amp;#39;&lt;/span&gt; ERR&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;-E&lt;/code&gt; option makes the &lt;code&gt;ERR&lt;/code&gt; trap inherit into functions and subshells. Without it, a failure inside a helper function may exit the script without running your error handler.&lt;/p&gt;
&lt;p&gt;For cleanup tasks such as removing temporary files, use &lt;code&gt;trap&lt;/code&gt; on &lt;code&gt;EXIT&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/script.sh&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;tmp_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;mktemp -d&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;trap&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rm -rf &amp;#34;$tmp_dir&amp;#34;&amp;#39;&lt;/span&gt; EXIT&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;EXIT&lt;/code&gt; trap runs whether the script exits normally, hits an error under &lt;code&gt;set -e&lt;/code&gt;, or is interrupted with Ctrl+C. It is the safest way to guarantee cleanup.&lt;/p&gt;
&lt;h2 id="validate-input-early"&gt;Validate Input Early &lt;a class="headline-link" href="#validate-input-early" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Scripts that take arguments should fail fast when those arguments are missing or invalid. Check them before doing any work:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;~/deploy.sh&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nv"&gt;$#&lt;/span&gt; -lt &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Usage: &lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;environment&amp;gt; &amp;lt;version&amp;gt;&amp;#34;&lt;/span&gt; &amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;env&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$env&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; in
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; staging&lt;span class="p"&gt;|&lt;/span&gt;production&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; *&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Unknown environment: &lt;/span&gt;&lt;span class="nv"&gt;$env&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;esac&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For scripts with several flags, use &lt;a href="https://linuxize.com/post/bash-getopts/"&gt;getopts&lt;/a&gt;
instead of parsing &lt;code&gt;$@&lt;/code&gt; manually. It handles short options, arguments, and error reporting in a consistent way.&lt;/p&gt;
&lt;h2 id="avoid-parsing-the-output-of-ls"&gt;Avoid Parsing the Output of ls &lt;a class="headline-link" href="#avoid-parsing-the-output-of-ls" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A common beginner mistake is looping over &lt;code&gt;ls&lt;/code&gt; output:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; f in &lt;span class="k"&gt;$(&lt;/span&gt;ls /var/log&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This breaks on filenames with spaces, newlines, or special characters. Use a glob or &lt;code&gt;find&lt;/code&gt; instead:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; f in /var/log/*&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For recursive traversal, use &lt;code&gt;find&lt;/code&gt; with &lt;code&gt;-print0&lt;/code&gt; and &lt;code&gt;xargs -0&lt;/code&gt;, or a &lt;code&gt;while read&lt;/code&gt; loop with &lt;code&gt;IFS=&lt;/code&gt; and &lt;code&gt;-d ''&lt;/code&gt; to handle unusual filenames correctly.&lt;/p&gt;
&lt;h2 id="keep-scripts-idempotent-when-possible"&gt;Keep Scripts Idempotent When Possible &lt;a class="headline-link" href="#keep-scripts-idempotent-when-possible" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A script you can safely re-run is much easier to work with than one that breaks on the second attempt. Aim for idempotent behavior: check before creating directories, use &lt;code&gt;mkdir -p&lt;/code&gt; instead of &lt;code&gt;mkdir&lt;/code&gt;, use &lt;code&gt;ln -sf&lt;/code&gt; instead of &lt;code&gt;ln -s&lt;/code&gt;, and guard commands with &lt;code&gt;if&lt;/code&gt; blocks when they would otherwise fail on re-run.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir -p /opt/app/config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The same pattern applies to package installation, user creation, and configuration edits. Tools like Ansible enforce idempotency by design; in Bash, you have to add those checks yourself.&lt;/p&gt;
&lt;h2 id="use-shellcheck"&gt;Use Shellcheck &lt;a class="headline-link" href="#use-shellcheck" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.shellcheck.net/" target="_blank" rel="noopener noreferrer"&gt;Shellcheck&lt;/a&gt;
is a static analyzer for shell scripts. It catches unquoted variables, unsafe &lt;code&gt;for&lt;/code&gt; loops, and many other common mistakes before you hit them in production.&lt;/p&gt;
&lt;p&gt;Install it from your package manager:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install shellcheck&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Then run it against your script:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;shellcheck script.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Fix the warnings it raises, or document with an inline comment why a specific check is being ignored. Making shellcheck part of your editor or pre-commit hook removes an entire class of Bash bugs.&lt;/p&gt;
&lt;h2 id="prefer-readable-over-clever"&gt;Prefer Readable Over Clever &lt;a class="headline-link" href="#prefer-readable-over-clever" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bash is full of shortcuts and obscure expansions. They can make scripts shorter, but they also make them harder to read six months later. Choose the clearer form, even when it is a few characters longer.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; -z &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;anonymous&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;is almost always easier to maintain than the golfed equivalent:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;: &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:=anonymous&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Aim for scripts that a teammate can read once and understand, not ones that require a reference manual.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/bash/"&gt;Bash cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;Before committing a Bash script, confirm the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;#!/usr/bin/env bash&lt;/code&gt; shebang is present.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;set -euo pipefail&lt;/code&gt; is enabled.&lt;/li&gt;
&lt;li&gt;All variable expansions are quoted.&lt;/li&gt;
&lt;li&gt;Tests use &lt;code&gt;[[ ]]&lt;/code&gt; instead of &lt;code&gt;[ ]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Functions replace long repeated blocks, with &lt;code&gt;local&lt;/code&gt; variables.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;trap&lt;/code&gt; handles errors and cleanup.&lt;/li&gt;
&lt;li&gt;Input is validated before work begins.&lt;/li&gt;
&lt;li&gt;No parsing of &lt;code&gt;ls&lt;/code&gt; output.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;shellcheck&lt;/code&gt; reports no warnings, or they are explicitly ignored.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Is &lt;code&gt;set -e&lt;/code&gt; enough on its own?&lt;/strong&gt;&lt;br&gt;
No. &lt;code&gt;set -e&lt;/code&gt; stops on many errors, but it misses failures in pipelines and ignores unset variables. Combine it with &lt;code&gt;-u&lt;/code&gt; and &lt;code&gt;-o pipefail&lt;/code&gt; to cover those cases.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does strict mode break existing scripts?&lt;/strong&gt;&lt;br&gt;
It often surfaces bugs that were already there, such as unset variables and ignored errors. The fix is to quote variables, use default values like &lt;code&gt;${VAR:-}&lt;/code&gt;, and handle expected failures with &lt;code&gt;|| true&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Should I write scripts in Bash or switch to Python?&lt;/strong&gt;&lt;br&gt;
Bash is a good fit for short glue scripts that mostly call other commands. Once a script grows past a few hundred lines, has complex data structures, or needs proper error handling and testing, Python or another language is usually a better choice.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where can I learn more safe scripting patterns?&lt;/strong&gt;&lt;br&gt;
Keep the &lt;a href="https://www.shellcheck.net/wiki/" target="_blank" rel="noopener noreferrer"&gt;Shellcheck wiki&lt;/a&gt;
open while you write, and read through the official &lt;a href="https://www.gnu.org/software/bash/manual/bash.html" target="_blank" rel="noopener noreferrer"&gt;Bash manual&lt;/a&gt;
section on shell builtins. Both cover the reasoning behind each rule, not only the rule itself.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Strict mode, quoting, and a few well-placed traps cover most of the risk in Bash scripting. Make these practices your defaults, run &lt;code&gt;shellcheck&lt;/code&gt; on every change, and your scripts will behave the same way on your laptop, in CI, and on a production server.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/bash-best-practices/featured_hu_de6a5152d402e81c.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>dd Command in Linux: Copy Disks, Partitions, and Files</title><link>https://linuxize.com/post/dd-command-in-linux/</link><pubDate>Sun, 10 May 2026 08:30:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/dd-command-in-linux/</guid><category>disk</category><category>linux commands</category><description>This guide explains how to use the dd command in Linux to write ISO images, clone disks, back up partitions, wipe drives, and test disk speed.</description><content:encoded>&lt;p&gt;Most of the time when you copy a file on Linux, you reach for &lt;code&gt;cp&lt;/code&gt;. It walks the filesystem, respects permissions, and works on individual files. But when you need to copy an entire disk, write an ISO image to a USB stick, or create a byte-for-byte backup of a partition, the filesystem view is not enough. For that, Linux ships with &lt;code&gt;dd&lt;/code&gt;, a tool that copies raw data block by block between any two files or devices.&lt;/p&gt;
&lt;p&gt;This guide explains how to use &lt;code&gt;dd&lt;/code&gt; safely to write ISO images, clone disks, back up partitions, create test files, and benchmark storage performance.&lt;/p&gt;
&lt;h2 id="dd-syntax"&gt;dd Syntax &lt;a class="headline-link" href="#dd-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The general form of the &lt;code&gt;dd&lt;/code&gt; command is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dd if=INPUT of=OUTPUT [OPTIONS]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The two key operands are &lt;code&gt;if&lt;/code&gt; (input file) and &lt;code&gt;of&lt;/code&gt; (output file). Either one can be a regular file, a block device such as &lt;code&gt;/dev/sda&lt;/code&gt;, or even &lt;code&gt;/dev/zero&lt;/code&gt; and &lt;code&gt;/dev/urandom&lt;/code&gt;. Options control the block size, how many blocks to copy, and what conversions to apply.&lt;/p&gt;
&lt;div class="note callout callout-warning"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"&gt;
&lt;path d="M10 20C4.477 20 0 15.523 0 10S4.477 0 10 0s10 4.477 10 10-4.477 10-10 10zm0-2c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm-.5-5h1c.276 0 .5.224.5.5v1c0 .276-.224.5-.5.5h-1c-.276 0-.5-.224-.5-.5v-1c0-.276.224-.5.5-.5zm0-8h1c.276 0 .5.224.5.5V8l-.5 3-1 .5L9 8V5.5c0-.276.224-.5.5-.5z"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;span class="callout-title"&gt;Warning&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;&lt;code&gt;dd&lt;/code&gt; writes exactly what you tell it to write, to exactly the target you point it at. Pointing &lt;code&gt;of=&lt;/code&gt; at the wrong disk will overwrite that disk without warning or confirmation. Always double-check the target device with &lt;code&gt;lsblk&lt;/code&gt; or &lt;code&gt;sudo fdisk -l&lt;/code&gt; before running a &lt;code&gt;dd&lt;/code&gt; command.&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="writing-an-iso-image-to-a-usb-drive"&gt;Writing an ISO Image to a USB Drive &lt;a class="headline-link" href="#writing-an-iso-image-to-a-usb-drive" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The most common use for &lt;code&gt;dd&lt;/code&gt; is flashing a Linux ISO to a USB drive so you can boot and install from it. First, identify the USB device with &lt;code&gt;lsblk&lt;/code&gt; or &lt;code&gt;sudo fdisk -l&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lsblk&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 465.8G 0 disk
├─sda1 8:1 0 512M 0 part /boot/efi
└─sda2 8:2 0 465.3G 0 part /
sdb 8:16 1 14.5G 0 disk
└─sdb1 8:17 1 14.5G 0 part&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here &lt;code&gt;sda&lt;/code&gt; is the system disk and &lt;code&gt;sdb&lt;/code&gt; is the USB drive. Make sure the USB is unmounted before writing to it:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo umount /dev/sdb1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Then write the ISO image:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dd &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ubuntu-24.04-desktop-amd64.iso &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/sdb &lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4M &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;progress &lt;span class="nv"&gt;oflag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;sync&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Notice that the output target is the whole disk (&lt;code&gt;/dev/sdb&lt;/code&gt;), not a partition (&lt;code&gt;/dev/sdb1&lt;/code&gt;). Writing an ISO to a partition would leave the USB unbootable. The options do the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;bs=4M&lt;/code&gt; - Read and write 4 MB at a time, which is much faster than the 512-byte default.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;status=progress&lt;/code&gt; - Print a live progress indicator so you can see how much has been written.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;oflag=sync&lt;/code&gt; - Flush every write to the device, so the final byte count reflects data actually on disk.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When &lt;code&gt;dd&lt;/code&gt; finishes, run &lt;code&gt;sync&lt;/code&gt; once more to make sure all buffered writes hit the USB stick before you remove it:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sync&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For alternative methods and distro-specific tips, see the guide on how to &lt;a href="https://linuxize.com/post/how-to-create-a-bootable-linux-usb-drive/"&gt;create a bootable Linux USB drive&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="cloning-a-whole-disk"&gt;Cloning a Whole Disk &lt;a class="headline-link" href="#cloning-a-whole-disk" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To make an exact block-level copy of one disk onto another, point &lt;code&gt;if=&lt;/code&gt; and &lt;code&gt;of=&lt;/code&gt; at two different block devices:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dd &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/sda &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/sdb &lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;64K &lt;span class="nv"&gt;conv&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;noerror,sync &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;progress&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The destination disk must be at least as large as the source. Anything already on it is overwritten. The conversion flags handle read errors gracefully:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;conv=noerror&lt;/code&gt; - Keep going when a read error occurs instead of aborting.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;conv=sync&lt;/code&gt; - Pad short reads with zeros so the output stays aligned with the source.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Clone offline whenever possible. Cloning a disk that is actively being written to produces an inconsistent copy, especially for databases and journaling filesystems.&lt;/p&gt;
&lt;h2 id="backing-up-a-partition-to-an-image-file"&gt;Backing Up a Partition to an Image File &lt;a class="headline-link" href="#backing-up-a-partition-to-an-image-file" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;dd&lt;/code&gt; can also write a partition or whole disk to a regular file. That file becomes a bit-for-bit image you can restore later:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dd &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/sda1 &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/backup/sda1.img &lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4M &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;progress&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To save space, pipe the output through &lt;code&gt;gzip&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dd &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/sda1 &lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4M &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;progress &lt;span class="p"&gt;|&lt;/span&gt; gzip -c &amp;gt; /backup/sda1.img.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The compressed image is much smaller for filesystems that contain text or empty space, though the compression step adds CPU time.&lt;/p&gt;
&lt;p&gt;To restore the image to a partition:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;gunzip -c /backup/sda1.img.gz &lt;span class="p"&gt;|&lt;/span&gt; sudo dd &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/sda1 &lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4M &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;progress&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The target partition must be unmounted during restore, and it must be at least as large as the original.&lt;/p&gt;
&lt;h2 id="backing-up-and-restoring-the-mbr"&gt;Backing Up and Restoring the MBR &lt;a class="headline-link" href="#backing-up-and-restoring-the-mbr" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The Master Boot Record sits in the first 512 bytes of a disk that uses a traditional BIOS partition table. You can back it up with &lt;code&gt;dd&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dd &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/sda &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/backup/mbr.img &lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;512&lt;/span&gt; &lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To restore the MBR, swap the input and output:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dd &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/backup/mbr.img &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/sda &lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;512&lt;/span&gt; &lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On modern UEFI systems the partition table uses GPT instead of MBR, so this trick only applies to older BIOS installations. For GPT disks, use &lt;code&gt;sgdisk --backup&lt;/code&gt; and &lt;code&gt;sgdisk --load-backup&lt;/code&gt; from the &lt;code&gt;gdisk&lt;/code&gt; package.&lt;/p&gt;
&lt;h2 id="creating-an-empty-file-of-a-specific-size"&gt;Creating an Empty File of a Specific Size &lt;a class="headline-link" href="#creating-an-empty-file-of-a-specific-size" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;dd&lt;/code&gt; is often used to create test files of a known size. The &lt;code&gt;count&lt;/code&gt; option sets how many blocks to write, and &lt;code&gt;bs&lt;/code&gt; sets the block size:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dd &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/zero &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;testfile &lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1M &lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This creates a 100 MB file filled with zeros, useful for testing backups, simulating quota limits, or preparing a swap file. To create a file filled with random data instead, read from &lt;code&gt;/dev/urandom&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dd &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/urandom &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;random.bin &lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1M &lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Random data is slower to generate because the kernel has to produce the bytes, while &lt;code&gt;/dev/zero&lt;/code&gt; is effectively free.&lt;/p&gt;
&lt;h2 id="creating-a-swap-file"&gt;Creating a Swap File &lt;a class="headline-link" href="#creating-a-swap-file" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One practical use of the empty-file pattern is creating a &lt;a href="https://linuxize.com/post/how-to-add-swap-space-on-ubuntu-20-04/"&gt;swap file&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dd &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/zero &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/swapfile &lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1M &lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2048&lt;/span&gt; &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;progress
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chmod &lt;span class="m"&gt;600&lt;/span&gt; /swapfile
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mkswap /swapfile
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo swapon /swapfile&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;chmod 600&lt;/code&gt; step keeps the swap file readable only by root, which is required by &lt;code&gt;mkswap&lt;/code&gt; on most distros. After &lt;code&gt;swapon&lt;/code&gt;, the 2 GB swap file is active immediately. Add an entry to &lt;code&gt;/etc/fstab&lt;/code&gt; to make it permanent.&lt;/p&gt;
&lt;h2 id="wiping-a-disk"&gt;Wiping a Disk &lt;a class="headline-link" href="#wiping-a-disk" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To destroy data on a disk before disposing of it or repurposing it, overwrite the entire device with zeros:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dd &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/zero &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/sdb &lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4M &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;progress&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For a stronger wipe that makes recovery harder on traditional spinning disks, use random data:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dd &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/urandom &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/sdb &lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4M &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;progress&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On SSDs, a &lt;code&gt;dd&lt;/code&gt; wipe is not the right tool. SSDs remap blocks internally, so a full write does not guarantee every cell was overwritten. Use &lt;code&gt;blkdiscard&lt;/code&gt; or the drive vendor&amp;rsquo;s secure-erase utility instead.&lt;/p&gt;
&lt;h2 id="benchmarking-disk-write-speed"&gt;Benchmarking Disk Write Speed &lt;a class="headline-link" href="#benchmarking-disk-write-speed" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;dd&lt;/code&gt; is a quick way to measure sustained write throughput. Write a 1 GB file of zeros and let &lt;code&gt;dd&lt;/code&gt; report the rate:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dd &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/zero &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;tempfile &lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1M &lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1024&lt;/span&gt; &lt;span class="nv"&gt;oflag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;direct&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 3.1 s, 346 MB/s&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;oflag=direct&lt;/code&gt; flag bypasses the page cache, so the number reflects actual disk speed rather than memory throughput. For a read benchmark, drop the caches first and then read the file back:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo sh -c &lt;span class="s2"&gt;&amp;#34;sync &amp;amp;&amp;amp; echo 3 &amp;gt; /proc/sys/vm/drop_caches&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dd &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;tempfile &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/null &lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1M&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Remove the test file when you are done:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm tempfile&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For more detailed I/O profiling, tools like &lt;code&gt;fio&lt;/code&gt; and &lt;code&gt;ioping&lt;/code&gt; produce more accurate, repeatable results.&lt;/p&gt;
&lt;h2 id="showing-progress-on-a-running-dd"&gt;Showing Progress on a Running dd &lt;a class="headline-link" href="#showing-progress-on-a-running-dd" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you started &lt;code&gt;dd&lt;/code&gt; without &lt;code&gt;status=progress&lt;/code&gt;, you can still ask it to print a status line by sending the &lt;code&gt;USR1&lt;/code&gt; signal to its process. From another terminal, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo &lt;span class="nb"&gt;kill&lt;/span&gt; -USR1 &lt;span class="k"&gt;$(&lt;/span&gt;pidof dd&lt;span class="k"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;dd&lt;/code&gt; will respond by printing the number of bytes copied so far and its current rate, then keep running.&lt;/p&gt;
&lt;h2 id="common-options"&gt;Common Options &lt;a class="headline-link" href="#common-options" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A quick rundown of the options covered in this guide, plus a few more worth knowing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;if=FILE&lt;/code&gt; - Input file or device.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;of=FILE&lt;/code&gt; - Output file or device.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bs=N&lt;/code&gt; - Block size for both reads and writes (e.g., &lt;code&gt;4M&lt;/code&gt; for 4 MB).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ibs=N&lt;/code&gt; / &lt;code&gt;obs=N&lt;/code&gt; - Separate input and output block sizes.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;count=N&lt;/code&gt; - Number of input blocks to copy.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;skip=N&lt;/code&gt; - Skip N blocks at the start of the input.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;seek=N&lt;/code&gt; - Skip N blocks at the start of the output.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;status=progress&lt;/code&gt; - Print progress while copying.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;conv=noerror&lt;/code&gt; - Continue past read errors.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;conv=sync&lt;/code&gt; - Pad short reads with zeros to keep block alignment.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;oflag=direct&lt;/code&gt; - Bypass the kernel page cache on write.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;oflag=sync&lt;/code&gt; - Flush each write to the device before continuing.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo dd if=image.iso of=/dev/sdX bs=4M status=progress oflag=sync&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Write an ISO image to a USB drive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo dd if=/dev/sda of=/dev/sdb bs=64K conv=noerror,sync status=progress&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Clone one disk to another&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo dd if=/dev/sda1 of=/backup/sda1.img bs=4M status=progress&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Back up a partition to an image file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo dd if=/dev/sda bs=4M status=progress | gzip -c &amp;gt; disk.img.gz&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Compressed disk image backup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo dd if=/dev/sda of=/backup/mbr.img bs=512 count=1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Back up the MBR&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dd if=/dev/zero of=testfile bs=1M count=100&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a 100 MB file of zeros&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo dd if=/dev/zero of=/dev/sdX bs=4M status=progress&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Wipe a disk with zeros&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dd if=/dev/zero of=tempfile bs=1M count=1024 oflag=direct&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Benchmark disk write speed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo kill -USR1 $(pidof dd)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ask a running dd for its progress&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;dd: failed to open &amp;lsquo;/dev/sdX&amp;rsquo;: Permission denied&lt;/strong&gt;&lt;br&gt;
Writing to a block device requires root privileges. Prefix the command with &lt;code&gt;sudo&lt;/code&gt;. If you are already using &lt;code&gt;sudo&lt;/code&gt;, double-check that the device path is correct and that the device is not exclusively held by another process.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;dd: error writing &amp;lsquo;/dev/sdX&amp;rsquo;: No space left on device&lt;/strong&gt;&lt;br&gt;
The destination is smaller than the source. When cloning, the target disk or partition must be at least as large as the source. When writing an ISO, the USB drive must be larger than the ISO file.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The write is much slower than expected&lt;/strong&gt;&lt;br&gt;
The default block size of 512 bytes forces millions of tiny syscalls. Set &lt;code&gt;bs=4M&lt;/code&gt; or &lt;code&gt;bs=64K&lt;/code&gt; to speed things up. Also check whether other processes are doing heavy I/O on the same device.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The USB does not boot after writing the ISO&lt;/strong&gt;&lt;br&gt;
Verify that you wrote the image to the disk (&lt;code&gt;/dev/sdb&lt;/code&gt;), not a partition (&lt;code&gt;/dev/sdb1&lt;/code&gt;). Also confirm the ISO download with its SHA256 checksum; a truncated or corrupted download produces an unbootable stick.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;dd: invalid number: &amp;lsquo;4M&amp;rsquo;&lt;/strong&gt;&lt;br&gt;
Older or minimal systems may ship a &lt;code&gt;dd&lt;/code&gt; that does not accept the &lt;code&gt;M&lt;/code&gt;, &lt;code&gt;G&lt;/code&gt;, or &lt;code&gt;K&lt;/code&gt; suffixes. On those systems, spell out the block size in bytes (&lt;code&gt;bs=4194304&lt;/code&gt; for 4 MB), or install GNU coreutils.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What does dd stand for?&lt;/strong&gt;&lt;br&gt;
The name comes from the IBM Job Control Language statement &amp;ldquo;Data Definition.&amp;rdquo; Because of how often the command is used to overwrite disks by mistake, many Linux users jokingly call it &amp;ldquo;disk destroyer.&amp;rdquo; Either way, the behavior is the same: it copies bytes from input to output without touching the filesystem layer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is dd faster than cp for copying large files?&lt;/strong&gt;&lt;br&gt;
For regular files on a normal filesystem, &lt;code&gt;cp&lt;/code&gt; is usually just as fast and safer to use. &lt;code&gt;dd&lt;/code&gt; only wins when you are copying raw devices, working with exact byte offsets, or deliberately limiting how much data is copied with &lt;code&gt;count&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I use dd on an SSD without damaging it?&lt;/strong&gt;&lt;br&gt;
Reading and writing with &lt;code&gt;dd&lt;/code&gt; is fine. The concern with SSDs is full-disk wipes: a single pass of zeros is enough to erase visible data, but repeated full-drive writes wear out the flash cells. For secure erase, use &lt;code&gt;blkdiscard&lt;/code&gt; or the drive&amp;rsquo;s built-in secure-erase command.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I see how much data dd has copied?&lt;/strong&gt;&lt;br&gt;
Add &lt;code&gt;status=progress&lt;/code&gt; to the command, or send the running process the &lt;code&gt;USR1&lt;/code&gt; signal with &lt;code&gt;sudo kill -USR1 $(pidof dd)&lt;/code&gt;. Both methods print the byte count and current throughput without interrupting the copy.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why use bs=4M instead of the default?&lt;/strong&gt;&lt;br&gt;
The default block size of 512 bytes means &lt;code&gt;dd&lt;/code&gt; issues a separate read and write for every 512 bytes of data. Larger block sizes such as 4 MB dramatically reduce syscall overhead and let the kernel fill the disk pipeline efficiently, often cutting copy times by a factor of ten.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;dd&lt;/code&gt; is one of the most direct tools in the Linux toolbox. It copies bytes, no more and no less, between any two files or devices. That power makes it indispensable for flashing installers, cloning disks, and building image backups, and the same power makes it unforgiving if you point it at the wrong target.&lt;/p&gt;
&lt;p&gt;For related disk tools, see the guides on &lt;a href="https://linuxize.com/post/fdisk-command-in-linux/"&gt;&lt;code&gt;fdisk&lt;/code&gt;&lt;/a&gt;
for partitioning and &lt;a href="https://linuxize.com/post/how-to-check-disk-space-in-linux-using-the-df-command/"&gt;&lt;code&gt;df&lt;/code&gt;&lt;/a&gt;
for checking free space.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/dd-command-in-linux/featured_hu_ad057e3aa5d007b9.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>How to Install and Use uv: Fast Python Package Manager</title><link>https://linuxize.com/post/how-to-install-and-use-uv/</link><pubDate>Sat, 09 May 2026 10:35:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-install-and-use-uv/</guid><category>python</category><category>linux commands</category><description>uv is a fast Python package and project manager written in Rust. This guide covers installation on Linux, creating projects, adding dependencies, managing virtual environments, and installing Python versions with uv.</description><content:encoded>&lt;p&gt;If you have worked with Python for a while, you have probably juggled &lt;code&gt;pip&lt;/code&gt;, &lt;code&gt;virtualenv&lt;/code&gt;, &lt;code&gt;pip-tools&lt;/code&gt;, &lt;code&gt;pipx&lt;/code&gt;, and &lt;code&gt;pyenv&lt;/code&gt; just to keep a few projects running. Each tool does one thing, and wiring them together is slow and fragile. &lt;code&gt;uv&lt;/code&gt; is a single binary that replaces all of them. It is written in Rust, published by Astral (the team behind &lt;code&gt;ruff&lt;/code&gt;), and is typically ten to a hundred times faster than &lt;code&gt;pip&lt;/code&gt; for common workflows.&lt;/p&gt;
&lt;p&gt;This guide explains how to install &lt;code&gt;uv&lt;/code&gt; on Linux, create and manage Python projects with it, add dependencies, work with virtual environments, and install specific Python versions.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uv init my-project&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a new project with &lt;code&gt;pyproject.toml&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uv add requests&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Add a dependency and update the lockfile&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uv add --dev pytest&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Add a development dependency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uv remove requests&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Remove a dependency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uv sync&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Install dependencies from the lockfile&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uv lock&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Update the lockfile&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uv run script.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run a command in the project environment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uv venv&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a virtual environment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uv pip install requests&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pip-compatible install interface&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uv python install 3.12&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Install a specific Python version&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uv python list&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List installed and available Python versions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uv tool install ruff&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Install a CLI tool globally&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uvx ruff check .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run a tool without installing it permanently&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="installing-uv"&gt;Installing uv &lt;a class="headline-link" href="#installing-uv" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The recommended install path on Linux is the standalone script from Astral. It downloads a prebuilt binary, places it in &lt;code&gt;~/.local/bin&lt;/code&gt;, and does not require Python to be installed first:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -LsSf https://astral.sh/uv/install.sh &lt;span class="p"&gt;|&lt;/span&gt; sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The script prints where it put the binary and whether it updated your shell rc file. Reload your shell or run &lt;code&gt;source ~/.bashrc&lt;/code&gt; so the new &lt;code&gt;PATH&lt;/code&gt; takes effect, then verify the install:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv --version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;uv 0.11.11&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you prefer to install from a package manager, &lt;code&gt;uv&lt;/code&gt; is also available through &lt;code&gt;pip&lt;/code&gt;, &lt;code&gt;pipx&lt;/code&gt;, and Homebrew:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install uv&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pipx install uv&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;brew install uv&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Ubuntu, Debian, and Derivatives, &lt;code&gt;pip&lt;/code&gt; may refuse a system-wide install because the Python environment is marked as externally managed. In that case, use &lt;code&gt;pipx install uv&lt;/code&gt; or the standalone installer.&lt;/p&gt;
&lt;p&gt;If you installed &lt;code&gt;uv&lt;/code&gt; with the standalone installer, update it to the latest release with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv self update&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="creating-a-project"&gt;Creating a Project &lt;a class="headline-link" href="#creating-a-project" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;uv init&lt;/code&gt; scaffolds a new project with a &lt;code&gt;pyproject.toml&lt;/code&gt;, a &lt;code&gt;README.md&lt;/code&gt;, a &lt;code&gt;.python-version&lt;/code&gt; file, and a starter module:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv init my-project
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; my-project&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Initialized project `my-project`&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The generated &lt;code&gt;pyproject.toml&lt;/code&gt; looks like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="toml"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;pyproject.toml&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-orange-100 text-orange-700 dark:bg-orange-900 dark:text-orange-300"&gt;toml&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;my-project&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;0.1.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Add your description here&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;readme&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;README.md&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;requires-python&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;gt;=3.12&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;dependencies&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;uv&lt;/code&gt; has not created a virtual environment yet. That happens the first time you add a dependency or run a command in the project.&lt;/p&gt;
&lt;h2 id="adding-and-removing-dependencies"&gt;Adding and Removing Dependencies &lt;a class="headline-link" href="#adding-and-removing-dependencies" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To add a package, use &lt;code&gt;uv add&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv add requests&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Resolved 5 packages in 320ms
Installed 5 packages in 45ms
+ certifi==2025.1.31
+ charset-normalizer==3.4.1
+ idna==3.10
+ requests==2.32.3
+ urllib3==2.3.0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;On the first run, &lt;code&gt;uv&lt;/code&gt; creates a &lt;code&gt;.venv&lt;/code&gt; directory in the project root, resolves the dependency graph, writes a &lt;code&gt;uv.lock&lt;/code&gt; file that pins every package and its transitive dependencies, and installs everything into the venv. The &lt;code&gt;requests&lt;/code&gt; line is also added to &lt;code&gt;pyproject.toml&lt;/code&gt; under &lt;code&gt;dependencies&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Development-only dependencies go into a separate group with &lt;code&gt;--dev&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv add --dev pytest ruff&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;They are recorded under a &lt;code&gt;dev&lt;/code&gt; dependency group in &lt;code&gt;pyproject.toml&lt;/code&gt; and are installed into the same venv, but they are excluded when your project is published or installed as a library.&lt;/p&gt;
&lt;p&gt;Remove a dependency with &lt;code&gt;uv remove&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv remove requests&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;uv&lt;/code&gt; updates &lt;code&gt;pyproject.toml&lt;/code&gt;, updates &lt;code&gt;uv.lock&lt;/code&gt;, and uninstalls the package along with any dependencies that are no longer needed.&lt;/p&gt;
&lt;h2 id="running-code-in-the-project-environment"&gt;Running Code in the Project Environment &lt;a class="headline-link" href="#running-code-in-the-project-environment" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You do not have to activate the virtual environment manually. &lt;code&gt;uv run&lt;/code&gt; executes a command inside the project venv and syncs dependencies first if needed:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv run python main.py&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv run pytest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Scripts declared in &lt;code&gt;pyproject.toml&lt;/code&gt; under &lt;code&gt;[project.scripts]&lt;/code&gt; are also available:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv run my-command&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you prefer the classic workflow, activate the venv yourself:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;python main.py&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Either approach works, but &lt;code&gt;uv run&lt;/code&gt; has the advantage of keeping the environment in sync with &lt;code&gt;uv.lock&lt;/code&gt; every time you invoke it.&lt;/p&gt;
&lt;h2 id="syncing-and-reproducing-an-environment"&gt;Syncing and Reproducing an Environment &lt;a class="headline-link" href="#syncing-and-reproducing-an-environment" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When you clone a project that uses &lt;code&gt;uv&lt;/code&gt;, run &lt;code&gt;uv sync&lt;/code&gt; to install exactly the versions pinned in &lt;code&gt;uv.lock&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv sync&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Resolved 12 packages in 5ms
Installed 12 packages in 110ms&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;uv sync&lt;/code&gt; is deterministic: given the same &lt;code&gt;uv.lock&lt;/code&gt;, it produces the same environment on any machine. This is the command to run in CI, in Docker builds, and on every fresh checkout.&lt;/p&gt;
&lt;p&gt;If &lt;code&gt;pyproject.toml&lt;/code&gt; changes but the lockfile is out of date, refresh the lock with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv lock&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Use &lt;code&gt;uv lock --upgrade&lt;/code&gt; to bump every dependency to the latest version allowed by the version constraints in &lt;code&gt;pyproject.toml&lt;/code&gt;, and &lt;code&gt;uv lock --upgrade-package requests&lt;/code&gt; to bump a single package.&lt;/p&gt;
&lt;h2 id="working-with-virtual-environments-directly"&gt;Working with Virtual Environments Directly &lt;a class="headline-link" href="#working-with-virtual-environments-directly" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;uv&lt;/code&gt; can also be used as a faster drop-in for &lt;code&gt;virtualenv&lt;/code&gt;. To create a standalone venv in the current directory:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv venv&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Using Python 3.12.8
Creating virtual environment at: .venv
Activate with: source .venv/bin/activate&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Specify a Python version with &lt;code&gt;--python&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv venv --python 3.11&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Specify a different path:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv venv /tmp/myenv&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Once the venv exists, use &lt;code&gt;uv pip&lt;/code&gt; as a fast replacement for the regular &lt;code&gt;pip&lt;/code&gt; commands:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv pip install requests
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv pip install -r requirements.txt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv pip freeze
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv pip list&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;uv pip&lt;/code&gt; interface is intentionally compatible with &lt;code&gt;pip&lt;/code&gt;, which makes it easy to adopt &lt;code&gt;uv&lt;/code&gt; in existing projects without restructuring them as &lt;code&gt;pyproject.toml&lt;/code&gt;-based projects.&lt;/p&gt;
&lt;p&gt;For a refresher on classic virtual environments, see the guide on &lt;a href="https://linuxize.com/post/python-virtual-environments/"&gt;Python virtual environments&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="installing-and-managing-python-versions"&gt;Installing and Managing Python Versions &lt;a class="headline-link" href="#installing-and-managing-python-versions" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;uv&lt;/code&gt; can download and manage Python interpreters without touching your system Python. List the versions available and installed:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv python list&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Install a specific version:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv python install 3.12&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv python install 3.11 3.13&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The downloaded interpreters live under &lt;code&gt;~/.local/share/uv/python/&lt;/code&gt; and are independent of the system package manager. To use a specific version in a project, set it in the &lt;code&gt;.python-version&lt;/code&gt; file or pass &lt;code&gt;--python&lt;/code&gt; when creating the venv:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv venv --python 3.13&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When &lt;code&gt;uv run&lt;/code&gt; starts a project, it reads &lt;code&gt;.python-version&lt;/code&gt; and the &lt;code&gt;requires-python&lt;/code&gt; constraint in &lt;code&gt;pyproject.toml&lt;/code&gt;, then picks or downloads a matching interpreter automatically.&lt;/p&gt;
&lt;h2 id="installing-cli-tools"&gt;Installing CLI Tools &lt;a class="headline-link" href="#installing-cli-tools" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;uv&lt;/code&gt; ships with a tool manager similar to &lt;code&gt;pipx&lt;/code&gt;. It installs Python-based CLIs in isolated environments so they do not pollute your system Python:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv tool install ruff&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Resolved 1 package in 80ms
Installed 1 package in 12ms
+ ruff==0.9.2
Installed 1 executable: ruff&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;ruff&lt;/code&gt; binary is now on your &lt;code&gt;PATH&lt;/code&gt;. List, upgrade, or remove tools:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv tool list
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv tool upgrade ruff
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv tool uninstall ruff&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To run a tool without installing it permanently, use &lt;code&gt;uvx&lt;/code&gt; (an alias for &lt;code&gt;uv tool run&lt;/code&gt;):&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uvx ruff check .&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;uvx&lt;/code&gt; downloads the tool into a cached environment, runs it, and reuses the cache on subsequent invocations. This is the fastest way to try a CLI without making it permanent.&lt;/p&gt;
&lt;h2 id="running-single-file-scripts"&gt;Running Single-File Scripts &lt;a class="headline-link" href="#running-single-file-scripts" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A Python script can declare its dependencies inline with a PEP 723 comment block. &lt;code&gt;uv run&lt;/code&gt; reads that block and sets up an ephemeral environment before executing the script:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="py"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;script.py&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-300"&gt;py&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# /// script&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# requires-python = &amp;#34;&amp;gt;=3.12&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# dependencies = [&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# &amp;#34;requests&amp;#34;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ///&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;requests&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://api.github.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Run the script with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv run script.py&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;uv&lt;/code&gt; creates a temporary venv, installs &lt;code&gt;requests&lt;/code&gt;, runs the script, and keeps the environment in a cache for next time. This pattern is useful for small utilities and one-off automation where a full project is overkill.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;uv: command not found after install&lt;/strong&gt;&lt;br&gt;
The installer places the binary in &lt;code&gt;~/.local/bin&lt;/code&gt;, which may not be on your &lt;code&gt;PATH&lt;/code&gt;. Add it in your shell rc file: &lt;code&gt;export PATH=&amp;quot;$HOME/.local/bin:$PATH&amp;quot;&lt;/code&gt;, then reload the shell. Verify with &lt;code&gt;which uv&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Installation fails with &amp;ldquo;error: externally-managed-environment&amp;rdquo;&lt;/strong&gt;&lt;br&gt;
This message comes from system &lt;code&gt;pip&lt;/code&gt;, not from &lt;code&gt;uv&lt;/code&gt;. Use &lt;code&gt;pipx install uv&lt;/code&gt; or the standalone installer instead. Installing Python packages into the system Python is discouraged on modern Ubuntu and Debian releases.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;uv sync installs different versions than expected&lt;/strong&gt;&lt;br&gt;
Check that &lt;code&gt;uv.lock&lt;/code&gt; is committed to your repository. Without the lockfile, &lt;code&gt;uv sync&lt;/code&gt; falls back to resolving from &lt;code&gt;pyproject.toml&lt;/code&gt; and may pick newer versions. Commit &lt;code&gt;uv.lock&lt;/code&gt; to keep environments reproducible across machines.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;uv cannot find a suitable Python interpreter&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;uv python install 3.12&lt;/code&gt; (or whichever version your project requires) to let &lt;code&gt;uv&lt;/code&gt; download a matching interpreter. The &lt;code&gt;requires-python&lt;/code&gt; field in &lt;code&gt;pyproject.toml&lt;/code&gt; tells &lt;code&gt;uv&lt;/code&gt; which versions are acceptable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Permission denied when installing to the system&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;uv&lt;/code&gt; does not need root. If a command prompts for &lt;code&gt;sudo&lt;/code&gt;, the destination path is wrong. Use a project virtual environment or &lt;code&gt;uv tool install&lt;/code&gt; for CLIs instead of writing to system directories.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;How is uv different from pip?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;pip&lt;/code&gt; installs packages into an existing Python environment. &lt;code&gt;uv&lt;/code&gt; is a full project manager: it creates and manages virtual environments, locks dependencies, installs Python interpreters, and runs scripts and tools. &lt;code&gt;uv pip&lt;/code&gt; also provides a drop-in pip-compatible command for teams that want just the speed without adopting the full workflow.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does uv replace Poetry or Hatch?&lt;/strong&gt;&lt;br&gt;
For most projects, yes. &lt;code&gt;uv&lt;/code&gt; reads the standard &lt;code&gt;pyproject.toml&lt;/code&gt; format used by Poetry and Hatch, manages lockfiles, and handles dependency groups. If you depend on specific features of Poetry plugins or Hatch build hooks, evaluate those needs before migrating.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is uv compatible with existing requirements.txt workflows?&lt;/strong&gt;&lt;br&gt;
Yes. &lt;code&gt;uv pip install -r requirements.txt&lt;/code&gt; works as a faster replacement for &lt;code&gt;pip install -r&lt;/code&gt;, and &lt;code&gt;uv pip compile&lt;/code&gt; generates a pinned requirements file from your unpinned input, similar to &lt;code&gt;pip-compile&lt;/code&gt; from &lt;code&gt;pip-tools&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I use uv with Docker?&lt;/strong&gt;&lt;br&gt;
Yes, and it is a good fit. The recommended pattern is to copy &lt;code&gt;pyproject.toml&lt;/code&gt; and &lt;code&gt;uv.lock&lt;/code&gt; first, run &lt;code&gt;uv sync --frozen --no-install-project&lt;/code&gt; to install dependencies, then copy the rest of the source and run &lt;code&gt;uv sync --frozen&lt;/code&gt;. This keeps the dependency layer cached across builds.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where does uv store downloaded interpreters and package cache?&lt;/strong&gt;&lt;br&gt;
Interpreters go under &lt;code&gt;~/.local/share/uv/python/&lt;/code&gt; and the package cache lives in &lt;code&gt;~/.cache/uv/&lt;/code&gt;. Both paths respect the XDG environment variables, so you can override them by setting &lt;code&gt;XDG_DATA_HOME&lt;/code&gt; and &lt;code&gt;XDG_CACHE_HOME&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;uv&lt;/code&gt; rolls together the jobs that previously required &lt;code&gt;pip&lt;/code&gt;, &lt;code&gt;virtualenv&lt;/code&gt;, &lt;code&gt;pip-tools&lt;/code&gt;, &lt;code&gt;pipx&lt;/code&gt;, and &lt;code&gt;pyenv&lt;/code&gt; into one fast binary. The speed is the headline feature, but the real payoff is a single, consistent workflow for projects, tools, scripts, and Python versions.&lt;/p&gt;
&lt;p&gt;For related Python tooling on Linux, see the guide on &lt;a href="https://linuxize.com/post/how-to-install-python-on-ubuntu-24-04/"&gt;installing Python on Ubuntu 24.04&lt;/a&gt;
and the guide on &lt;a href="https://linuxize.com/post/python-virtual-environments/"&gt;Python virtual environments&lt;/a&gt;
.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-install-and-use-uv/featured_hu_d8faa6ef84c6292f.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>netstat Command in Linux: Network Connections and Statistics</title><link>https://linuxize.com/post/netstat-command-in-linux/</link><pubDate>Sat, 02 May 2026 09:00:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/netstat-command-in-linux/</guid><category>linux commands</category><description>Use the netstat command to list network connections, listening ports, routing tables, interface counters, and TCP states on Linux.</description><content:encoded>&lt;p&gt;When something on a server is holding port 80, a connection is refusing to close, or a service is not reachable from the outside, the first question is almost always the same: what is actually listening, and who is talking to whom. For years, the answer on Linux was the &lt;code&gt;netstat&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;netstat&lt;/code&gt; is part of the classic &lt;code&gt;net-tools&lt;/code&gt; package and prints network connections, listening ports, routing tables, interface counters, and per-protocol statistics. It has been deprecated in favor of &lt;a href="https://linuxize.com/post/ss-command-in-linux/"&gt;&lt;code&gt;ss&lt;/code&gt;&lt;/a&gt;
and &lt;a href="https://linuxize.com/post/linux-ip-command/"&gt;&lt;code&gt;ip&lt;/code&gt;&lt;/a&gt;
, but it is still installed on many systems and the tool many sysadmins reach for first. This guide explains how to read its output and which flags cover the cases you run into day to day.&lt;/p&gt;
&lt;h2 id="install-netstat"&gt;Install netstat &lt;a class="headline-link" href="#install-netstat" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;On most modern distributions, &lt;code&gt;net-tools&lt;/code&gt; is not installed by default. If &lt;code&gt;netstat&lt;/code&gt; is not available, install it with your package manager.&lt;/p&gt;
&lt;p&gt;On Ubuntu, Debian, and Derivatives:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install net-tools&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Fedora, RHEL, and Derivatives:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install net-tools&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Once the package is installed, verify the binary is on your path:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;netstat --version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="netstat-syntax"&gt;netstat Syntax &lt;a class="headline-link" href="#netstat-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The general form of the command is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;netstat [OPTIONS]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Run without options, &lt;code&gt;netstat&lt;/code&gt; prints a list of open non-listening sockets, which is rarely what you want. In practice, you almost always pass a combination of flags that describe what kind of sockets you care about (TCP, UDP, Unix), what state they are in, and how you want the output formatted.&lt;/p&gt;
&lt;h2 id="list-all-connections"&gt;List All Connections &lt;a class="headline-link" href="#list-all-connections" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To list every connection, both listening and established, use the &lt;code&gt;-a&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo netstat -a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output is divided into two parts. The top lists Internet sockets with columns for protocol, receive and send queue sizes, local and foreign address, and state. The bottom lists Unix domain sockets used for local inter-process communication.&lt;/p&gt;
&lt;p&gt;Running &lt;code&gt;netstat&lt;/code&gt; with &lt;code&gt;sudo&lt;/code&gt; is recommended because without it, the command cannot read socket ownership for processes that belong to other users.&lt;/p&gt;
&lt;h2 id="show-tcp-and-udp-connections"&gt;Show TCP and UDP Connections &lt;a class="headline-link" href="#show-tcp-and-udp-connections" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;-t&lt;/code&gt; and &lt;code&gt;-u&lt;/code&gt; flags filter the output by protocol. To show only TCP connections:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo netstat -at&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To show only UDP connections:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo netstat -au&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can combine both flags to get TCP and UDP together:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo netstat -atu&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="show-listening-ports"&gt;Show Listening Ports &lt;a class="headline-link" href="#show-listening-ports" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When you want to know which services are accepting new connections, use the &lt;code&gt;-l&lt;/code&gt; option. For TCP, it restricts the output to sockets in the &lt;code&gt;LISTEN&lt;/code&gt; state. UDP does not use the same connection states, but UDP sockets that are ready to receive traffic are still shown.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo netstat -tuln&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The combined flags read as: show TCP (&lt;code&gt;-t&lt;/code&gt;) and UDP (&lt;code&gt;-u&lt;/code&gt;) sockets that are listening (&lt;code&gt;-l&lt;/code&gt;), with numeric addresses and ports (&lt;code&gt;-n&lt;/code&gt;). The output looks similar to this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN
tcp6 0 0 :::80 :::* LISTEN
udp 0 0 0.0.0.0:68 0.0.0.0:*&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;From the output, we can see that SSH is listening on all interfaces on port 22, MySQL is bound to localhost only on port 3306, and a web server is listening on port 80 over IPv6.&lt;/p&gt;
&lt;h2 id="show-the-process-using-a-port"&gt;Show the Process Using a Port &lt;a class="headline-link" href="#show-the-process-using-a-port" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To find out which program owns a socket, add the &lt;code&gt;-p&lt;/code&gt; option. It prints the PID and the process name next to each connection:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo netstat -tulnp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 812/sshd
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 1034/mysqld
tcp6 0 0 :::80 :::* LISTEN 1591/nginx: master&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;PID/Program name&lt;/code&gt; column ties each listening port to a process. This is the quickest way to find out which service is holding a port when you get an &lt;code&gt;Address already in use&lt;/code&gt; error.&lt;/p&gt;
&lt;p&gt;To check one specific port, pipe the output to &lt;a href="https://linuxize.com/post/how-to-use-grep-command-to-search-files-in-linux/"&gt;&lt;code&gt;grep&lt;/code&gt;&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo netstat -tulnp &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="s1"&gt;&amp;#39;:80&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the command prints a row, a process is listening on port &lt;code&gt;80&lt;/code&gt;. If it prints nothing, no TCP or UDP listener matched that port on the local system.&lt;/p&gt;
&lt;h2 id="show-numeric-output"&gt;Show Numeric Output &lt;a class="headline-link" href="#show-numeric-output" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;netstat&lt;/code&gt; resolves IP addresses to hostnames and port numbers to service names (for example, &lt;code&gt;22&lt;/code&gt; becomes &lt;code&gt;ssh&lt;/code&gt;). On a busy system, this can be slow because each address needs a DNS lookup.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;-n&lt;/code&gt; option disables name resolution and prints raw numbers:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo netstat -n&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Numeric output is also easier to pipe into other tools such as &lt;code&gt;grep&lt;/code&gt; or &lt;code&gt;awk&lt;/code&gt;, because the field values are predictable.&lt;/p&gt;
&lt;h2 id="continuous-monitoring"&gt;Continuous Monitoring &lt;a class="headline-link" href="#continuous-monitoring" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;-c&lt;/code&gt; option tells &lt;code&gt;netstat&lt;/code&gt; to print the output every second until you stop it with &lt;code&gt;Ctrl+C&lt;/code&gt;. It is useful when you want to watch a connection appear, change state, and close:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo netstat -atnc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Each iteration prints the full table again, so it is best used together with a filter such as &lt;code&gt;grep&lt;/code&gt; to isolate a single connection.&lt;/p&gt;
&lt;h2 id="show-tcp-connection-states"&gt;Show TCP Connection States &lt;a class="headline-link" href="#show-tcp-connection-states" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;TCP connections move through states such as &lt;code&gt;ESTABLISHED&lt;/code&gt;, &lt;code&gt;LISTEN&lt;/code&gt;, &lt;code&gt;TIME_WAIT&lt;/code&gt;, and &lt;code&gt;CLOSE_WAIT&lt;/code&gt;. To show active TCP sockets with numeric addresses, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo netstat -ant&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;State&lt;/code&gt; column tells you where each connection is in the TCP lifecycle:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 192.168.1.10:22 192.168.1.5:52710 ESTABLISHED
tcp 0 0 192.168.1.10:80 203.0.113.25:51422 TIME_WAIT
tcp 0 0 127.0.0.1:3306 127.0.0.1:41834 CLOSE_WAIT&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;ESTABLISHED&lt;/code&gt; means the connection is active. &lt;code&gt;TIME_WAIT&lt;/code&gt; is normal after a connection closes. A large number of &lt;code&gt;CLOSE_WAIT&lt;/code&gt; entries can mean the local application is not closing sockets correctly.&lt;/p&gt;
&lt;p&gt;To show only established TCP connections, filter the output:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo netstat -ant &lt;span class="p"&gt;|&lt;/span&gt; grep ESTABLISHED&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For new troubleshooting work, &lt;a href="https://linuxize.com/post/ss-command-in-linux/"&gt;&lt;code&gt;ss&lt;/code&gt;&lt;/a&gt;
gives better built-in state filters, such as &lt;code&gt;ss -tn state established&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="count-connections"&gt;Count Connections &lt;a class="headline-link" href="#count-connections" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;On busy web servers, you may want a quick count instead of a full connection table. To count all current TCP connections that involve port &lt;code&gt;80&lt;/code&gt;, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo netstat -ant &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="s1"&gt;&amp;#39;:80&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; wc -l&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To count only established connections on port &lt;code&gt;80&lt;/code&gt;, add the TCP state to the filter:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo netstat -ant &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="s1"&gt;&amp;#39;:80&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; grep ESTABLISHED &lt;span class="p"&gt;|&lt;/span&gt; wc -l&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;These counts are useful as a quick signal, but they are not a replacement for application metrics. The number can change while the pipeline is running, especially on high-traffic systems.&lt;/p&gt;
&lt;h2 id="display-the-routing-table"&gt;Display the Routing Table &lt;a class="headline-link" href="#display-the-routing-table" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To print the kernel IP routing table, use the &lt;code&gt;-r&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;netstat -rn&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first row is the default route, which sends all traffic not matching another rule to &lt;code&gt;192.168.1.1&lt;/code&gt;. The &lt;code&gt;ip route&lt;/code&gt; command from &lt;a href="https://linuxize.com/post/linux-ip-command/"&gt;&lt;code&gt;ip&lt;/code&gt;&lt;/a&gt;
is the modern equivalent and is what you should use on new systems.&lt;/p&gt;
&lt;h2 id="interface-statistics"&gt;Interface Statistics &lt;a class="headline-link" href="#interface-statistics" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;-i&lt;/code&gt; option prints a per-interface summary that includes received and transmitted packets, errors, drops, and the MTU:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;netstat -i&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Kernel Interface table
Iface MTU RX-OK RX-ERR RX-DRP TX-OK TX-ERR TX-DRP Flg
eth0 1500 2345678 0 12 1987654 0 0 BMRU
lo 65536 55432 0 0 55432 0 0 LRU&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A growing &lt;code&gt;RX-ERR&lt;/code&gt; or &lt;code&gt;TX-ERR&lt;/code&gt; column is a hint that you have a cabling, duplex, or driver issue on that interface.&lt;/p&gt;
&lt;h2 id="protocol-statistics"&gt;Protocol Statistics &lt;a class="headline-link" href="#protocol-statistics" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To print a summary of statistics for each protocol, use &lt;code&gt;-s&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;netstat -s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output is long and grouped by protocol (&lt;code&gt;Ip&lt;/code&gt;, &lt;code&gt;Tcp&lt;/code&gt;, &lt;code&gt;Udp&lt;/code&gt;, and so on). It includes counters such as total packets received, segments retransmitted, and connection resets. You can narrow the output to a single protocol by combining &lt;code&gt;-s&lt;/code&gt; with &lt;code&gt;-t&lt;/code&gt; or &lt;code&gt;-u&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;netstat -st&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="netstat-vs-ss"&gt;netstat vs ss &lt;a class="headline-link" href="#netstat-vs-ss" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;On modern Linux distributions, &lt;code&gt;ss&lt;/code&gt; is the recommended replacement for &lt;code&gt;netstat&lt;/code&gt;. It is faster and reads information directly from the kernel through Netlink, with richer filter support. The &lt;code&gt;ip&lt;/code&gt; command replaces the routing and interface parts of &lt;code&gt;netstat&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;A few common translations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;netstat -tuln&lt;/code&gt; is equivalent to &lt;code&gt;ss -tuln&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;netstat -tulnp&lt;/code&gt; is equivalent to &lt;code&gt;sudo ss -tulnp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;netstat -s&lt;/code&gt; maps to &lt;code&gt;ss -s&lt;/code&gt; (a much shorter summary)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;netstat -i&lt;/code&gt; maps to &lt;code&gt;ip -s link&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;netstat -r&lt;/code&gt; maps to &lt;code&gt;ip route&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For a full walkthrough of the replacement tool, see the guide on the &lt;a href="https://linuxize.com/post/ss-command-in-linux/"&gt;ss command&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/netstat/"&gt;netstat cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;netstat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show active non-listening sockets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo netstat -a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show all listening and non-listening sockets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo netstat -at&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show all TCP sockets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo netstat -au&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show all UDP sockets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo netstat -tuln&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show TCP and UDP listening sockets with numeric output&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo netstat -tulnp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show listening sockets with PID and process name&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo netstat -tulnp | grep ':80'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Find the process listening on port 80&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo netstat -ant&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show all TCP sockets with numeric addresses&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo netstat -ant | grep ESTABLISHED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show established TCP connections&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo netstat -ant | grep ':80' | wc -l&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Count TCP connections involving port 80&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sudo netstat -atnc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Refresh TCP connection output every second&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;netstat -rn&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show the routing table with numeric addresses&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;netstat -i&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show interface statistics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;netstat -s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show protocol statistics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;netstat -st&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show TCP protocol statistics&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;netstat: command not found&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The &lt;code&gt;net-tools&lt;/code&gt; package is not installed. Install it with your package manager, or use &lt;code&gt;ss&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;No &lt;code&gt;PID/Program name&lt;/code&gt; column shown&lt;/strong&gt;&lt;br&gt;
You need to run the command with &lt;code&gt;sudo&lt;/code&gt;. Without root privileges, &lt;code&gt;netstat&lt;/code&gt; cannot read process information for sockets owned by other users.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Output is slow or hangs&lt;/strong&gt;&lt;br&gt;
DNS resolution is slow or failing. Add the &lt;code&gt;-n&lt;/code&gt; option to disable name lookups and print numeric addresses and ports.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A port shows up as &lt;code&gt;LISTEN&lt;/code&gt; on &lt;code&gt;::&lt;/code&gt; but not on &lt;code&gt;0.0.0.0&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The service is listening on the IPv6 wildcard address. On systems with dual-stack enabled, this accepts IPv4 traffic too. Check your IPv6 configuration if only IPv4 clients are failing.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Is netstat deprecated?&lt;/strong&gt;&lt;br&gt;
Yes. The &lt;code&gt;net-tools&lt;/code&gt; suite, which includes &lt;code&gt;netstat&lt;/code&gt;, &lt;code&gt;ifconfig&lt;/code&gt;, and &lt;code&gt;route&lt;/code&gt;, has been deprecated for years in favor of the &lt;code&gt;iproute2&lt;/code&gt; tools &lt;code&gt;ss&lt;/code&gt; and &lt;code&gt;ip&lt;/code&gt;. It is still functional and still shipped by most distributions, but new scripts should target &lt;code&gt;ss&lt;/code&gt; and &lt;code&gt;ip&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between netstat on Linux and Windows?&lt;/strong&gt;&lt;br&gt;
The command name is the same, and the general idea is the same, but the flags are different. This guide covers the Linux version from &lt;code&gt;net-tools&lt;/code&gt;. On Windows, the closest equivalents to &lt;code&gt;netstat -tulnp&lt;/code&gt; are &lt;code&gt;netstat -ano&lt;/code&gt; and &lt;code&gt;Get-NetTCPConnection&lt;/code&gt; in PowerShell.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I find what process is using a specific port?&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;sudo netstat -tulnp | grep ':PORT'&lt;/code&gt;, replacing &lt;code&gt;PORT&lt;/code&gt; with the port number. The last column shows the PID and program name. With &lt;code&gt;ss&lt;/code&gt;, the same query is &lt;code&gt;sudo ss -tulnp 'sport = :PORT'&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why is a port still &lt;code&gt;TIME_WAIT&lt;/code&gt; after I stopped the service?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;TIME_WAIT&lt;/code&gt; is a normal TCP state that keeps a closed connection around for a short period so late packets can be handled safely. The kernel clears these entries automatically, usually within one or two minutes.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;netstat&lt;/code&gt; remains useful when you need to inspect network connections on systems that still have &lt;code&gt;net-tools&lt;/code&gt; installed. For new scripts and current Linux systems, prefer &lt;code&gt;ss&lt;/code&gt; for sockets and &lt;code&gt;ip&lt;/code&gt; for routes and interface statistics.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/netstat-command-in-linux/featured_hu_dedabc9a736c5934.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>git branch Command: Create, List, and Delete Branches</title><link>https://linuxize.com/post/git-branch-command/</link><pubDate>Wed, 22 Apr 2026 22:12:53 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/git-branch-command/</guid><category>git</category><category>linux commands</category><description>The git branch command creates, lists, renames, and deletes Git branches. This guide explains the full command reference with practical examples for local and remote branches, merged filters, and tracking upstream branches.</description><content:encoded>&lt;p&gt;Branches are how Git keeps your work separated from the main line of development. A new branch lets you experiment, fix a bug, or build a feature without touching what is already shipped, and a merge brings the work back together when it is ready. The tool that creates, lists, and removes those branches is &lt;code&gt;git branch&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This guide explains how to use &lt;code&gt;git branch&lt;/code&gt; to manage local and remote branches, filter by merged or upstream state, rename branches, and clean up stale ones.&lt;/p&gt;
&lt;h2 id="git-branch-syntax"&gt;git branch Syntax &lt;a class="headline-link" href="#git-branch-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The general form of the command is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch [OPTIONS] [BRANCH] [START_POINT]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;With no arguments, &lt;code&gt;git branch&lt;/code&gt; lists your local branches and marks the currently checked-out one with an asterisk. With a branch name, it creates a new branch pointing at the current commit. With additional flags, it can list remote branches, delete branches, rename them, or set upstream tracking.&lt;/p&gt;
&lt;h2 id="listing-branches"&gt;Listing Branches &lt;a class="headline-link" href="#listing-branches" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To list the local branches in the current repository, run &lt;code&gt;git branch&lt;/code&gt; with no arguments:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt; develop
* main
feature/login&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The asterisk marks the branch you are currently on. The branches are sorted alphabetically.&lt;/p&gt;
&lt;p&gt;To include remote-tracking branches, add &lt;code&gt;-a&lt;/code&gt; (all):&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch -a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt; develop
* main
feature/login
remotes/origin/HEAD -&amp;gt; origin/main
remotes/origin/develop
remotes/origin/main&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Anything prefixed with &lt;code&gt;remotes/&lt;/code&gt; is a local reference to a branch on a remote, not a branch you can commit to directly. Check it out to create a local tracking branch.&lt;/p&gt;
&lt;p&gt;To list only remote-tracking branches, use &lt;code&gt;-r&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch -r&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To see the latest commit on each branch, add &lt;code&gt;-v&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch -v&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt; develop a1b2c3d Add release notes
* main 7e8f9a0 Merge pull request #42
feature/login 3d4e5f6 Stub login form&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For even more detail, &lt;code&gt;-vv&lt;/code&gt; also prints the upstream branch each local branch tracks and whether it is ahead, behind, or in sync:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch -vv&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt; develop a1b2c3d [origin/develop] Add release notes
* main 7e8f9a0 [origin/main] Merge pull request #42
feature/login 3d4e5f6 [origin/feature/login: ahead 2] Stub login form&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="creating-a-branch"&gt;Creating a Branch &lt;a class="headline-link" href="#creating-a-branch" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To create a new branch, pass the name as an argument. This creates the branch at the current &lt;code&gt;HEAD&lt;/code&gt; but does not switch to it:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch feature/login&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To start the branch from a specific commit, tag, or another branch, pass it as the second argument:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch hotfix v1.4.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch hotfix 3d4e5f6&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Creating a branch without switching to it is useful when you want to mark a commit for later work. Most of the time, though, you create a branch and switch to it in one step. The modern command for that is &lt;code&gt;git switch -c&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git switch -c feature/login&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The older equivalent is &lt;code&gt;git checkout -b feature/login&lt;/code&gt;. Both create the branch at the current commit and check it out immediately. See the &lt;a href="https://linuxize.com/post/how-to-create-and-list-git-branches/"&gt;create and list Git branches&lt;/a&gt;
guide for a fuller walkthrough.&lt;/p&gt;
&lt;h2 id="renaming-a-branch"&gt;Renaming a Branch &lt;a class="headline-link" href="#renaming-a-branch" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To rename the branch you are currently on, use &lt;code&gt;-m&lt;/code&gt; with the new name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch -m new-name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To rename any branch, pass both the old and the new name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch -m old-name new-name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If a branch with the target name already exists, this form fails to protect you from overwriting it. To force the rename and overwrite the existing branch, use the capital &lt;code&gt;-M&lt;/code&gt; instead. Use &lt;code&gt;-M&lt;/code&gt; with care: it discards the destination branch.&lt;/p&gt;
&lt;p&gt;After renaming a branch that is already pushed, push the new name to the remote and delete the old one so collaborators see the change. The &lt;a href="https://linuxize.com/post/how-to-rename-local-and-remote-git-branch/"&gt;rename a Git branch&lt;/a&gt;
guide walks through the full local-and-remote flow.&lt;/p&gt;
&lt;h2 id="deleting-a-branch"&gt;Deleting a Branch &lt;a class="headline-link" href="#deleting-a-branch" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To delete a local branch that has been merged into the current branch, use &lt;code&gt;-d&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch -d feature/login&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Deleted branch feature/login (was 3d4e5f6).&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Git refuses to delete a branch that has unmerged work, to protect you from losing commits:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;error: The branch &amp;#39;feature/wip&amp;#39; is not fully merged.
If you are sure you want to delete it, run &amp;#39;git branch -D feature/wip&amp;#39;.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you are sure the work is no longer needed, force the deletion with &lt;code&gt;-D&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch -D feature/wip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You cannot delete the branch you are currently on. Switch to another branch first, then delete it. For remote branch deletion, see the &lt;a href="https://linuxize.com/post/how-to-delete-local-and-remote-git-branch/"&gt;delete local and remote Git branch&lt;/a&gt;
guide.&lt;/p&gt;
&lt;h2 id="filtering-by-merged-state"&gt;Filtering by Merged State &lt;a class="headline-link" href="#filtering-by-merged-state" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;git branch&lt;/code&gt; can filter branches by whether they are fully merged into the current branch. List branches that have been merged:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch --merged&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is the safest way to find branches that can be deleted without losing history. Before deleting anything, preview the filtered list:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch --merged &lt;span class="p"&gt;|&lt;/span&gt; grep -vE &lt;span class="s1"&gt;&amp;#39;^\*|^[[:space:]]*(main|develop)$&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;grep&lt;/code&gt; filter keeps the current branch and the protected &lt;code&gt;main&lt;/code&gt; and &lt;code&gt;develop&lt;/code&gt; branches out of the list. If the output looks correct, pipe the same list to &lt;code&gt;git branch -d&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch --merged &lt;span class="p"&gt;|&lt;/span&gt; grep -vE &lt;span class="s1"&gt;&amp;#39;^\*|^[[:space:]]*(main|develop)$&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; xargs -r git branch -d&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To list branches that still have unmerged work, use &lt;code&gt;--no-merged&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch --no-merged&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;These are the branches you should review before deleting, because they contain commits that are not on your current branch.&lt;/p&gt;
&lt;h2 id="filtering-remote-branches-too"&gt;Filtering Remote Branches Too &lt;a class="headline-link" href="#filtering-remote-branches-too" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;--merged&lt;/code&gt; and &lt;code&gt;--no-merged&lt;/code&gt; accept a reference argument. To check against &lt;code&gt;main&lt;/code&gt; from the remote:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch --merged origin/main&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is useful in CI or cleanup scripts where you want to see which local branches are safely merged into the shipped code, regardless of which branch you are currently on.&lt;/p&gt;
&lt;h2 id="setting-an-upstream-branch"&gt;Setting an Upstream Branch &lt;a class="headline-link" href="#setting-an-upstream-branch" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;An upstream branch tells Git which remote branch your local branch tracks for &lt;code&gt;git pull&lt;/code&gt; and &lt;code&gt;git push&lt;/code&gt;. To set it on an existing branch, use &lt;code&gt;--set-upstream-to&lt;/code&gt; (or &lt;code&gt;-u&lt;/code&gt;):&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch --set-upstream-to&lt;span class="o"&gt;=&lt;/span&gt;origin/main main&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Branch &amp;#39;main&amp;#39; set up to track remote branch &amp;#39;main&amp;#39; from &amp;#39;origin&amp;#39;.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To remove tracking information from a branch, use &lt;code&gt;--unset-upstream&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch --unset-upstream main&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When you push a new branch to a remote for the first time, pass &lt;code&gt;-u&lt;/code&gt; to &lt;code&gt;git push&lt;/code&gt; to create the remote branch and set it as the upstream in one step:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git push -u origin feature/login&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="showing-the-current-branch"&gt;Showing the Current Branch &lt;a class="headline-link" href="#showing-the-current-branch" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To print just the name of the branch you are on, use &lt;code&gt;--show-current&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch --show-current&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;main&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is the right command for shell prompts and scripts. It prints nothing if you are in a detached &lt;code&gt;HEAD&lt;/code&gt; state, which scripts can detect and handle.&lt;/p&gt;
&lt;h2 id="copying-a-branch"&gt;Copying a Branch &lt;a class="headline-link" href="#copying-a-branch" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;git branch -c&lt;/code&gt; copies a branch, including its reflog and configuration, to a new name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch -c old-branch new-branch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The original branch is kept. Use the capital &lt;code&gt;-C&lt;/code&gt; to force the copy and overwrite an existing target branch. Copying is less common than creating a fresh branch, but it is useful when you want to preserve the history and config of a branch under a new name.&lt;/p&gt;
&lt;h2 id="sorting-the-branch-list"&gt;Sorting the Branch List &lt;a class="headline-link" href="#sorting-the-branch-list" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, branches are listed alphabetically. The &lt;code&gt;--sort&lt;/code&gt; option changes the order. To sort by the date of the most recent commit:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git branch --sort&lt;span class="o"&gt;=&lt;/span&gt;-committerdate&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The minus sign reverses the order, so the most recently updated branch appears first. This is handy when you return to a project after a break and want to see what you were working on last.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List local branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch -a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List local and remote-tracking branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch -r&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List only remote-tracking branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch -v&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show the latest commit on each branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch -vv&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show upstream tracking and ahead/behind counts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch NAME&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a new branch at &lt;code&gt;HEAD&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch NAME START&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a branch at a specific commit or tag&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch -m NEW&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rename the current branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch -m OLD NEW&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rename another branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch -d NAME&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Delete a merged branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch -D NAME&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Force-delete a branch with unmerged work&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch --merged&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List branches merged into the current branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch --no-merged&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List branches with unmerged work&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch -u origin/main&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Set the upstream of the current branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch --show-current&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Print the current branch name&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch --sort=-committerdate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sort by most recent commit&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between git branch and git checkout?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;git branch&lt;/code&gt; manages branches: creating, listing, renaming, and deleting. &lt;code&gt;git checkout&lt;/code&gt; (and its modern replacement &lt;code&gt;git switch&lt;/code&gt;) changes which branch you are on. Creating and switching in one step uses &lt;code&gt;git switch -c&lt;/code&gt; or &lt;code&gt;git checkout -b&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I delete a remote branch?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;git branch -d&lt;/code&gt; only deletes local branches. To delete a branch on the remote, run &lt;code&gt;git push origin --delete BRANCH_NAME&lt;/code&gt;. The &lt;a href="https://linuxize.com/post/how-to-delete-local-and-remote-git-branch/"&gt;delete local and remote Git branch&lt;/a&gt;
guide covers the full flow, including cleanup of stale tracking references.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why does Git say &amp;ldquo;branch is not fully merged&amp;rdquo;?&lt;/strong&gt;&lt;br&gt;
The branch has commits that are not reachable from your current branch. Git is protecting you from losing work. Review the commits with &lt;code&gt;git log BRANCH_NAME&lt;/code&gt;, merge them if needed, and then use &lt;code&gt;-d&lt;/code&gt; again. If you are certain the commits are not needed, force the delete with &lt;code&gt;-D&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I see which branch a remote branch tracks locally?&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;git branch -vv&lt;/code&gt;. The output includes each local branch&amp;rsquo;s upstream in brackets along with its ahead and behind counts relative to that upstream.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I list branches sorted by who committed most recently?&lt;/strong&gt;&lt;br&gt;
Yes. Use &lt;code&gt;git branch --sort=-committerdate&lt;/code&gt; to sort branches by the timestamp of their most recent commit, with the freshest branch first. This is a fast way to see what is actively being worked on.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;git branch&lt;/code&gt; covers the full lifecycle of a branch: creating it, renaming it, keeping track of what it points at, and deleting it when the work is done. Combined with &lt;code&gt;git switch&lt;/code&gt; for moving between branches and &lt;code&gt;git merge&lt;/code&gt; for integrating changes, it is the foundation of any Git workflow.&lt;/p&gt;
&lt;p&gt;For related Git commands, see the &lt;a href="https://linuxize.com/post/git-diff-command/"&gt;&lt;code&gt;git diff&lt;/code&gt;&lt;/a&gt;
guide for reviewing changes and the &lt;a href="https://linuxize.com/post/git-log-command/"&gt;&lt;code&gt;git log&lt;/code&gt;&lt;/a&gt;
guide for inspecting branch history.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/git-branch-command/featured_hu_226ffc90fa3946ba.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>git fetch vs git pull: What Is the Difference?</title><link>https://linuxize.com/post/git-fetch-vs-git-pull/</link><pubDate>Sat, 18 Apr 2026 09:20:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/git-fetch-vs-git-pull/</guid><category>git</category><category>linux commands</category><description>git fetch and git pull both download changes from a remote repository, but only one updates your current branch. This guide explains the difference, when to use each command, and how to avoid merge surprises.</description><content:encoded>&lt;p&gt;Sooner or later, every Git user runs into the same question: should you use &lt;code&gt;git fetch&lt;/code&gt; or &lt;code&gt;git pull&lt;/code&gt; to get the latest changes from the remote? The two commands look similar, and both talk to the remote repository, but they do very different things to your working branch.&lt;/p&gt;
&lt;p&gt;This guide explains the difference between &lt;code&gt;git fetch&lt;/code&gt; and &lt;code&gt;git pull&lt;/code&gt;, how each command works, and when to use one over the other.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;If you want to&amp;hellip;&lt;/th&gt;
&lt;th&gt;Use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Download remote changes without touching your branch&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git fetch&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Download and immediately integrate remote changes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git pull&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Preview incoming commits before merging&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git fetch&lt;/code&gt; + &lt;code&gt;git log HEAD..origin/main --oneline&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Update your branch but refuse merge commits&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git pull --ff-only&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rebase local commits on top of remote changes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git pull --rebase&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="what-git-fetch-does"&gt;What git fetch Does &lt;a class="headline-link" href="#what-git-fetch-does" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;git fetch&lt;/code&gt; downloads commits, branches, and tags from a remote repository and stores them locally under remote-tracking references such as &lt;code&gt;origin/main&lt;/code&gt; or &lt;code&gt;origin/feature-x&lt;/code&gt;. It does not touch your working directory, your current branch, or the index.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git fetch origin&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;remote: Enumerating objects: 12, done.
remote: Counting objects: 100% (12/12), done.
From github.com:example/project
4a1c2e3..9f7b8d1 main -&amp;gt; origin/main
a6d4c02..1e2f3a4 feature-x -&amp;gt; origin/feature-x&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output shows which remote branches were updated. After the fetch, the local branch &lt;code&gt;main&lt;/code&gt; is still pointing to whatever commit it was on before. Only the remote-tracking branch &lt;code&gt;origin/main&lt;/code&gt; has moved.&lt;/p&gt;
&lt;p&gt;You can then inspect what changed before doing anything with it:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log main..origin/main&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is the safe way to look at new work without merging or rebasing yet. It gives you a preview of what the remote has that your branch does not.&lt;/p&gt;
&lt;h2 id="what-git-pull-does"&gt;What git pull Does &lt;a class="headline-link" href="#what-git-pull-does" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;git pull&lt;/code&gt; is a convenience command. Under the hood, it runs &lt;code&gt;git fetch&lt;/code&gt; followed by an integration step (a merge by default, or a rebase if configured). In other words:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git pull origin main&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;is roughly equivalent to:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git fetch origin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git merge origin/main&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;After &lt;code&gt;git pull&lt;/code&gt;, your current branch has moved forward, and your working directory may contain new files, updated files, or merge conflicts that need resolving. The change is immediate and affects your checked-out branch.&lt;/p&gt;
&lt;h2 id="side-by-side-comparison"&gt;Side-By-Side Comparison &lt;a class="headline-link" href="#side-by-side-comparison" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The difference between the two commands comes down to what they change in your repository.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;&lt;code&gt;git fetch&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;git pull&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Downloads new commits from remote&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Updates remote-tracking branches (&lt;code&gt;origin/*&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Updates your current local branch&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modifies the working directory&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can create merge conflicts&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Safe to run at any time&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Only when ready to integrate&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;git fetch&lt;/code&gt; is read-only from your branch&amp;rsquo;s perspective. &lt;code&gt;git pull&lt;/code&gt; actively changes your branch.&lt;/p&gt;
&lt;h2 id="when-to-use-git-fetch"&gt;When to Use git fetch &lt;a class="headline-link" href="#when-to-use-git-fetch" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;git fetch&lt;/code&gt; when you want to see what changed on the remote without integrating anything yet. This is useful before you start new work, before rebasing a feature branch, or when you want to inspect a teammate&amp;rsquo;s branch safely.&lt;/p&gt;
&lt;p&gt;For example, after fetching, you can compare your branch with the remote like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log HEAD..origin/main --oneline&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This shows commits that exist on the remote but not in your current branch. Running &lt;code&gt;git fetch&lt;/code&gt; often is cheap and has no side effects on your work, which is why many developers do it regularly throughout the day.&lt;/p&gt;
&lt;h2 id="when-to-use-git-pull"&gt;When to Use git pull &lt;a class="headline-link" href="#when-to-use-git-pull" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;git pull&lt;/code&gt; when you are ready to bring remote changes into your current branch and keep working on top of them. The common flow looks like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git checkout main
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git pull origin main&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is the quickest way to sync a branch with its upstream when you know the integration will be straightforward, such as on a shared &lt;code&gt;main&lt;/code&gt; branch where you rarely have local commits. &lt;code&gt;git pull&lt;/code&gt; always updates the branch you currently have checked out, so it is worth confirming where you are before you run it.&lt;/p&gt;
&lt;p&gt;If you want a cleaner history without merge commits, configure pull to rebase:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git config --global pull.rebase true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;From that point on, &lt;code&gt;git pull&lt;/code&gt; runs &lt;code&gt;git fetch&lt;/code&gt; followed by &lt;code&gt;git rebase&lt;/code&gt; instead of &lt;code&gt;git merge&lt;/code&gt;. Your local commits are replayed on top of the fetched changes, producing a linear history.&lt;/p&gt;
&lt;h2 id="avoiding-merge-surprises"&gt;Avoiding Merge Surprises &lt;a class="headline-link" href="#avoiding-merge-surprises" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The biggest reason to prefer &lt;code&gt;git fetch&lt;/code&gt; over &lt;code&gt;git pull&lt;/code&gt; in day-to-day work is control. A bare &lt;code&gt;git pull&lt;/code&gt; on a branch where you have local commits can create a merge commit, introduce conflicts, or rewrite history during a rebase, all in one step.&lt;/p&gt;
&lt;p&gt;A safer pattern is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git fetch origin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log HEAD..origin/main --oneline
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git merge origin/main&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You fetch first, review what is coming, then decide whether to merge, rebase, or defer the integration. For active feature branches, this workflow avoids most of the &amp;ldquo;what just happened to my branch&amp;rdquo; moments.&lt;/p&gt;
&lt;p&gt;If you already ran &lt;code&gt;git pull&lt;/code&gt; and need to inspect what happened, start with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log --oneline --decorate -n &lt;span class="m"&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This helps you confirm whether Git created a merge commit, fast-forwarded the branch, or rebased your local work.&lt;/p&gt;
&lt;p&gt;If the pull created a merge commit that you do not want, &lt;code&gt;ORIG_HEAD&lt;/code&gt; often points to the commit your branch was on before the pull. In that case, you can reset back to it:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git reset --hard ORIG_HEAD&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="note callout callout-warning"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"&gt;
&lt;path d="M10 20C4.477 20 0 15.523 0 10S4.477 0 10 0s10 4.477 10 10-4.477 10-10 10zm0-2c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm-.5-5h1c.276 0 .5.224.5.5v1c0 .276-.224.5-.5.5h-1c-.276 0-.5-.224-.5-.5v-1c0-.276.224-.5.5-.5zm0-8h1c.276 0 .5.224.5.5V8l-.5 3-1 .5L9 8V5.5c0-.276.224-.5.5-.5z"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;span class="callout-title"&gt;Warning&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;&lt;code&gt;git reset --hard&lt;/code&gt; discards uncommitted changes. Use it only when you are sure you do not need the current state of your working tree.&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="useful-flags"&gt;Useful Flags &lt;a class="headline-link" href="#useful-flags" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A few flags make both commands more predictable in real workflows.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git fetch --all&lt;/code&gt; - Fetch from every configured remote, not only &lt;code&gt;origin&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git fetch --prune&lt;/code&gt; - Remove remote-tracking branches that no longer exist on the remote.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git fetch --tags&lt;/code&gt; - Download tags in addition to branches.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git pull --rebase&lt;/code&gt; - Rebase your local commits on top of the fetched changes instead of merging.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git pull --ff-only&lt;/code&gt; - Update the branch only if Git can fast-forward it; prevents unexpected merge commits.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;--ff-only&lt;/code&gt; is especially useful on shared branches. If your branch cannot move forward by simply advancing the pointer, the pull fails and you decide what to do next.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Does git fetch modify any local files?&lt;/strong&gt;&lt;br&gt;
No. It only updates remote-tracking references such as &lt;code&gt;origin/main&lt;/code&gt;. Your branches, working directory, and staging area stay the same.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is git pull the same as git fetch plus git merge?&lt;/strong&gt;&lt;br&gt;
By default, yes. With &lt;code&gt;pull.rebase&lt;/code&gt; set to true (or &lt;code&gt;--rebase&lt;/code&gt; on the command line), it runs &lt;code&gt;git fetch&lt;/code&gt; followed by &lt;code&gt;git rebase&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Which one should I use daily?&lt;/strong&gt;&lt;br&gt;
Prefer &lt;code&gt;git fetch&lt;/code&gt; for visibility and &lt;code&gt;git pull --ff-only&lt;/code&gt; (or &lt;code&gt;git pull --rebase&lt;/code&gt;) for the integration step. A bare &lt;code&gt;git pull&lt;/code&gt; works, but it hides two operations behind one command.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I see what git fetch downloaded?&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;git log main..origin/main&lt;/code&gt; to see commits on the remote that are not yet in your local branch, or &lt;code&gt;git diff main origin/main&lt;/code&gt; to compare the content directly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can git fetch cause conflicts?&lt;/strong&gt;&lt;br&gt;
No. Conflicts only happen when you merge or rebase the fetched commits into your branch. Fetching itself is conflict-free.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;git fetch&lt;/code&gt; lets you inspect remote changes without touching your branch, while &lt;code&gt;git pull&lt;/code&gt; fetches and integrates those changes in one step. If you want more control and fewer surprises, fetch first, review the incoming commits, and then merge or rebase on your own terms. For more Git workflow details, see the &lt;a href="https://linuxize.com/post/git-log-command/"&gt;git log command&lt;/a&gt;
and &lt;a href="https://linuxize.com/post/git-diff-command/"&gt;git diff command&lt;/a&gt;
guides.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/git-fetch-vs-git-pull/featured_hu_d315dafc81ccee34.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>sha256sum and md5sum Commands: Verify File Integrity in Linux</title><link>https://linuxize.com/post/sha256sum-and-md5sum-commands/</link><pubDate>Fri, 17 Apr 2026 10:00:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/sha256sum-and-md5sum-commands/</guid><category>linux commands</category><description>How to use sha256sum and md5sum to generate and verify checksums for files, validate ISO downloads, and detect tampering on Linux systems.</description><content:encoded>&lt;p&gt;When you download an ISO image, a backup archive, or a large release tarball, there is no easy way to tell by looking whether the file arrived intact. A single flipped bit can break a boot image or turn a compressed archive into junk, and a compromised mirror can serve a tampered file that looks legitimate. The fix is to compare a cryptographic fingerprint of the file against a value the publisher has signed or posted somewhere you trust.&lt;/p&gt;
&lt;p&gt;This guide shows how to use &lt;code&gt;sha256sum&lt;/code&gt; and &lt;code&gt;md5sum&lt;/code&gt; to generate, compare, and verify checksums on Linux, and when to use each one.&lt;/p&gt;
&lt;h2 id="sha256sum-and-md5sum-syntax"&gt;sha256sum and md5sum Syntax &lt;a class="headline-link" href="#sha256sum-and-md5sum-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Both commands follow the same form:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sha256sum [OPTIONS] [FILE]...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;md5sum [OPTIONS] [FILE]...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Without options, each command prints a hex digest followed by two spaces and the file name. Pass &lt;code&gt;-c&lt;/code&gt; to verify files against a list of previously generated checksums.&lt;/p&gt;
&lt;h2 id="sha256sum-vs-md5sum"&gt;sha256sum vs md5sum &lt;a class="headline-link" href="#sha256sum-vs-md5sum" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The two tools do the same job: they read a file and print a fixed-length fingerprint. The difference is the algorithm and, by extension, how safe the result is against intentional tampering.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;md5sum&lt;/code&gt; uses the MD5 algorithm and produces a 128-bit digest. MD5 is fast but has been broken for years: it is possible to construct two different files that share the same MD5 hash. Treat it as a checksum for accidental corruption only, not for authenticity or security.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sha256sum&lt;/code&gt; uses SHA-256 from the SHA-2 family and produces a 256-bit digest. It is the default choice for verifying downloads, release artifacts, and anything where the threat model includes a malicious middle party. Most Linux distributions publish &lt;code&gt;SHA256SUMS&lt;/code&gt; files next to their ISO images for exactly this reason.&lt;/p&gt;
&lt;p&gt;When in doubt, use &lt;code&gt;sha256sum&lt;/code&gt;. Reach for &lt;code&gt;md5sum&lt;/code&gt; only when a publisher provides MD5 values and nothing stronger, or when you need quick parity checks between known-good files.&lt;/p&gt;
&lt;h2 id="generating-a-checksum-for-a-file"&gt;Generating a Checksum for a File &lt;a class="headline-link" href="#generating-a-checksum-for-a-file" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To produce a SHA-256 digest for a single file, pass it as an argument:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sha256sum ubuntu-24.04.2-desktop-amd64.iso&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;5e38b55d57d94ff029719342357325ed3bda38fa80054f9330dc789cd2d43931 ubuntu-24.04.2-desktop-amd64.iso&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output is one line: the hex digest, two spaces, and the file name. The same file always produces the same digest, so you can run the command again after a copy or a download and compare the values by eye.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;md5sum&lt;/code&gt; behaves the same way:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;md5sum ubuntu-24.04.2-desktop-amd64.iso&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;2e3720b76b2f9f96edc43ec4d87d7d52 ubuntu-24.04.2-desktop-amd64.iso&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Notice that the MD5 digest is shorter. That is the 128-bit hash encoded in 32 hex characters, compared with 64 hex characters for SHA-256.&lt;/p&gt;
&lt;h2 id="generating-checksums-for-multiple-files"&gt;Generating Checksums for Multiple Files &lt;a class="headline-link" href="#generating-checksums-for-multiple-files" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Both commands accept any number of file arguments and print one line per file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sha256sum *.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;b2b09c1e04b2a3a4c5d6e7f890123456789abcdef0123456789abcdef01234567 backup-2026-04-01.tar.gz
c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8091a2b3c4d5e6f708192a3b4c5d6e7f8 backup-2026-04-08.tar.gz&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To save the output to a checksum file that you can share or verify later, redirect it:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sha256sum *.tar.gz &amp;gt; SHA256SUMS&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The resulting &lt;code&gt;SHA256SUMS&lt;/code&gt; file can be published alongside the archives, and anyone who downloads them can run a single command to confirm that their copy matches.&lt;/p&gt;
&lt;h2 id="verifying-a-file-against-a-known-checksum"&gt;Verifying a File Against a Known Checksum &lt;a class="headline-link" href="#verifying-a-file-against-a-known-checksum" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The most common task is to check that a download matches the digest the publisher posted. Distributions usually ship a &lt;code&gt;SHA256SUMS&lt;/code&gt; file that lists every release file and its digest. Change into the directory that holds both the archive and the checksum file, then pass &lt;code&gt;-c&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sha256sum -c SHA256SUMS&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;ubuntu-24.04.2-desktop-amd64.iso: OK
ubuntu-24.04.2-live-server-amd64.iso: OK&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;sha256sum&lt;/code&gt; reads each line of &lt;code&gt;SHA256SUMS&lt;/code&gt;, recomputes the digest for the named file, and prints &lt;code&gt;OK&lt;/code&gt; when they match. Any line whose file is missing or whose digest differs prints a clear error and causes the command to exit with a non-zero status, which is convenient in scripts.&lt;/p&gt;
&lt;p&gt;When you only care about one file out of many, &lt;code&gt;grep&lt;/code&gt; the relevant line into the check:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep &lt;span class="s2"&gt;&amp;#34;ubuntu-24.04.2-desktop-amd64.iso&amp;#34;&lt;/span&gt; SHA256SUMS &lt;span class="p"&gt;|&lt;/span&gt; sha256sum -c -&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The trailing &lt;code&gt;-&lt;/code&gt; tells &lt;code&gt;sha256sum&lt;/code&gt; to read the checksum list from standard input. This keeps the verification scoped to a single file without creating a second checksum file.&lt;/p&gt;
&lt;h2 id="comparing-a-file-to-a-published-digest"&gt;Comparing a File to a Published Digest &lt;a class="headline-link" href="#comparing-a-file-to-a-published-digest" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Sometimes the publisher does not provide a full &lt;code&gt;SHA256SUMS&lt;/code&gt; file but instead shows a single digest on a release page. You can compare it directly without creating a file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;5e38b55d57d94ff029719342357325ed3bda38fa80054f9330dc789cd2d43931 ubuntu-24.04.2-desktop-amd64.iso&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sha256sum -c -&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;ubuntu-24.04.2-desktop-amd64.iso: OK&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The key detail is the double space between the digest and the file name. That is the exact format &lt;code&gt;sha256sum&lt;/code&gt; produces and expects, and a single space will cause the check to fail.&lt;/p&gt;
&lt;h2 id="quiet-and-warn-modes"&gt;Quiet and Warn Modes &lt;a class="headline-link" href="#quiet-and-warn-modes" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;During an automated check, the per-file &lt;code&gt;OK&lt;/code&gt; lines can be noisy. The &lt;code&gt;--quiet&lt;/code&gt; option suppresses successful lines so only failures appear:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sha256sum -c --quiet SHA256SUMS&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If every file passes, the command prints nothing and exits with status &lt;code&gt;0&lt;/code&gt;. If a file fails, you see a single failure line and a non-zero exit status, which fits well in a CI job or a backup script.&lt;/p&gt;
&lt;p&gt;To flag lines in a checksum file that are not formatted correctly, add &lt;code&gt;--warn&lt;/code&gt;. This is helpful when the file was assembled by hand and you want to be sure every entry parses.&lt;/p&gt;
&lt;h2 id="common-options"&gt;Common Options &lt;a class="headline-link" href="#common-options" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The flags below are the ones you are likely to use day to day:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-c&lt;/code&gt;, &lt;code&gt;--check&lt;/code&gt; - Read digests from a file and verify each one.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-b&lt;/code&gt;, &lt;code&gt;--binary&lt;/code&gt; - Mark files as binary in the output (default on Linux).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-t&lt;/code&gt;, &lt;code&gt;--text&lt;/code&gt; - Read files in text mode (rare on Linux, kept for portability).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--quiet&lt;/code&gt; - Suppress &lt;code&gt;OK&lt;/code&gt; lines when checking.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--status&lt;/code&gt; - Print nothing; rely on the exit status alone.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--ignore-missing&lt;/code&gt; - Skip files listed in the digest file that are not present.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--tag&lt;/code&gt; - Output BSD-style tagged format, useful when mixing hash algorithms.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;md5sum&lt;/code&gt; accepts the same flags, which makes it easy to swap one command for the other when the algorithm changes.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sha256sum file.iso&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Generate a SHA-256 checksum for one file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;md5sum file.iso&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Generate an MD5 checksum for one file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sha256sum *.tar.gz &amp;gt; SHA256SUMS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Save checksums for multiple files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sha256sum -c SHA256SUMS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Verify files against a checksum list&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;`grep &amp;ldquo;file.iso&amp;rdquo; SHA256SUMS&lt;/td&gt;
&lt;td&gt;sha256sum -c -`&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sha256sum -c --quiet SHA256SUMS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show only failures during verification&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="verifying-a-download-end-to-end"&gt;Verifying a Download End to End &lt;a class="headline-link" href="#verifying-a-download-end-to-end" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Putting the pieces together, a typical download check looks like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget https://releases.ubuntu.com/24.04/ubuntu-24.04.2-desktop-amd64.iso
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget https://releases.ubuntu.com/24.04/SHA256SUMS
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sha256sum -c --ignore-missing SHA256SUMS&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;--ignore-missing&lt;/code&gt; flag keeps the check focused on the file you actually downloaded instead of failing on every other release listed in &lt;code&gt;SHA256SUMS&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For full confidence, also verify the signature on &lt;code&gt;SHA256SUMS&lt;/code&gt; itself using the publisher&amp;rsquo;s GPG key. A digest is only as trustworthy as the source you got it from, so a signed checksum file closes the loop.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Checksum mismatch on a freshly downloaded file&lt;/strong&gt;&lt;br&gt;
Re-download the file, ideally from a different mirror. The most common cause is a truncated transfer or a network error. If the second download still fails, the file on the mirror may be stale or tampered with, and you should report it to the project.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;No such file or directory&lt;/code&gt; when running with &lt;code&gt;-c&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The names in the checksum file are resolved relative to the current directory. Change into the directory that holds the files, or edit the checksum file to use paths that match where the files live.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;improperly formatted checksum line&lt;/code&gt; warnings&lt;/strong&gt;&lt;br&gt;
A single space between the digest and the file name instead of two, trailing whitespace, or Windows line endings will all trip the parser. Run &lt;code&gt;dos2unix&lt;/code&gt; on the file or recreate it with &lt;code&gt;sha256sum &amp;gt; SHA256SUMS&lt;/code&gt; to reset the format.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The MD5 digest matches but you still do not trust the file&lt;/strong&gt;&lt;br&gt;
You are right to be cautious. MD5 collisions are practical, so match an MD5 against accidental corruption only. Ask the publisher for a SHA-256 digest or a signed checksum file.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Which is faster, sha256sum or md5sum?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;md5sum&lt;/code&gt; is faster, sometimes noticeably so on large files. The speed difference rarely matters on modern hardware, and it is not a good reason to pick MD5 over SHA-256 for security-sensitive checks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I use sha256sum on a directory?&lt;/strong&gt;&lt;br&gt;
Not directly. Hash tools operate on files. To produce a digest that represents an entire directory, pipe a deterministic listing such as &lt;code&gt;find ... -type f -print0 | sort -z | xargs -0 sha256sum&lt;/code&gt; through another &lt;code&gt;sha256sum&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where do I find the expected digest for a Linux distro ISO?&lt;/strong&gt;&lt;br&gt;
Every major distribution publishes a &lt;code&gt;SHA256SUMS&lt;/code&gt; or &lt;code&gt;SHA512SUMS&lt;/code&gt; file on its download page, usually along with a detached GPG signature. Prefer those files over digests shown in third-party blog posts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is sha256sum available by default on Linux?&lt;/strong&gt;&lt;br&gt;
Yes. Both &lt;code&gt;sha256sum&lt;/code&gt; and &lt;code&gt;md5sum&lt;/code&gt; ship with the GNU coreutils package, which is installed on every mainstream Linux distribution.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;sha256sum&lt;/code&gt; should be the default for verifying downloads and backups, with &lt;code&gt;md5sum&lt;/code&gt; reserved for quick corruption checks when the publisher provides nothing stronger. When you pair a SHA-256 digest with a signed checksum file and a trusted key, you can answer the question that matters most: did I get the file the publisher actually shipped?&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/sha256sum-and-md5sum-commands/featured_hu_b36a5822e20a6b92.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>git cherry-pick Command: Apply Commits from Another Branch</title><link>https://linuxize.com/post/git-cherry-pick/</link><pubDate>Wed, 15 Apr 2026 10:20:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/git-cherry-pick/</guid><category>git</category><category>linux commands</category><description>How to use git cherry-pick to apply commits from one branch to another, including single commits, ranges, conflict handling, backports, and merge commits.</description><content:encoded>&lt;p&gt;Sometimes the change you need is already written, just on the wrong branch. A hotfix may land on &lt;code&gt;main&lt;/code&gt; when it also needs to go to a maintenance branch, or a useful commit may be buried in a feature branch that you do not want to merge wholesale. In that situation, &lt;code&gt;git cherry-pick&lt;/code&gt; lets you copy the effect of a specific commit onto your current branch.&lt;/p&gt;
&lt;p&gt;This guide explains how &lt;code&gt;git cherry-pick&lt;/code&gt; works, how to apply one or more commits safely, and how to handle the conflicts that can appear along the way.&lt;/p&gt;
&lt;h2 id="syntax"&gt;Syntax &lt;a class="headline-link" href="#syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The general syntax for &lt;code&gt;git cherry-pick&lt;/code&gt; is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git cherry-pick [OPTIONS] COMMIT...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;OPTIONS&lt;/code&gt; - Flags that change how Git applies the commit.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;COMMIT&lt;/code&gt; - One or more commit hashes, branch references, or commit ranges.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;git cherry-pick&lt;/code&gt; replays the changes introduced by the selected commit on top of your current branch. Git creates a new commit, so the result has a different commit hash even when the file changes are the same.&lt;/p&gt;
&lt;h2 id="cherry-picking-a-single-commit"&gt;Cherry-Picking a Single Commit &lt;a class="headline-link" href="#cherry-picking-a-single-commit" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Start by finding the commit you want to copy. This example lists the recent commits on a feature branch:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log --oneline feature/auth&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;a3f1c92 Fix null pointer in auth handler
d8b22e1 Add login form validation
7c4e003 Refactor session logic&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output gives you the abbreviated commit hashes. In this case, &lt;code&gt;a3f1c92&lt;/code&gt; is the fix we want to move.&lt;/p&gt;
&lt;p&gt;Switch to the target branch before running &lt;code&gt;git cherry-pick&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git switch main
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git cherry-pick a3f1c92&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;[main 9b2d4f1] Fix null pointer in auth handler
Date: Tue Apr 14 10:42:00 2026 +0200
1 file changed, 2 insertions(+)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Git applies the change from &lt;code&gt;a3f1c92&lt;/code&gt; to &lt;code&gt;main&lt;/code&gt; and creates a new commit, &lt;code&gt;9b2d4f1&lt;/code&gt;. The subject line is the same, but the commit hash is different because the parent commit is different.&lt;/p&gt;
&lt;h2 id="cherry-picking-multiple-commits"&gt;Cherry-Picking Multiple Commits &lt;a class="headline-link" href="#cherry-picking-multiple-commits" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you need more than one non-consecutive commit, pass each hash in the order you want Git to apply them:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git cherry-pick a3f1c92 d8b22e1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Git creates a separate new commit for each one. This works well when you need a few targeted fixes but do not want the rest of the source branch.&lt;/p&gt;
&lt;p&gt;For a range of consecutive commits, use the range notation:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git cherry-pick a3f1c92^..7c4e003&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This tells Git to include &lt;code&gt;a3f1c92&lt;/code&gt; and every commit after it up to &lt;code&gt;7c4e003&lt;/code&gt;. If you omit the caret, the starting commit itself is excluded:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git cherry-pick a3f1c92..7c4e003&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;That form applies every commit after &lt;code&gt;a3f1c92&lt;/code&gt; through &lt;code&gt;7c4e003&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="applying-changes-without-committing"&gt;Applying Changes Without Committing &lt;a class="headline-link" href="#applying-changes-without-committing" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Sometimes you want the changes from a commit, but not an automatic commit for each one. Use &lt;code&gt;--no-commit&lt;/code&gt; (or &lt;code&gt;-n&lt;/code&gt;) to apply the changes to your working tree and staging area without creating the commit yet:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git cherry-pick --no-commit a3f1c92&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is useful when you want to combine several small fixes into one commit on the target branch, or when you need to edit the files before committing.&lt;/p&gt;
&lt;p&gt;After reviewing the result, create the commit yourself:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git status
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git commit -m &lt;span class="s2"&gt;&amp;#34;Backport auth null-check fix&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This gives you more control over the final commit message and lets you group related backports together.&lt;/p&gt;
&lt;h2 id="recording-where-the-commit-came-from"&gt;Recording Where the Commit Came From &lt;a class="headline-link" href="#recording-where-the-commit-came-from" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For maintenance branches and backports, it is often helpful to keep a reference to the original commit. Use &lt;code&gt;-x&lt;/code&gt; to append the source commit hash to the new commit message:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git cherry-pick -x a3f1c92&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Git adds a line like this to the new commit message:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;(cherry picked from commit a3f1c92...)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That extra line makes future audits easier, especially when you need to prove that a fix on a release branch came from a reviewed change on another branch.&lt;/p&gt;
&lt;h2 id="cherry-picking-a-merge-commit"&gt;Cherry-Picking a Merge Commit &lt;a class="headline-link" href="#cherry-picking-a-merge-commit" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Cherry-picking a regular commit is straightforward, but merge commits need one extra option. Git must know which parent to treat as the main line:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git cherry-pick -m &lt;span class="m"&gt;1&lt;/span&gt; MERGE_COMMIT_HASH&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-m 1&lt;/code&gt; - Use the first parent as the base, which is usually the branch that received the merge.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-m 2&lt;/code&gt; - Use the second parent instead.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you are not sure which parent is which, inspect the history first:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log --oneline --graph&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Cherry-picking merge commits is more advanced and easier to get wrong. If the goal is to bring over an entire merged feature, a normal merge is often clearer than cherry-picking the merge commit itself.&lt;/p&gt;
&lt;h2 id="resolving-conflicts"&gt;Resolving Conflicts &lt;a class="headline-link" href="#resolving-conflicts" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If the target branch has changed in the same area of code, Git may stop and ask you to resolve a conflict:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;error: could not apply a3f1c92... Fix null pointer in auth handler
hint: After resolving the conflicts, mark them with
hint: &amp;#34;git add/rm &amp;lt;pathspec&amp;gt;&amp;#34;, then run
hint: &amp;#34;git cherry-pick --continue&amp;#34;.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Open the conflicted file and look for the conflict markers:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; HEAD
return session.getUser();
=======
if (session == null) return null;
return session.getUser();
&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; a3f1c92 (Fix null pointer in auth handler)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Edit the file to keep the final version you want, then stage it and continue:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git add src/auth.js
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git cherry-pick --continue&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you decide the commit is not worth applying after all, abort the operation:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git cherry-pick --abort&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;git cherry-pick --abort&lt;/code&gt; puts the branch back where it was before the cherry-pick started.&lt;/p&gt;
&lt;h2 id="a-safe-backport-workflow"&gt;A Safe Backport Workflow &lt;a class="headline-link" href="#a-safe-backport-workflow" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When you cherry-pick onto a release or maintenance branch, slow down and make the source obvious. A simple workflow looks like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git switch release/1.4
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git pull --ff-only
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git cherry-pick -x a3f1c92
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git status&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The important part is the sequence. Start from the branch that needs the fix, make sure it is up to date, cherry-pick with &lt;code&gt;-x&lt;/code&gt;, then review and test the branch before pushing it. This avoids the common mistake of copying a fix into an outdated branch and shipping an untested backport.&lt;/p&gt;
&lt;p&gt;If the picked commit depends on earlier refactors or new APIs that are not present on the target branch, stop there. In that case, either copy the prerequisite commits too or recreate the fix manually.&lt;/p&gt;
&lt;h2 id="when-to-use-git-cherry-pick"&gt;When to Use git cherry-pick &lt;a class="headline-link" href="#when-to-use-git-cherry-pick" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;git cherry-pick&lt;/code&gt; is a good fit when you need a precise change without the rest of the branch:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Backporting a bug fix from &lt;code&gt;main&lt;/code&gt; to a release branch&lt;/li&gt;
&lt;li&gt;Recovering one useful commit from an abandoned feature branch&lt;/li&gt;
&lt;li&gt;Moving a small fix that was committed on the wrong branch&lt;/li&gt;
&lt;li&gt;Pulling a reviewed change into a hotfix branch without merging unrelated work&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Avoid it when the target branch needs the full context of the source branch. If the commit depends on earlier commits, shared refactors, or schema changes, a merge or rebase is usually the cleaner option.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;error: could not apply ...&lt;/code&gt; during cherry-pick&lt;/strong&gt;&lt;br&gt;
The target branch has conflicting changes. Resolve the files Git marks as conflicted, stage them with &lt;code&gt;git add&lt;/code&gt;, then run &lt;code&gt;git cherry-pick --continue&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cherry-pick created duplicate-looking history&lt;/strong&gt;&lt;br&gt;
That is normal. Cherry-pick copies the effect of a commit, not the original object. The new commit has a different hash because it has a different parent.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The picked commit does not build on the target branch&lt;/strong&gt;&lt;br&gt;
The commit likely depends on earlier work that is missing from the target branch. Inspect the source branch history with &lt;a href="https://linuxize.com/post/git-log-command/"&gt;&lt;code&gt;git log&lt;/code&gt;&lt;/a&gt;
and either cherry-pick the prerequisites too or reimplement the change manually.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You picked the wrong commit&lt;/strong&gt;&lt;br&gt;
If the cherry-pick already completed, use &lt;a href="https://linuxize.com/post/git-revert-commit/"&gt;&lt;code&gt;git revert&lt;/code&gt;&lt;/a&gt;
on the new commit. If the operation is still in progress, use &lt;code&gt;git cherry-pick --abort&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/git/"&gt;Git cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Pick one commit&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git cherry-pick COMMIT&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pick several specific commits&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git cherry-pick C1 C2 C3&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pick a consecutive range including the first commit&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git cherry-pick A^..B&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apply changes without committing&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git cherry-pick --no-commit COMMIT&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Record the source commit in the message&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git cherry-pick -x COMMIT&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Continue after resolving a conflict&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git cherry-pick --continue&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skip the current commit in a sequence&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git cherry-pick --skip&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Abort the operation&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git cherry-pick --abort&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pick a merge commit&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git cherry-pick -m 1 MERGE_COMMIT&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;git cherry-pick&lt;/code&gt; and &lt;code&gt;git merge&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;git cherry-pick&lt;/code&gt; copies the effect of selected commits onto your current branch. &lt;code&gt;git merge&lt;/code&gt; joins two branch histories and brings over all commits that are missing from the target branch.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does cherry-pick change the original commit?&lt;/strong&gt;&lt;br&gt;
No. The source commit stays exactly where it is. Git creates a new commit on your current branch with the same file changes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Should I use &lt;code&gt;-x&lt;/code&gt; every time?&lt;/strong&gt;&lt;br&gt;
Not always, but it is a good habit for backports and maintenance branches. It gives you a clear link back to the original commit.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I cherry-pick commits from another remote branch?&lt;/strong&gt;&lt;br&gt;
Yes. Fetch the remote branch first, then cherry-pick the commit hash you want. You can inspect the incoming history with &lt;a href="https://linuxize.com/post/git-log-command/"&gt;&lt;code&gt;git log&lt;/code&gt;&lt;/a&gt;
or review the file changes with &lt;a href="https://linuxize.com/post/git-diff-command/"&gt;&lt;code&gt;git diff&lt;/code&gt;&lt;/a&gt;
before applying anything.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;git cherry-pick&lt;/code&gt; is the tool to reach for when one commit matters more than the branch it came from. Use it for targeted fixes, keep &lt;code&gt;-x&lt;/code&gt; in mind for backports, and fall back to merge or rebase when the change depends on broader branch context.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/git-cherry-pick/featured_hu_78323f1acd5d97ed.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>ufw Command in Linux: Uncomplicated Firewall Reference</title><link>https://linuxize.com/post/ufw-command-in-linux/</link><pubDate>Tue, 14 Apr 2026 07:45:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/ufw-command-in-linux/</guid><category>firewall</category><category>security</category><category>linux commands</category><description>Reference for the ufw command on Linux, with examples for enabling the firewall, allowing and denying traffic, deleting rules, and managing application profiles.</description><content:encoded>&lt;p&gt;If your server is open to the public network, it needs a firewall. On Ubuntu and Debian, the easiest way to set one up is with &lt;code&gt;ufw&lt;/code&gt;. This tool sits on top of &lt;code&gt;iptables&lt;/code&gt; (or &lt;code&gt;nftables&lt;/code&gt; on newer systems) and replaces complex rules with simple, easy-to-read commands.&lt;/p&gt;
&lt;p&gt;This guide walks through the &lt;code&gt;ufw&lt;/code&gt; command, from enabling the firewall and setting default policies to writing rules for ports, services, and specific addresses.&lt;/p&gt;
&lt;h2 id="ufw-syntax"&gt;ufw Syntax &lt;a class="headline-link" href="#ufw-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The general form of the command is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw [OPTIONS] COMMAND [ARGS]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;OPTIONS&lt;/code&gt; - Flags such as &lt;code&gt;--dry-run&lt;/code&gt; to preview what a rule would do.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;COMMAND&lt;/code&gt; - The action, for example &lt;code&gt;enable&lt;/code&gt;, &lt;code&gt;allow&lt;/code&gt;, &lt;code&gt;deny&lt;/code&gt;, &lt;code&gt;delete&lt;/code&gt;, or &lt;code&gt;status&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ARGS&lt;/code&gt; - The rule body, such as a port number, a service name, or a full rule specification.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;ufw&lt;/code&gt; changes firewall rules, so almost every invocation needs &lt;code&gt;sudo&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="checking-the-firewall-status"&gt;Checking the Firewall Status &lt;a class="headline-link" href="#checking-the-firewall-status" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before you touch the rules, check whether the firewall is running and what is already in place:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw status&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If &lt;code&gt;ufw&lt;/code&gt; is inactive, you will see:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Status: inactive&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This confirms that &lt;code&gt;ufw&lt;/code&gt; is installed but not currently enforcing any firewall rules.&lt;/p&gt;
&lt;p&gt;Once active, the same command lists the rules:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
80/tcp ALLOW Anywhere
22/tcp (v6) ALLOW Anywhere (v6)
80/tcp (v6) ALLOW Anywhere (v6)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For a numbered view that is easier to reference when deleting rules, use:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw status numbered&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;And for a more detailed output that shows default policies and logging level:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw status verbose&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="enabling-and-disabling-the-firewall"&gt;Enabling and Disabling the Firewall &lt;a class="headline-link" href="#enabling-and-disabling-the-firewall" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The first time you enable &lt;code&gt;ufw&lt;/code&gt;, make sure you have already allowed SSH. Enabling the firewall over an SSH session without an &lt;code&gt;allow ssh&lt;/code&gt; rule will lock you out of the server.&lt;/p&gt;
&lt;p&gt;Allow SSH first:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Then turn the firewall on:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw enable&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Firewall is active and enabled on system startup&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;At this point, &lt;code&gt;ufw&lt;/code&gt; starts enforcing the rules immediately and will come back automatically after a reboot.&lt;/p&gt;
&lt;p&gt;To stop the firewall and clear it from the startup sequence:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw disable&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;A disabled &lt;code&gt;ufw&lt;/code&gt; keeps the rules you defined. When you re-enable it, the same rules come back.&lt;/p&gt;
&lt;h2 id="default-policies"&gt;Default Policies &lt;a class="headline-link" href="#default-policies" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Default policies decide what happens to traffic that does not match any rule. The usual hardening is to deny incoming traffic and allow outgoing traffic:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw default deny incoming
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw default allow outgoing&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;After running these two commands, you only need to open the specific inbound ports your server should expose. Outbound traffic still flows freely, which is what most servers need.&lt;/p&gt;
&lt;p&gt;You can also set the default for forwarded traffic, which matters if the host acts as a router or runs containers:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw default deny routed&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="allowing-connections"&gt;Allowing Connections &lt;a class="headline-link" href="#allowing-connections" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;allow&lt;/code&gt; command is the one you will use most often. It accepts a service name, a port, a protocol, or a full rule.&lt;/p&gt;
&lt;h3 id="allow-a-service-by-name"&gt;Allow a Service by Name &lt;a class="headline-link" href="#allow-a-service-by-name" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ufw&lt;/code&gt; reads &lt;code&gt;/etc/services&lt;/code&gt; and understands common service names:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow ssh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow http
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow https&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Each command opens the matching port (22, 80, and 443) for both TCP and UDP where applicable.&lt;/p&gt;
&lt;h3 id="allow-a-specific-port"&gt;Allow a Specific Port &lt;a class="headline-link" href="#allow-a-specific-port" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To open a port directly, pass the port number:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow &lt;span class="m"&gt;8080&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;By default, this opens the port for both TCP and UDP. To limit it to one protocol, add &lt;code&gt;/tcp&lt;/code&gt; or &lt;code&gt;/udp&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow 8080/tcp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow 53/udp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="allow-a-port-range"&gt;Allow a Port Range &lt;a class="headline-link" href="#allow-a-port-range" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Port ranges require an explicit protocol:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow 6000:6007/tcp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow 6000:6007/udp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The colon separates the start and the end of the range, both inclusive.&lt;/p&gt;
&lt;h3 id="allow-traffic-from-a-specific-address"&gt;Allow Traffic From a Specific Address &lt;a class="headline-link" href="#allow-traffic-from-a-specific-address" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To accept connections from a single IP address, use &lt;code&gt;from&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow from 203.0.113.25&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To restrict that to a single service, add &lt;code&gt;to any port&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow from 203.0.113.25 to any port &lt;span class="m"&gt;22&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="allow-traffic-from-a-subnet"&gt;Allow Traffic From a Subnet &lt;a class="headline-link" href="#allow-traffic-from-a-subnet" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;CIDR notation works the same way for whole networks:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow from 192.168.1.0/24 to any port &lt;span class="m"&gt;3306&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is a common pattern for databases: the port stays closed to the internet and is only reachable from your internal network.&lt;/p&gt;
&lt;h3 id="allow-traffic-on-a-specific-interface"&gt;Allow Traffic on a Specific Interface &lt;a class="headline-link" href="#allow-traffic-on-a-specific-interface" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To tie a rule to a network interface, add &lt;code&gt;on INTERFACE&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow in on eth1 to any port &lt;span class="m"&gt;3306&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;in&lt;/code&gt; keyword applies the rule to inbound traffic on &lt;code&gt;eth1&lt;/code&gt;. Use &lt;code&gt;out&lt;/code&gt; for outbound traffic.&lt;/p&gt;
&lt;h2 id="denying-connections"&gt;Denying Connections &lt;a class="headline-link" href="#denying-connections" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;deny&lt;/code&gt; command is the mirror of &lt;code&gt;allow&lt;/code&gt; and takes the same arguments:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw deny &lt;span class="m"&gt;23&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw deny from 198.51.100.77&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When the default incoming policy is already &lt;code&gt;deny&lt;/code&gt;, you usually do not need to write explicit &lt;code&gt;deny&lt;/code&gt; rules for closed ports. Explicit denies are useful when you want to block a specific address while keeping a port open to everyone else.&lt;/p&gt;
&lt;p&gt;To log the denied packets instead of silently dropping them, use &lt;code&gt;reject&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw reject &lt;span class="m"&gt;23&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;A reject sends an ICMP message back to the sender, while a deny drops the packet with no response.&lt;/p&gt;
&lt;h2 id="rate-limiting-ssh"&gt;Rate Limiting SSH &lt;a class="headline-link" href="#rate-limiting-ssh" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;ufw&lt;/code&gt; can throttle repeated connections from the same IP, which is handy for SSH brute-force protection:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw limit ssh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The limit rule denies a connection if the source address attempts six or more connections in 30 seconds. This is a quick way to slow down password-guessing bots without installing a full intrusion-prevention tool.&lt;/p&gt;
&lt;h2 id="deleting-rules"&gt;Deleting Rules &lt;a class="headline-link" href="#deleting-rules" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are two common ways to remove a rule. The first is to repeat the rule with &lt;code&gt;delete&lt;/code&gt; in front:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw delete allow 8080/tcp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The second is to delete by rule number:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw status numbered&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt; To Action From
-- ------ ----
[ 1] 22/tcp ALLOW IN Anywhere
[ 2] 80/tcp ALLOW IN Anywhere
[ 3] 8080/tcp ALLOW IN Anywhere&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw delete &lt;span class="m"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;ufw&lt;/code&gt; asks for confirmation before removing the rule. Keep in mind that after a deletion, the numbering shifts for the remaining rules, so always check the numbered status again before deleting another rule.&lt;/p&gt;
&lt;p&gt;For a deeper walkthrough, see &lt;a href="https://linuxize.com/post/how-to-list-and-delete-ufw-firewall-rules/"&gt;how to list and delete UFW firewall rules&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="application-profiles"&gt;Application Profiles &lt;a class="headline-link" href="#application-profiles" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Services that come with their own &lt;code&gt;ufw&lt;/code&gt; profile can be referenced by name. List them with:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw app list&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Available applications:
Nginx Full
Nginx HTTP
Nginx HTTPS
OpenSSH&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To open the ports that a profile covers, pass its name to &lt;code&gt;allow&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow &lt;span class="s1"&gt;&amp;#39;Nginx Full&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Quote profile names that contain spaces. To see what ports a profile includes, use:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw app info &lt;span class="s1"&gt;&amp;#39;Nginx Full&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="dry-run"&gt;Dry Run &lt;a class="headline-link" href="#dry-run" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before you commit to a change, you can preview the &lt;code&gt;iptables&lt;/code&gt; rules &lt;code&gt;ufw&lt;/code&gt; would add with &lt;code&gt;--dry-run&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw --dry-run allow 8080/tcp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;No rule is created. The output shows the exact lines &lt;code&gt;ufw&lt;/code&gt; would write, which is useful when you are writing rules over SSH and want to double-check them first.&lt;/p&gt;
&lt;h2 id="logging"&gt;Logging &lt;a class="headline-link" href="#logging" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;ufw&lt;/code&gt; can log packets that match rules, which helps when troubleshooting. The log level can be adjusted:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw logging on
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw logging medium&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Valid levels are &lt;code&gt;off&lt;/code&gt;, &lt;code&gt;low&lt;/code&gt;, &lt;code&gt;medium&lt;/code&gt;, &lt;code&gt;high&lt;/code&gt;, and &lt;code&gt;full&lt;/code&gt;. &lt;code&gt;ufw&lt;/code&gt; logs through the kernel log facility, so the exact destination depends on your system logging setup. On many Ubuntu systems with rsyslog, you will see entries in &lt;code&gt;/var/log/ufw.log&lt;/code&gt;, and you can often inspect them with &lt;code&gt;journalctl&lt;/code&gt; as well.&lt;/p&gt;
&lt;h2 id="reset-the-firewall"&gt;Reset the Firewall &lt;a class="headline-link" href="#reset-the-firewall" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To clear every rule and set &lt;code&gt;ufw&lt;/code&gt; back to its fresh state, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw reset&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="note callout callout-warning"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"&gt;
&lt;path d="M10 20C4.477 20 0 15.523 0 10S4.477 0 10 0s10 4.477 10 10-4.477 10-10 10zm0-2c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm-.5-5h1c.276 0 .5.224.5.5v1c0 .276-.224.5-.5.5h-1c-.276 0-.5-.224-.5-.5v-1c0-.276.224-.5.5-.5zm0-8h1c.276 0 .5.224.5.5V8l-.5 3-1 .5L9 8V5.5c0-.276.224-.5.5-.5z"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;span class="callout-title"&gt;Warning&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;&lt;code&gt;ufw reset&lt;/code&gt; disables the firewall and removes every rule, including the one that allows SSH. If you are connected over SSH, add an allow rule for SSH and re-enable the firewall right after the reset, or you will lose access the moment you turn it back on.&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="ipv6-support"&gt;IPv6 Support &lt;a class="headline-link" href="#ipv6-support" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;On most modern systems, &lt;code&gt;ufw&lt;/code&gt; can manage IPv6 rules as well as IPv4 rules. Check the setting in &lt;code&gt;/etc/default/ufw&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/default/ufw&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;IPV6&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When &lt;code&gt;IPV6=yes&lt;/code&gt;, generic rules such as &lt;code&gt;sudo ufw allow 22/tcp&lt;/code&gt; are created for both IPv4 and IPv6. Rules that include an explicit address stay specific to that address family. In the status output, the IPv6 rules appear with &lt;code&gt;(v6)&lt;/code&gt; next to them.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/ufw/"&gt;ufw cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Show status&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo ufw status verbose&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Show numbered rules&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo ufw status numbered&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enable firewall&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo ufw enable&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Disable firewall&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo ufw disable&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Default deny incoming&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo ufw default deny incoming&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Default allow outgoing&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo ufw default allow outgoing&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Allow SSH&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo ufw allow ssh&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Allow port&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo ufw allow 8080/tcp&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Allow port range&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo ufw allow 6000:6007/tcp&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Allow from IP&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo ufw allow from 203.0.113.25&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Allow from subnet&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo ufw allow from 192.168.1.0/24&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rate-limit SSH&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo ufw limit ssh&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete rule by number&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo ufw delete 3&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List app profiles&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo ufw app list&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reset all rules&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo ufw reset&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;ufw: command not found&lt;/strong&gt;&lt;br&gt;
Install the &lt;code&gt;ufw&lt;/code&gt; package with &lt;code&gt;sudo apt install ufw&lt;/code&gt; on Ubuntu or Debian. On Fedora, RHEL, and derivatives, &lt;code&gt;firewalld&lt;/code&gt; is the default and &lt;code&gt;ufw&lt;/code&gt; is rarely used.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Locked out after enabling the firewall over SSH&lt;/strong&gt;&lt;br&gt;
The default deny policy blocked your SSH session. You will need console access to the server. Once in, run &lt;code&gt;sudo ufw allow ssh&lt;/code&gt; and &lt;code&gt;sudo ufw reload&lt;/code&gt; to restore access. The usual safeguard is to allow SSH before the first &lt;code&gt;enable&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rule added but traffic still blocked&lt;/strong&gt;&lt;br&gt;
Confirm the rule is in the right direction (inbound vs outbound) and on the right interface. Check with &lt;code&gt;sudo ufw status verbose&lt;/code&gt;. If Docker is running, it writes its own &lt;code&gt;iptables&lt;/code&gt; rules that can bypass &lt;code&gt;ufw&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes do not take effect&lt;/strong&gt;&lt;br&gt;
After manual edits to &lt;code&gt;/etc/ufw/&lt;/code&gt; files, reload the firewall with &lt;code&gt;sudo ufw reload&lt;/code&gt;. Commands issued through &lt;code&gt;ufw&lt;/code&gt; apply immediately and do not need a reload.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Is ufw the same as iptables?&lt;/strong&gt;&lt;br&gt;
No. &lt;code&gt;ufw&lt;/code&gt; is a front end that generates &lt;code&gt;iptables&lt;/code&gt; (or &lt;code&gt;nftables&lt;/code&gt;) rules for you. The kernel still enforces the rules through its packet filter, but you do not need to edit the raw tables yourself.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does ufw start automatically after reboot?&lt;/strong&gt;&lt;br&gt;
Yes, once you run &lt;code&gt;sudo ufw enable&lt;/code&gt;, the service is registered with systemd and starts on boot. You can confirm with &lt;code&gt;systemctl status ufw&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I allow a port for a single IP address?&lt;/strong&gt;&lt;br&gt;
Use the &lt;code&gt;from&lt;/code&gt; and &lt;code&gt;to any port&lt;/code&gt; form: &lt;code&gt;sudo ufw allow from 203.0.113.25 to any port 22&lt;/code&gt;. This keeps the port closed to the rest of the internet and only opens it for that one address.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between deny and reject?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;deny&lt;/code&gt; drops the packet without any reply. &lt;code&gt;reject&lt;/code&gt; sends an ICMP message back to the sender telling them the connection was refused. Reject is slightly friendlier to well-behaved clients but makes the server more visible to scans.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I undo everything and start over?&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;sudo ufw reset&lt;/code&gt;. It disables the firewall and removes every rule. Remember to re-add the SSH rule before re-enabling, especially on a remote server.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;ufw&lt;/code&gt; keeps firewall management readable: allow what you need, deny what you do not, and lean on the default policies to cover the rest. If you want step-by-step instructions for setting it up on a new server, see &lt;a href="https://linuxize.com/post/how-to-setup-a-firewall-with-ufw-on-ubuntu-24-04/"&gt;how to set up a firewall with UFW on Ubuntu 24.04&lt;/a&gt;
.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/ufw-command-in-linux/featured_hu_c076730e72f422d3.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>nslookup Command in Linux: Query DNS Records</title><link>https://linuxize.com/post/nslookup-command-in-linux/</link><pubDate>Sat, 11 Apr 2026 11:00:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/nslookup-command-in-linux/</guid><category>dns</category><category>linux commands</category><description>The nslookup command queries DNS servers for domain records. This guide covers A, MX, NS, TXT, and AAAA lookups, reverse DNS, interactive mode, and choosing a specific name server.</description><content:encoded>&lt;p&gt;When a website does not load or email stops arriving, the first thing to check is whether the domain resolves to the correct address. The &lt;code&gt;nslookup&lt;/code&gt; command is a quick way to query DNS servers and inspect the records behind a domain name.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;nslookup&lt;/code&gt; ships with most Linux distributions and works on macOS and Windows as well. It supports both one-off queries from the command line and an interactive mode for running multiple lookups in a row.&lt;/p&gt;
&lt;p&gt;This guide explains how to use &lt;code&gt;nslookup&lt;/code&gt; with practical examples covering record types, reverse lookups, and troubleshooting.&lt;/p&gt;
&lt;h2 id="syntax"&gt;Syntax &lt;a class="headline-link" href="#syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nslookup [OPTIONS] [NAME] [SERVER]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;NAME&lt;/code&gt; — The domain name or IP address to look up.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SERVER&lt;/code&gt; — The DNS server to query. If omitted, &lt;code&gt;nslookup&lt;/code&gt; uses the server configured in &lt;code&gt;/etc/resolv.conf&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OPTIONS&lt;/code&gt; — Query options such as &lt;code&gt;-type=MX&lt;/code&gt; or &lt;code&gt;-debug&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When called without arguments, &lt;code&gt;nslookup&lt;/code&gt; starts in interactive mode.&lt;/p&gt;
&lt;h2 id="installing-nslookup"&gt;Installing nslookup &lt;a class="headline-link" href="#installing-nslookup" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;On most distributions &lt;code&gt;nslookup&lt;/code&gt; is already installed. To check, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nslookup -version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the command is not found, install it using your distribution&amp;rsquo;s package manager.&lt;/p&gt;
&lt;h3 id="install-nslookup-on-ubuntu-debian-and-derivatives"&gt;Install nslookup on Ubuntu, Debian, and Derivatives &lt;a class="headline-link" href="#install-nslookup-on-ubuntu-debian-and-derivatives" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo apt install dnsutils&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="install-nslookup-on-fedora-rhel-and-derivatives"&gt;Install nslookup on Fedora, RHEL, and Derivatives &lt;a class="headline-link" href="#install-nslookup-on-fedora-rhel-and-derivatives" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install bind-utils&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="install-nslookup-on-arch-linux"&gt;Install nslookup on Arch Linux &lt;a class="headline-link" href="#install-nslookup-on-arch-linux" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo pacman -S bind&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;nslookup&lt;/code&gt; command is bundled with the same packages that provide &lt;a href="https://linuxize.com/post/how-to-use-dig-command-to-query-dns-in-linux/"&gt;&lt;code&gt;dig&lt;/code&gt;&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="look-up-a-domain-name"&gt;Look Up a Domain Name &lt;a class="headline-link" href="#look-up-a-domain-name" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The simplest use is passing a domain name as an argument:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nslookup linux.org&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: linux.org
Address: 104.26.14.72
Name: linux.org
Address: 104.26.15.72
Name: linux.org
Address: 172.67.73.26&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first two lines show the DNS server that answered the query. Everything under &amp;ldquo;Non-authoritative answer&amp;rdquo; is the actual result. In this case, &lt;code&gt;linux.org&lt;/code&gt; resolves to three IPv4 addresses.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Non-authoritative&amp;rdquo; means the answer came from a resolver&amp;rsquo;s cache rather than directly from the domain&amp;rsquo;s authoritative name server.&lt;/p&gt;
&lt;h2 id="query-a-specific-dns-server"&gt;Query a Specific DNS Server &lt;a class="headline-link" href="#query-a-specific-dns-server" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;nslookup&lt;/code&gt; queries the resolver configured in &lt;code&gt;/etc/resolv.conf&lt;/code&gt;. To query a different server, add it as the last argument.&lt;/p&gt;
&lt;p&gt;For example, to query Google&amp;rsquo;s public DNS:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nslookup linux.org 8.8.8.8&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Server: 8.8.8.8
Address: 8.8.8.8#53
Non-authoritative answer:
Name: linux.org
Address: 104.26.14.72
Name: linux.org
Address: 104.26.15.72
Name: linux.org
Address: 172.67.73.26&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is useful when you want to compare results across different resolvers or verify whether a DNS change has propagated to public servers.&lt;/p&gt;
&lt;h2 id="query-record-types"&gt;Query Record Types &lt;a class="headline-link" href="#query-record-types" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;nslookup&lt;/code&gt; returns A (IPv4 address) records. Use the &lt;code&gt;-type&lt;/code&gt; option to query other record types.&lt;/p&gt;
&lt;h3 id="mx-records-mail-servers"&gt;MX Records (Mail Servers) &lt;a class="headline-link" href="#mx-records-mail-servers" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;MX records identify the mail servers responsible for receiving email for a domain:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nslookup -type&lt;span class="o"&gt;=&lt;/span&gt;mx google.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
google.com mail exchanger = 10 smtp.google.com.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The number before the mail server hostname is the priority. A lower number means higher priority.&lt;/p&gt;
&lt;h3 id="ns-records-name-servers"&gt;NS Records (Name Servers) &lt;a class="headline-link" href="#ns-records-name-servers" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;NS records show which name servers are authoritative for a domain:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nslookup -type&lt;span class="o"&gt;=&lt;/span&gt;ns google.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
google.com nameserver = ns1.google.com.
google.com nameserver = ns2.google.com.
google.com nameserver = ns3.google.com.
google.com nameserver = ns4.google.com.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="txt-records"&gt;TXT Records &lt;a class="headline-link" href="#txt-records" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;TXT records store arbitrary text data, commonly used for SPF, DKIM, and domain ownership verification:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nslookup -type&lt;span class="o"&gt;=&lt;/span&gt;txt google.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
google.com text = &amp;#34;v=spf1 include:_spf.google.com ~all&amp;#34;
google.com text = &amp;#34;facebook-domain-verification=22rm551cu4k0ab0bxsw536tlds4h95&amp;#34;
google.com text = &amp;#34;docusign=05958488-4752-4ef2-95eb-aa7ba8a3bd0e&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output may include many entries. The example above shows a subset of the TXT records returned for &lt;code&gt;google.com&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="aaaa-records-ipv6"&gt;AAAA Records (IPv6) &lt;a class="headline-link" href="#aaaa-records-ipv6" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;AAAA records return the IPv6 address of a domain:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nslookup -type&lt;span class="o"&gt;=&lt;/span&gt;aaaa google.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: google.com
Address: 2a00:1450:4017:818::200e&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="soa-record-start-of-authority"&gt;SOA Record (Start of Authority) &lt;a class="headline-link" href="#soa-record-start-of-authority" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The SOA record contains administrative information about the domain, including the primary name server, the responsible email address, and timing parameters for zone transfers:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nslookup -type&lt;span class="o"&gt;=&lt;/span&gt;soa google.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
google.com
origin = ns1.google.com
mail addr = dns-admin.google.com
serial = 897592583
refresh = 900
retry = 900
expire = 1800
minimum = 60&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;serial&lt;/code&gt; number increments each time the zone is updated. DNS secondaries use it to decide whether they need a zone transfer.&lt;/p&gt;
&lt;h3 id="cname-records"&gt;CNAME Records &lt;a class="headline-link" href="#cname-records" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;CNAME records point one domain name to another:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nslookup -type&lt;span class="o"&gt;=&lt;/span&gt;cname www.github.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If a CNAME record exists, the output shows the canonical name the alias points to. If the domain does not have a CNAME record, &lt;code&gt;nslookup&lt;/code&gt; returns &lt;code&gt;No answer&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="run-an-any-query"&gt;Run an &lt;code&gt;ANY&lt;/code&gt; Query &lt;a class="headline-link" href="#run-an-any-query" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To ask the DNS server for an &lt;code&gt;ANY&lt;/code&gt; response, use &lt;code&gt;-type=any&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nslookup -type&lt;span class="o"&gt;=&lt;/span&gt;any google.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;ANY&lt;/code&gt; queries do not reliably return every record type for a domain. Many DNS servers return only a subset of records or refuse the query entirely.&lt;/p&gt;
&lt;h2 id="reverse-dns-lookup"&gt;Reverse DNS Lookup &lt;a class="headline-link" href="#reverse-dns-lookup" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A reverse lookup finds the hostname associated with an IP address. Pass an IP address instead of a domain name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nslookup 208.118.235.148&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;148.235.118.208.in-addr.arpa name = ip-208-118-235-148.twdx.net.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Reverse lookups query PTR records. They are useful for verifying that an IP address maps back to the expected hostname, which matters for mail server configuration and security checks.&lt;/p&gt;
&lt;h2 id="interactive-mode"&gt;Interactive Mode &lt;a class="headline-link" href="#interactive-mode" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Running &lt;code&gt;nslookup&lt;/code&gt; without arguments starts an interactive session where you can run multiple queries without retyping the command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nslookup&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;At the &lt;code&gt;&amp;gt;&lt;/code&gt; prompt, type a domain name to look it up:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;&amp;gt; linux.org
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: linux.org
Address: 104.26.14.72
Name: linux.org
Address: 104.26.15.72&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can change query settings during the session with the &lt;code&gt;set&lt;/code&gt; command. For example, to switch to MX record lookups and then query a domain:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;&amp;gt; set type=mx
&amp;gt; google.com
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
google.com mail exchanger = 10 smtp.google.com.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To change the DNS server:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;&amp;gt; server 8.8.8.8
Default server: 8.8.8.8
Address: 8.8.8.8#53&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Type &lt;code&gt;exit&lt;/code&gt; to leave interactive mode.&lt;/p&gt;
&lt;p&gt;Interactive mode is convenient when you need to test several domains or record types in a row without running separate commands each time.&lt;/p&gt;
&lt;h2 id="debugging-dns-issues"&gt;Debugging DNS Issues &lt;a class="headline-link" href="#debugging-dns-issues" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;-debug&lt;/code&gt; option shows the full query and response details, including TTL values and additional sections that &lt;code&gt;nslookup&lt;/code&gt; normally hides:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nslookup -debug linux.org&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The debug output is verbose, but it is helpful when you need to see TTL values, check whether answers are authoritative, or trace unexpected behavior.&lt;/p&gt;
&lt;h2 id="nslookup-vs-dig"&gt;nslookup vs dig &lt;a class="headline-link" href="#nslookup-vs-dig" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Both &lt;code&gt;nslookup&lt;/code&gt; and &lt;a href="https://linuxize.com/post/how-to-use-dig-command-to-query-dns-in-linux/"&gt;&lt;code&gt;dig&lt;/code&gt;&lt;/a&gt;
query DNS servers, but they differ in output and capabilities:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nslookup&lt;/code&gt; produces simpler, more readable output. It also has an interactive mode that is convenient for quick checks.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dig&lt;/code&gt; provides detailed, structured output with sections (QUESTION, ANSWER, AUTHORITY, ADDITIONAL) and supports advanced options like &lt;code&gt;+trace&lt;/code&gt; for tracing the full resolution path and &lt;code&gt;+dnssec&lt;/code&gt; for verifying DNSSEC signatures.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For quick lookups and basic troubleshooting, &lt;code&gt;nslookup&lt;/code&gt; is often faster to type and read. For in-depth DNS debugging, &lt;code&gt;dig&lt;/code&gt; gives you more control and detail.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;nslookup returns NXDOMAIN&lt;/strong&gt;&lt;br&gt;
The domain does not exist or is misspelled. Verify the domain name and check that it is registered.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;nslookup returns SERVFAIL&lt;/strong&gt;&lt;br&gt;
The DNS server could not process the query. Try a different resolver to isolate the problem:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nslookup linux.org 1.1.1.1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If public resolvers return the correct answer, the issue is with your configured resolver.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Connection timed out; no servers could be reached&lt;/strong&gt;&lt;br&gt;
This means &lt;code&gt;nslookup&lt;/code&gt; could not contact the DNS server. Check your network connection and verify that &lt;code&gt;/etc/resolv.conf&lt;/code&gt; contains a reachable name server. A firewall may also be blocking outbound DNS traffic on port 53.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Non-authoritative answer appears on every query&lt;/strong&gt;&lt;br&gt;
This is normal. It means the answer came from a resolver&amp;rsquo;s cache, not directly from the domain&amp;rsquo;s authoritative server. The result is still valid.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/nslookup/"&gt;nslookup cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Look up a domain&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nslookup example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Query a specific DNS server&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nslookup example.com 8.8.8.8&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Query MX records&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nslookup -type=mx example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Query NS records&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nslookup -type=ns example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Query TXT records&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nslookup -type=txt example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Query AAAA (IPv6) records&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nslookup -type=aaaa example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Query SOA record&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nslookup -type=soa example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Query CNAME record&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nslookup -type=cname example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Run an &lt;code&gt;ANY&lt;/code&gt; query&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nslookup -type=any example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reverse DNS lookup&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nslookup 192.0.2.1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Start interactive mode&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nslookup&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enable debug output&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nslookup -debug example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Can I use nslookup to check DNS propagation?&lt;/strong&gt;&lt;br&gt;
Yes. Query the same domain against several public DNS servers and compare the results. For example, run &lt;code&gt;nslookup example.com 8.8.8.8&lt;/code&gt;, &lt;code&gt;nslookup example.com 1.1.1.1&lt;/code&gt;, and &lt;code&gt;nslookup example.com 9.9.9.9&lt;/code&gt;. If the answers differ, the change has not fully propagated.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is nslookup deprecated?&lt;/strong&gt;&lt;br&gt;
The ISC (the organization behind BIND) once marked &lt;code&gt;nslookup&lt;/code&gt; as deprecated in favor of &lt;code&gt;dig&lt;/code&gt;, but later reversed that decision. &lt;code&gt;nslookup&lt;/code&gt; is actively maintained and included in current BIND releases. It remains a practical tool for quick DNS lookups.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What does &amp;ldquo;Non-authoritative answer&amp;rdquo; mean?&lt;/strong&gt;&lt;br&gt;
It means the response came from a caching resolver, not from one of the domain&amp;rsquo;s authoritative name servers. The data is still accurate, but it may be slightly behind if a DNS change was made very recently and the cache has not expired yet.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;nslookup&lt;/code&gt; command is a quick way to query DNS records from the command line. Use &lt;code&gt;-type&lt;/code&gt; to look up MX, NS, TXT, AAAA, and other record types, and pass a server argument to test against a specific resolver. For deeper DNS debugging, pair it with &lt;a href="https://linuxize.com/post/how-to-use-dig-command-to-query-dns-in-linux/"&gt;&lt;code&gt;dig&lt;/code&gt;&lt;/a&gt;
. To look up domain ownership and registration details instead of DNS records, use the &lt;a href="https://linuxize.com/post/whois-command-in-linux/"&gt;&lt;code&gt;whois&lt;/code&gt; command&lt;/a&gt;
.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/nslookup-command-in-linux/featured_hu_bfa5d0065cd76e20.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>env Command in Linux: Show and Set Environment Variables</title><link>https://linuxize.com/post/env-command-in-linux/</link><pubDate>Tue, 07 Apr 2026 10:30:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/env-command-in-linux/</guid><category>linux commands</category><description>The env command prints environment variables and runs programs with a modified environment. This guide covers env syntax, running commands with custom variables, clean environments, and portable shebangs.</description><content:encoded>&lt;p&gt;When you need to run a program with a different set of variables, test a script in a clean environment, or write a shebang line that works across systems, the &lt;code&gt;env&lt;/code&gt; command is the right tool. It prints the current environment, sets or removes variables for a single command, and can even start a process with no inherited variables at all.&lt;/p&gt;
&lt;p&gt;This guide covers how to use the &lt;code&gt;env&lt;/code&gt; command with practical examples for everyday tasks.&lt;/p&gt;
&lt;h2 id="env-syntax"&gt;env Syntax &lt;a class="headline-link" href="#env-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;env [OPTIONS] [NAME=VALUE]... [COMMAND [ARGS]]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When called without arguments, &lt;code&gt;env&lt;/code&gt; prints every environment variable in the current session, one per line. When followed by &lt;code&gt;NAME=VALUE&lt;/code&gt; pairs and a command, it runs that command with the specified variables added or changed without affecting the current shell.&lt;/p&gt;
&lt;h2 id="print-all-environment-variables"&gt;Print All Environment Variables &lt;a class="headline-link" href="#print-all-environment-variables" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The simplest use of &lt;code&gt;env&lt;/code&gt; is printing the full environment:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;env&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;SHELL=/bin/bash
USER=john
HOME=/home/john
LANG=en_US.UTF-8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
TERM=xterm-256color
XDG_SESSION_TYPE=tty
EDITOR=vim&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Each line is a &lt;code&gt;KEY=value&lt;/code&gt; pair. This is identical to what &lt;code&gt;printenv&lt;/code&gt; shows with no arguments. The difference between the two commands becomes clear when you start passing options: &lt;code&gt;printenv&lt;/code&gt; is designed for inspecting variables, while &lt;code&gt;env&lt;/code&gt; is designed for modifying the environment before launching a program.&lt;/p&gt;
&lt;h2 id="print-variables-with-nul-separator"&gt;Print Variables with NUL Separator &lt;a class="headline-link" href="#print-variables-with-nul-separator" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;env&lt;/code&gt; separates each variable with a newline character. If variable values contain newlines themselves, the output becomes ambiguous. The &lt;code&gt;-0&lt;/code&gt; (or &lt;code&gt;--null&lt;/code&gt;) option ends each entry with a NUL byte instead:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;env -0 &lt;span class="p"&gt;|&lt;/span&gt; tr &lt;span class="s1"&gt;&amp;#39;\0&amp;#39;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;\n&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; head -5&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is useful when piping environment data into tools that expect NUL-delimited input, such as &lt;a href="https://linuxize.com/post/linux-xargs-command/"&gt;&lt;code&gt;xargs&lt;/code&gt;&lt;/a&gt;
with its &lt;code&gt;-0&lt;/code&gt; flag.&lt;/p&gt;
&lt;h2 id="run-a-command-with-modified-variables"&gt;Run a Command with Modified Variables &lt;a class="headline-link" href="#run-a-command-with-modified-variables" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The most practical feature of &lt;code&gt;env&lt;/code&gt; is launching a command with variables changed for that command only. Place &lt;code&gt;NAME=VALUE&lt;/code&gt; pairs before the command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;env &lt;span class="nv"&gt;LANG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;C sort unsorted.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This runs &lt;code&gt;sort&lt;/code&gt; with &lt;code&gt;LANG&lt;/code&gt; set to &lt;code&gt;C&lt;/code&gt;, which forces byte-order sorting regardless of the system locale. The current shell&amp;rsquo;s &lt;code&gt;LANG&lt;/code&gt; value stays unchanged after the command finishes.&lt;/p&gt;
&lt;p&gt;You can set multiple variables at once:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;env &lt;span class="nv"&gt;DB_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;localhost &lt;span class="nv"&gt;DB_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;5432&lt;/span&gt; python3 app.py&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The application sees &lt;code&gt;DB_HOST&lt;/code&gt; and &lt;code&gt;DB_PORT&lt;/code&gt; in its environment, but those variables do not persist in your shell session after the process exits.&lt;/p&gt;
&lt;div class="note callout callout-tip"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50"&gt;
&lt;path d="M25 6c-1.645 0-3 1.355-3 3v1.406c-1.945.457-3.645 1.36-4.953 2.676C15.094 15.055 14 17.848 14 21.062v7.801c0 1.836-1.004 4.164-2.04 5.89l-1.792 2.692a1.01 1.01 0 0 0-.05 1.028c.175.324.515.527.882.527h9c0 2.746 2.254 5 5 5s5-2.254 5-5h9c.367 0 .707-.203.883-.527a1.01 1.01 0 0 0-.051-1.028l-1.785-2.68-.004-.003C36.996 33.016 36 30.836 36 29v-7.8c0-5.368-3.195-9.524-8-10.759V9c0-1.645-1.355-3-3-3zm0 2c.555 0 1 .445 1 1v1.113c-.223-.02-.441-.043-.668-.05A1.064 1.064 0 0 0 25 10c-.11 0-.215.02-.316.059-.235.004-.457.027-.684.043V9c0-.555.445-1 1-1zM3.48 9.477C1.25 13.102 0 17.418 0 22s1.25 8.898 3.48 12.523l1.708-1.046C3.151 30.168 2 26.219 2 22s1.152-8.168 3.188-11.477zm43.04 0l-1.708 1.046C46.849 13.832 48 17.781 48 22s-1.152 8.168-3.188 11.477l1.708 1.046C48.75 30.898 50 26.582 50 22s-1.25-8.898-3.48-12.523zM25 12c5.512 0 9 3.668 9 9.2V29c0 2.512 1.203 4.918 2.328 6.797.012.012.02.027.027.039L37.13 37H12.87l.774-1.164c.007-.012.015-.027.027-.04C14.809 33.903 16 31.376 16 28.864v-7.8c0-2.766.914-5.004 2.469-6.57C20.019 12.925 22.239 12 25 12zm-17.184.14C5.996 15.083 5 18.356 5 22c0 3.672 1.129 7.047 2.809 9.848l1.714-1.032C8.008 28.286 7 25.262 7 22c0-3.29.871-6.148 2.516-8.809zm34.368 0l-1.7 1.051C42.13 15.851 43 18.711 43 22c0 3.262-1.008 6.285-2.527 8.816l1.718 1.032C43.871 29.047 45 25.672 45 22c0-3.645-.996-6.918-2.816-9.86zM22 39h6a3 3 0 0 1-6 0z"/&gt;
&lt;/svg&gt;
&lt;span class="callout-title"&gt;Tip&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;You can achieve the same result with the shell&amp;rsquo;s built-in &lt;code&gt;VAR=value command&lt;/code&gt; syntax (for example, &lt;code&gt;LANG=C sort unsorted.txt&lt;/code&gt;). The &lt;code&gt;env&lt;/code&gt; command is useful when you need additional options like &lt;code&gt;-i&lt;/code&gt; or &lt;code&gt;-u&lt;/code&gt;, or when you want to be explicit about environment manipulation in scripts.&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="run-a-command-in-a-clean-environment"&gt;Run a Command in a Clean Environment &lt;a class="headline-link" href="#run-a-command-in-a-clean-environment" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;-i&lt;/code&gt; (or &lt;code&gt;--ignore-environment&lt;/code&gt;) option clears the entire inherited environment before running the command. Only the variables you explicitly set on the command line will be present:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;env -i bash -c &lt;span class="s1"&gt;&amp;#39;env&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;PWD=/home/john
SHLVL=1
_=/usr/bin/env&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output shows almost nothing. The shell itself sets a few internal variables (&lt;code&gt;PWD&lt;/code&gt;, &lt;code&gt;SHLVL&lt;/code&gt;, &lt;code&gt;_&lt;/code&gt;), but everything the parent shell normally passes along (&lt;code&gt;PATH&lt;/code&gt;, &lt;code&gt;HOME&lt;/code&gt;, &lt;code&gt;LANG&lt;/code&gt;, &lt;code&gt;USER&lt;/code&gt;) is gone.&lt;/p&gt;
&lt;p&gt;This is useful for testing whether a script depends on variables it does not set itself. You can combine &lt;code&gt;-i&lt;/code&gt; with explicit variables to create a minimal, controlled environment:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;env -i &lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/home/john &lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/bin:/bin bash -c &lt;span class="s1"&gt;&amp;#39;echo $HOME; echo $PATH&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;/home/john
/usr/bin:/bin&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A bare &lt;code&gt;-&lt;/code&gt; (hyphen) works as a shorthand for &lt;code&gt;-i&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;env - &lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/bin bash -c &lt;span class="s1"&gt;&amp;#39;echo $PATH&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="unset-a-variable-for-a-command"&gt;Unset a Variable for a Command &lt;a class="headline-link" href="#unset-a-variable-for-a-command" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;-u&lt;/code&gt; (or &lt;code&gt;--unset&lt;/code&gt;) option removes a specific variable from the environment before running the command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;env -u EDITOR vim&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This launches &lt;code&gt;vim&lt;/code&gt; without the &lt;code&gt;EDITOR&lt;/code&gt; variable in its environment. Other variables remain untouched. You can unset multiple variables by repeating &lt;code&gt;-u&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;env -u LANG -u LC_ALL python3 script.py&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The difference from &lt;code&gt;-i&lt;/code&gt; is that &lt;code&gt;-u&lt;/code&gt; is surgical: it removes only the named variables and leaves everything else in place.&lt;/p&gt;
&lt;h2 id="change-directory-before-running-a-command"&gt;Change Directory Before Running a Command &lt;a class="headline-link" href="#change-directory-before-running-a-command" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;-C&lt;/code&gt; (or &lt;code&gt;--chdir&lt;/code&gt;) option changes the working directory before executing the command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;env -C /var/log cat syslog &lt;span class="p"&gt;|&lt;/span&gt; head -3&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is equivalent to running &lt;code&gt;cd /var/log &amp;amp;&amp;amp; cat syslog&lt;/code&gt;, but without affecting the current shell&amp;rsquo;s working directory. It is a convenient way to run a command in another directory from within a script or one-liner.&lt;/p&gt;
&lt;div class="note callout callout-info"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" &gt;
&lt;path d="M 16 3 C 8.832031 3 3 8.832031 3 16 C 3 23.167969 8.832031 29 16 29 C 23.167969 29 29 23.167969 29 16 C 29 8.832031 23.167969 3 16 3 Z M 16 5 C 22.085938 5 27 9.914063 27 16 C 27 22.085938 22.085938 27 16 27 C 9.914063 27 5 22.085938 5 16 C 5 9.914063 9.914063 5 16 5 Z M 15 10 L 15 12 L 17 12 L 17 10 Z M 15 14 L 15 22 L 17 22 L 17 14 Z "&gt;&lt;/path&gt;
&lt;/svg&gt;&lt;span class="callout-title"&gt;Info&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;The &lt;code&gt;-C&lt;/code&gt; option requires GNU coreutils 8.28 or later. Check your version with &lt;code&gt;env --version&lt;/code&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="using-env-in-shebangs"&gt;Using env in Shebangs &lt;a class="headline-link" href="#using-env-in-shebangs" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One of the most common uses of &lt;code&gt;env&lt;/code&gt; is in shebang lines at the top of scripts:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Hello from Bash&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When the kernel encounters &lt;code&gt;#!/usr/bin/env bash&lt;/code&gt;, it runs &lt;code&gt;/usr/bin/env&lt;/code&gt; with &lt;code&gt;bash&lt;/code&gt; as its argument. &lt;code&gt;env&lt;/code&gt; then searches the &lt;code&gt;PATH&lt;/code&gt; for the &lt;code&gt;bash&lt;/code&gt; executable and runs it. This is more portable than hardcoding &lt;code&gt;#!/bin/bash&lt;/code&gt;, because &lt;code&gt;bash&lt;/code&gt; is not always located in &lt;code&gt;/bin&lt;/code&gt; on every system (for example, on FreeBSD it is typically at &lt;code&gt;/usr/local/bin/bash&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;The same pattern works for other interpreters:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#!/usr/bin/env python3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#!/usr/bin/env node&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On systems with GNU coreutils 8.30 or later, you can pass arguments to the interpreter using the &lt;code&gt;-S&lt;/code&gt; (split string) option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#!/usr/bin/env -S python3 -u&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Without &lt;code&gt;-S&lt;/code&gt;, the kernel treats &lt;code&gt;python3 -u&lt;/code&gt; as a single argument. The &lt;code&gt;-S&lt;/code&gt; option tells &lt;code&gt;env&lt;/code&gt; to split the string into separate arguments before executing.&lt;/p&gt;
&lt;h2 id="env-options"&gt;env Options &lt;a class="headline-link" href="#env-options" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-i&lt;/code&gt;, &lt;code&gt;--ignore-environment&lt;/code&gt; - Start with an empty environment&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-u NAME&lt;/code&gt;, &lt;code&gt;--unset=NAME&lt;/code&gt; - Remove NAME from the environment&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-C DIR&lt;/code&gt;, &lt;code&gt;--chdir=DIR&lt;/code&gt; - Change working directory to DIR before running the command&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-0&lt;/code&gt;, &lt;code&gt;--null&lt;/code&gt; - End each output line with a NUL byte instead of a newline&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-S STRING&lt;/code&gt;, &lt;code&gt;--split-string=STRING&lt;/code&gt; - Split STRING into separate arguments (useful in shebangs)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-v&lt;/code&gt;, &lt;code&gt;--debug&lt;/code&gt; - Print verbose information for each processing step&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--block-signal=SIG&lt;/code&gt; - Block delivery of the specified signal to the command&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--default-signal=SIG&lt;/code&gt; - Reset signal handling to the default for the command&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--ignore-signal=SIG&lt;/code&gt; - Set signal handling to ignore for the command&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/env/"&gt;env cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;env&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Print all environment variables&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;env -0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Print variables with NUL separator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;env VAR=value command&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run a command with a modified variable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;env -i command&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run a command in a clean environment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;env -i VAR=value command&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run a command with only the specified variables&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;env -u VAR command&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run a command with a variable removed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;env -C /path command&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run a command in a different directory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;#!/usr/bin/env bash&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Portable shebang line&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;#!/usr/bin/env -S python3 -u&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Shebang with interpreter arguments&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between env and printenv?&lt;/strong&gt;&lt;br&gt;
Both commands print environment variables when called without arguments. The difference is in their purpose: &lt;code&gt;printenv&lt;/code&gt; is a read-only inspection tool that can print individual variables by name (&lt;code&gt;printenv HOME&lt;/code&gt;). &lt;code&gt;env&lt;/code&gt; is designed to modify the environment and run commands. Use &lt;code&gt;printenv&lt;/code&gt; when you need to check a value, and &lt;code&gt;env&lt;/code&gt; when you need to change the environment for a process.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between env and export?&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://linuxize.com/post/export-command-in-linux/"&gt;&lt;code&gt;export&lt;/code&gt;&lt;/a&gt;
is a shell built-in that adds a variable to the current shell&amp;rsquo;s environment permanently (until the session ends or you &lt;code&gt;unset&lt;/code&gt; it). &lt;code&gt;env&lt;/code&gt; sets variables only for the duration of a single command and does not affect the current shell. If you need a variable to persist for all subsequent commands in your session, use &lt;code&gt;export&lt;/code&gt;. If you need a variable set for one command only, use &lt;code&gt;env&lt;/code&gt; or the shell&amp;rsquo;s &lt;code&gt;VAR=value command&lt;/code&gt; syntax.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When should I use env -i?&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;env -i&lt;/code&gt; when you want to verify that a script or program works without relying on inherited environment variables. It is also useful in security-sensitive contexts where you want to prevent a child process from seeing variables like &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt; or database credentials that exist in the parent shell.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why use #!/usr/bin/env bash instead of #!/bin/bash?&lt;/strong&gt;&lt;br&gt;
The &lt;code&gt;env&lt;/code&gt;-based shebang is more portable. On most Linux distributions, &lt;code&gt;bash&lt;/code&gt; lives at &lt;code&gt;/bin/bash&lt;/code&gt;, but on other Unix systems (FreeBSD, macOS with Homebrew, NixOS) it may be installed elsewhere. Using &lt;code&gt;#!/usr/bin/env bash&lt;/code&gt; searches the &lt;code&gt;PATH&lt;/code&gt; for the interpreter, so the script works regardless of where &lt;code&gt;bash&lt;/code&gt; is installed.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;env&lt;/code&gt; command gives you fine-grained control over the environment a process sees without touching your current shell session. For a broader look at how environment and shell variables work in Linux, including persistent configuration and the &lt;code&gt;PATH&lt;/code&gt; variable, see the guide on &lt;a href="https://linuxize.com/post/how-to-set-and-list-environment-variables-in-linux/"&gt;how to set and list environment variables&lt;/a&gt;
.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/env-command-in-linux/featured_hu_8d09fc59998b8716.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>htop Command in Linux: Monitor Processes Interactively</title><link>https://linuxize.com/post/htop-command-in-linux/</link><pubDate>Mon, 06 Apr 2026 11:00:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/htop-command-in-linux/</guid><category>linux commands</category><description>htop is an interactive process viewer for Linux that shows CPU, memory, and swap usage in real time. This guide covers sorting, filtering, tree view, killing processes, and customizing the display.</description><content:encoded>&lt;p&gt;When a server starts responding slowly or a desktop session feels sluggish, you need to figure out which process is consuming the most CPU or memory. The &lt;a href="https://linuxize.com/post/top-command-in-linux/"&gt;&lt;code&gt;top&lt;/code&gt;&lt;/a&gt;
command can do this, but its interface is minimal and navigation takes some getting used to. &lt;code&gt;htop&lt;/code&gt; is an interactive process viewer that improves on &lt;code&gt;top&lt;/code&gt; with color-coded meters, mouse support, and the ability to scroll, search, filter, and kill processes without leaving the viewer.&lt;/p&gt;
&lt;p&gt;This guide explains how to install and use &lt;code&gt;htop&lt;/code&gt; to monitor system resources and manage processes on Linux.&lt;/p&gt;
&lt;h2 id="installing-htop"&gt;Installing htop &lt;a class="headline-link" href="#installing-htop" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;htop&lt;/code&gt; is available in the default repositories of most Linux distributions but is not always pre-installed.&lt;/p&gt;
&lt;p&gt;On Ubuntu, Debian, and Derivatives:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install htop&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Fedora, RHEL, and Derivatives:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install htop&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Verify the installation by checking the version:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;htop --version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;htop 3.4.1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="htop-syntax"&gt;htop Syntax &lt;a class="headline-link" href="#htop-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;htop [OPTIONS]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Running &lt;code&gt;htop&lt;/code&gt; without arguments opens the interactive process viewer with default settings:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;htop&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="understanding-the-interface"&gt;Understanding the Interface &lt;a class="headline-link" href="#understanding-the-interface" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;htop&lt;/code&gt; screen is divided into three areas: a header with system meters, a process list in the center, and a footer with function key shortcuts.&lt;/p&gt;
&lt;h3 id="header-area"&gt;Header Area &lt;a class="headline-link" href="#header-area" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The top section shows system-wide resource usage at a glance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CPU bars&lt;/strong&gt;: one bar per CPU core, color-coded by usage type. Green is normal user processes, red is kernel (system) activity, blue is low-priority (nice) processes, and cyan is virtualization overhead (steal time)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Memory bar&lt;/strong&gt;: shows used, buffered, and cached memory as a proportion of total RAM. Green is memory in use by applications, blue is buffers, and yellow is file cache&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Swap bar&lt;/strong&gt;: shows swap usage. If this bar is consistently full, the system does not have enough physical memory for its workload&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tasks&lt;/strong&gt;: total number of processes and threads, with a count of how many are currently running&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Load average&lt;/strong&gt;: the 1-minute, 5-minute, and 15-minute system load averages&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Uptime&lt;/strong&gt;: how long the system has been running since the last boot&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="process-list"&gt;Process List &lt;a class="headline-link" href="#process-list" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Below the header, each row represents one process. The default columns are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;PID&lt;/code&gt; - process ID&lt;/li&gt;
&lt;li&gt;&lt;code&gt;USER&lt;/code&gt; - the owner of the process&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PRI&lt;/code&gt; - kernel scheduling priority&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NI&lt;/code&gt; - nice value (user-space priority, ranges from -20 to 19)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;VIRT&lt;/code&gt; - total virtual memory the process has allocated&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RES&lt;/code&gt; - resident memory, the portion of physical RAM the process is actually using&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SHR&lt;/code&gt; - shared memory, the portion of RES that is shared with other processes (such as shared libraries)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;S&lt;/code&gt; - process state (&lt;code&gt;R&lt;/code&gt; running, &lt;code&gt;S&lt;/code&gt; sleeping, &lt;code&gt;D&lt;/code&gt; uninterruptible sleep, &lt;code&gt;Z&lt;/code&gt; zombie, &lt;code&gt;T&lt;/code&gt; stopped)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CPU%&lt;/code&gt; - percentage of CPU time the process is using&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MEM%&lt;/code&gt; - percentage of physical memory the process is using&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TIME+&lt;/code&gt; - total CPU time consumed since the process started&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Command&lt;/code&gt; - the full command line that launched the process&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="function-keys"&gt;Function Keys &lt;a class="headline-link" href="#function-keys" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The bottom bar shows the available actions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;F1&lt;/code&gt; - open the help screen&lt;/li&gt;
&lt;li&gt;&lt;code&gt;F2&lt;/code&gt; - open the setup menu to customize meters and columns&lt;/li&gt;
&lt;li&gt;&lt;code&gt;F3&lt;/code&gt; - search for a process by name&lt;/li&gt;
&lt;li&gt;&lt;code&gt;F4&lt;/code&gt; - filter the process list to show only matching entries&lt;/li&gt;
&lt;li&gt;&lt;code&gt;F5&lt;/code&gt; - toggle tree view&lt;/li&gt;
&lt;li&gt;&lt;code&gt;F6&lt;/code&gt; - choose a column to sort by&lt;/li&gt;
&lt;li&gt;&lt;code&gt;F7&lt;/code&gt; - decrease the nice value (higher priority) of the selected process&lt;/li&gt;
&lt;li&gt;&lt;code&gt;F8&lt;/code&gt; - increase the nice value (lower priority) of the selected process&lt;/li&gt;
&lt;li&gt;&lt;code&gt;F9&lt;/code&gt; - send a signal to the selected process&lt;/li&gt;
&lt;li&gt;&lt;code&gt;F10&lt;/code&gt; - quit htop&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="sorting-processes"&gt;Sorting Processes &lt;a class="headline-link" href="#sorting-processes" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;htop&lt;/code&gt; sorts processes by CPU usage, so the heaviest processes float to the top. To change the sort column, press &lt;code&gt;F6&lt;/code&gt; and select a column from the list using the arrow keys.&lt;/p&gt;
&lt;p&gt;For quick sorting without opening the menu, use these shortcut keys:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;P&lt;/code&gt; - sort by CPU%&lt;/li&gt;
&lt;li&gt;&lt;code&gt;M&lt;/code&gt; - sort by MEM%&lt;/li&gt;
&lt;li&gt;&lt;code&gt;T&lt;/code&gt; - sort by TIME+&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Press the same key again to reverse the sort order. This is useful when you want to find the least active processes or the ones that started most recently.&lt;/p&gt;
&lt;p&gt;You can also set the initial sort column from the command line:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;htop -s PERCENT_MEM&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This starts &lt;code&gt;htop&lt;/code&gt; with the process list sorted by memory usage, which is handy when you are investigating high memory consumption on a server.&lt;/p&gt;
&lt;h2 id="searching-for-a-process"&gt;Searching for a Process &lt;a class="headline-link" href="#searching-for-a-process" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Press &lt;code&gt;F3&lt;/code&gt; (or &lt;code&gt;/&lt;/code&gt;) to open the search bar at the bottom of the screen. Type part of the process name and &lt;code&gt;htop&lt;/code&gt; will highlight the first matching entry in the process list. Press &lt;code&gt;F3&lt;/code&gt; again to jump to the next match.&lt;/p&gt;
&lt;p&gt;The search is incremental, so the highlight updates as you type each character. Press &lt;code&gt;Esc&lt;/code&gt; to close the search bar and return to normal navigation.&lt;/p&gt;
&lt;h2 id="filtering-processes"&gt;Filtering Processes &lt;a class="headline-link" href="#filtering-processes" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Press &lt;code&gt;F4&lt;/code&gt; to activate the filter. Unlike search, which jumps between matches, filtering hides all processes that do not match the text you type. Only matching entries remain visible in the list.&lt;/p&gt;
&lt;p&gt;This is especially useful on busy systems with hundreds of running processes. For example, typing &lt;code&gt;postgres&lt;/code&gt; after pressing &lt;code&gt;F4&lt;/code&gt; reduces the list to only PostgreSQL worker processes and the postmaster, making it much easier to see their combined resource usage.&lt;/p&gt;
&lt;p&gt;Press &lt;code&gt;Esc&lt;/code&gt; to clear the filter and restore the full process list.&lt;/p&gt;
&lt;h2 id="tree-view"&gt;Tree View &lt;a class="headline-link" href="#tree-view" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Press &lt;code&gt;F5&lt;/code&gt; to toggle tree view. In this mode, &lt;code&gt;htop&lt;/code&gt; groups child processes under their parent and displays the process hierarchy as an indented tree. This makes it straightforward to see which processes were spawned by a service manager, a shell session, or a container runtime.&lt;/p&gt;
&lt;p&gt;To start &lt;code&gt;htop&lt;/code&gt; in tree view directly from the command line:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;htop -t&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Tree view combines well with filtering. Press &lt;code&gt;F4&lt;/code&gt;, type a service name, and the tree shows only that service and its child processes. For a dedicated look at process hierarchies outside of &lt;code&gt;htop&lt;/code&gt;, see the &lt;a href="https://linuxize.com/post/pstree-command-in-linux/"&gt;&lt;code&gt;pstree&lt;/code&gt; command&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="killing-a-process"&gt;Killing a Process &lt;a class="headline-link" href="#killing-a-process" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To stop a process from within &lt;code&gt;htop&lt;/code&gt;, use the arrow keys to highlight it (or search with &lt;code&gt;F3&lt;/code&gt;), then press &lt;code&gt;F9&lt;/code&gt;. This opens a signal selection menu on the left side of the screen.&lt;/p&gt;
&lt;p&gt;The most commonly used signals are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;15 SIGTERM&lt;/code&gt; - asks the process to shut down gracefully. This is the default and the safest first choice&lt;/li&gt;
&lt;li&gt;&lt;code&gt;9 SIGKILL&lt;/code&gt; - forces the process to terminate immediately. Use this only when SIGTERM does not work, because the process gets no chance to clean up&lt;/li&gt;
&lt;li&gt;&lt;code&gt;2 SIGINT&lt;/code&gt; - the same signal sent by pressing &lt;code&gt;Ctrl+C&lt;/code&gt; in a terminal&lt;/li&gt;
&lt;li&gt;&lt;code&gt;1 SIGHUP&lt;/code&gt; - often used to tell a daemon to reload its configuration without restarting&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Select the signal with the arrow keys and press &lt;code&gt;Enter&lt;/code&gt; to send it. For more detail on process signals and how to send them from the command line, see the &lt;a href="https://linuxize.com/post/kill-command-in-linux/"&gt;&lt;code&gt;kill&lt;/code&gt; command guide&lt;/a&gt;
.&lt;/p&gt;
&lt;div class="note callout callout-warning"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"&gt;
&lt;path d="M10 20C4.477 20 0 15.523 0 10S4.477 0 10 0s10 4.477 10 10-4.477 10-10 10zm0-2c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm-.5-5h1c.276 0 .5.224.5.5v1c0 .276-.224.5-.5.5h-1c-.276 0-.5-.224-.5-.5v-1c0-.276.224-.5.5-.5zm0-8h1c.276 0 .5.224.5.5V8l-.5 3-1 .5L9 8V5.5c0-.276.224-.5.5-.5z"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;span class="callout-title"&gt;Warning&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;&lt;code&gt;SIGKILL&lt;/code&gt; bypasses all cleanup routines. Files and sockets may be left in an inconsistent state. Always try &lt;code&gt;SIGTERM&lt;/code&gt; first and wait a few seconds before escalating to &lt;code&gt;SIGKILL&lt;/code&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You can also tag multiple processes with &lt;code&gt;Space&lt;/code&gt; and then press &lt;code&gt;F9&lt;/code&gt; to send a signal to all of them at once. Press &lt;code&gt;U&lt;/code&gt; to untag all processes when you are done.&lt;/p&gt;
&lt;h2 id="changing-process-priority"&gt;Changing Process Priority &lt;a class="headline-link" href="#changing-process-priority" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can adjust the scheduling priority (nice value) of a process directly from &lt;code&gt;htop&lt;/code&gt;. Select the process and press:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;F7&lt;/code&gt; - decrease the nice value (give the process higher priority)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;F8&lt;/code&gt; - increase the nice value (give the process lower priority)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nice values range from -20 (highest priority) to 19 (lowest priority). Only root can set negative nice values, so you will need to run &lt;code&gt;htop&lt;/code&gt; with &lt;code&gt;sudo&lt;/code&gt; to raise a process above normal priority.&lt;/p&gt;
&lt;p&gt;This is useful when a background task like a large compilation is consuming too much CPU and you want to lower its priority so that interactive services remain responsive.&lt;/p&gt;
&lt;h2 id="showing-only-one-users-processes"&gt;Showing Only One User&amp;rsquo;s Processes &lt;a class="headline-link" href="#showing-only-one-users-processes" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To limit the process list to a single user, start &lt;code&gt;htop&lt;/code&gt; with the &lt;code&gt;-u&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;htop -u www-data&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This shows only processes owned by &lt;code&gt;www-data&lt;/code&gt;, which is useful when you are debugging a web server or an application service and do not want system processes cluttering the view.&lt;/p&gt;
&lt;h2 id="monitoring-specific-processes"&gt;Monitoring Specific Processes &lt;a class="headline-link" href="#monitoring-specific-processes" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To watch a known set of processes by their PIDs, use the &lt;code&gt;-p&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;htop -p 1234,5678&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The display is restricted to those two processes, but the header meters still show system-wide resource usage. This gives you a focused view while keeping overall load visible at the top.&lt;/p&gt;
&lt;h2 id="customizing-the-display"&gt;Customizing the Display &lt;a class="headline-link" href="#customizing-the-display" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Press &lt;code&gt;F2&lt;/code&gt; to open the setup screen. From here you can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rearrange the header meters (move CPU bars, swap positions, switch between bar, text, graph, or LED display styles)&lt;/li&gt;
&lt;li&gt;Add or remove columns in the process list&lt;/li&gt;
&lt;li&gt;Change the color scheme&lt;/li&gt;
&lt;li&gt;Toggle display options like showing kernel threads or custom thread names&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Changes are saved to &lt;code&gt;~/.config/htop/htoprc&lt;/code&gt; and persist across sessions.&lt;/p&gt;
&lt;h2 id="command-line-options"&gt;Command-Line Options &lt;a class="headline-link" href="#command-line-options" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-d N&lt;/code&gt; - set the update interval to N tenths of a second. For example, &lt;code&gt;-d 20&lt;/code&gt; updates every 2 seconds instead of the default 1.5 seconds&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-u USER&lt;/code&gt; - show only processes belonging to USER&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-p PID[,PID...]&lt;/code&gt; - show only the specified process IDs&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-t&lt;/code&gt; - start in tree view&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-s COLUMN&lt;/code&gt; - sort by the given column name (use names like &lt;code&gt;PERCENT_CPU&lt;/code&gt;, &lt;code&gt;PERCENT_MEM&lt;/code&gt;, &lt;code&gt;TIME&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-C&lt;/code&gt; - use monochrome mode (no colors), useful on terminals with limited color support&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-H&lt;/code&gt; - highlight new and old processes&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/htop/"&gt;htop cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Key / Command&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;F1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Help&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;F2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Setup (customize meters and columns)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;F3&lt;/code&gt; or &lt;code&gt;/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Search for a process&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;F4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Filter the process list&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;F5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Toggle tree view&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;F6&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Choose sort column&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;F7&lt;/code&gt; / &lt;code&gt;F8&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Decrease / increase nice value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;F9&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Send a signal to the selected process&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;F10&lt;/code&gt; or &lt;code&gt;q&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Quit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;P&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sort by CPU%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;M&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sort by MEM%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;T&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sort by TIME+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Space&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Tag a process&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;U&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Untag all processes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;htop -u USER&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show only one user&amp;rsquo;s processes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;htop -p PID,PID&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Monitor specific PIDs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;htop -t&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Start in tree view&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;htop -d 20&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Update every 2 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;htop -s PERCENT_MEM&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sort by memory usage&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;htop: command not found&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;htop&lt;/code&gt; is not installed by default on every distribution. Install it with your package manager: &lt;code&gt;sudo apt install htop&lt;/code&gt; on Debian-based systems or &lt;code&gt;sudo dnf install htop&lt;/code&gt; on Fedora and RHEL.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cannot change process priority (permission denied)&lt;/strong&gt;&lt;br&gt;
Setting a nice value below 0 requires root privileges. Run &lt;code&gt;htop&lt;/code&gt; with &lt;code&gt;sudo&lt;/code&gt; to adjust priority for processes owned by other users or to set negative nice values.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CPU bars show unexpected colors&lt;/strong&gt;&lt;br&gt;
Each color represents a different type of CPU usage. Green is normal user processes, red is kernel activity, blue is low-priority (nice) processes, and cyan is virtualization steal time. Press &lt;code&gt;F1&lt;/code&gt; inside &lt;code&gt;htop&lt;/code&gt; to see the full color legend for your version.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Memory bar looks full but the system is responsive&lt;/strong&gt;&lt;br&gt;
Linux uses free memory for disk cache and buffers. The memory bar in &lt;code&gt;htop&lt;/code&gt; distinguishes between application memory (green), buffers (blue), and cache (yellow). Cached memory is released to applications when they need it, so a full-looking bar does not mean the system is out of memory.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Processes appear and disappear quickly&lt;/strong&gt;&lt;br&gt;
Short-lived processes can start and exit between screen refreshes. Lower the update interval with &lt;code&gt;-d 5&lt;/code&gt; (half a second) to catch fast processes. Keep in mind that a very short interval increases the CPU usage of &lt;code&gt;htop&lt;/code&gt; itself.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between htop and top?&lt;/strong&gt;&lt;br&gt;
Both show running processes and system metrics in real time. &lt;code&gt;htop&lt;/code&gt; adds color-coded CPU and memory meters, mouse support, horizontal and vertical scrolling, built-in search and filtering, and the ability to kill or renice processes without typing a PID. The &lt;a href="https://linuxize.com/post/top-command-in-linux/"&gt;&lt;code&gt;top&lt;/code&gt; command&lt;/a&gt;
is pre-installed on virtually every Linux system, while &lt;code&gt;htop&lt;/code&gt; may need to be installed separately.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does htop use more resources than top?&lt;/strong&gt;&lt;br&gt;
Slightly. &lt;code&gt;htop&lt;/code&gt; reads additional process details from &lt;code&gt;/proc&lt;/code&gt;, so it uses a bit more CPU and memory than &lt;code&gt;top&lt;/code&gt;. On modern hardware the difference is negligible, even on systems with thousands of processes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What do VIRT, RES, and SHR mean?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;VIRT&lt;/code&gt; is the total virtual memory the process has mapped, including memory it has allocated but may not be using yet. &lt;code&gt;RES&lt;/code&gt; (Resident) is the portion actually held in physical RAM. &lt;code&gt;SHR&lt;/code&gt; (Shared) is the subset of RES that is shared with other processes, such as shared libraries loaded by multiple programs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I save my htop configuration?&lt;/strong&gt;&lt;br&gt;
Press &lt;code&gt;F2&lt;/code&gt; to open the setup screen, make your changes, and press &lt;code&gt;F10&lt;/code&gt; to exit. &lt;code&gt;htop&lt;/code&gt; saves the configuration automatically to &lt;code&gt;~/.config/htop/htoprc&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I run htop over SSH?&lt;/strong&gt;&lt;br&gt;
Yes. &lt;code&gt;htop&lt;/code&gt; works in any terminal emulator, including SSH sessions. If you are monitoring a remote server over a long session, consider running &lt;code&gt;htop&lt;/code&gt; inside &lt;a href="https://linuxize.com/post/how-to-use-linux-screen/"&gt;&lt;code&gt;screen&lt;/code&gt;&lt;/a&gt;
or &lt;a href="https://linuxize.com/post/getting-started-with-tmux/"&gt;&lt;code&gt;tmux&lt;/code&gt;&lt;/a&gt;
so the session persists if the connection drops.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;htop&lt;/code&gt; gives you a clear, interactive view of what is running on your system and the resources each process is consuming. For related tools, see the &lt;a href="https://linuxize.com/post/ps-command-in-linux/"&gt;&lt;code&gt;ps&lt;/code&gt; command&lt;/a&gt;
for snapshot process listings, &lt;a href="https://linuxize.com/post/kill-command-in-linux/"&gt;&lt;code&gt;kill&lt;/code&gt;&lt;/a&gt;
for sending signals from the command line, and &lt;a href="https://linuxize.com/post/pstree-command-in-linux/"&gt;&lt;code&gt;pstree&lt;/code&gt;&lt;/a&gt;
for visualizing the process hierarchy.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/htop-command-in-linux/featured_hu_21f053b9aef31b03.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>lsof Command in Linux: List Open Files and Network Connections</title><link>https://linuxize.com/post/lsof-command-in-linux/</link><pubDate>Wed, 01 Apr 2026 10:00:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/lsof-command-in-linux/</guid><category>linux commands</category><description>The lsof command lists every open file, socket, and network connection on a Linux system. This guide covers how to find what is using a port, trace open files by process or user, and recover disk space from deleted but held-open files.</description><content:encoded>&lt;p&gt;When you delete a file but the disk space does not come back, or a port appears occupied and you cannot tell what is using it, the &lt;code&gt;lsof&lt;/code&gt; command gives you the answer. &lt;code&gt;lsof&lt;/code&gt; stands for &amp;ldquo;list open files.&amp;rdquo; In Linux, many resources are represented as files, so &lt;code&gt;lsof&lt;/code&gt; can show regular files, directories, pipes, sockets, and network connections.&lt;/p&gt;
&lt;p&gt;This guide explains how to use &lt;code&gt;lsof&lt;/code&gt; to inspect open files, trace network connections, and identify which processes hold resources on your system.&lt;/p&gt;
&lt;h2 id="lsof-syntax"&gt;lsof Syntax &lt;a class="headline-link" href="#lsof-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lsof [OPTIONS] [FILE]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When called without arguments, &lt;code&gt;lsof&lt;/code&gt; attempts to list every open file visible to the current user. That output is usually thousands of lines long, so in practice you will almost always combine it with a filter or run it with &lt;code&gt;sudo&lt;/code&gt; when you need a full system-wide view.&lt;/p&gt;
&lt;h2 id="understanding-the-output"&gt;Understanding the Output &lt;a class="headline-link" href="#understanding-the-output" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Running &lt;code&gt;lsof&lt;/code&gt; without arguments produces output like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo lsof &lt;span class="p"&gt;|&lt;/span&gt; head -5&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root cwd DIR 8,1 4096 2 /
systemd 1 root rtd DIR 8,1 4096 2 /
nginx 1234 root 6u IPv4 28743 0t0 TCP *:http (LISTEN)
bash 5678 john 1u REG 8,1 102400 789 /home/john/log.txt&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Each column tells you something specific:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;COMMAND&lt;/code&gt; - the name of the process&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PID&lt;/code&gt; - process ID&lt;/li&gt;
&lt;li&gt;&lt;code&gt;USER&lt;/code&gt; - the user running the process&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FD&lt;/code&gt; - file descriptor (&lt;code&gt;cwd&lt;/code&gt; is the current working directory, &lt;code&gt;txt&lt;/code&gt; is the program executable, a number like &lt;code&gt;4u&lt;/code&gt; is an open file handle where &lt;code&gt;r&lt;/code&gt; means read, &lt;code&gt;w&lt;/code&gt; means write, and &lt;code&gt;u&lt;/code&gt; means read and write)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TYPE&lt;/code&gt; - type of file (&lt;code&gt;REG&lt;/code&gt; for a regular file, &lt;code&gt;DIR&lt;/code&gt; for a directory, &lt;code&gt;IPv4&lt;/code&gt;/&lt;code&gt;IPv6&lt;/code&gt; for network sockets, &lt;code&gt;unix&lt;/code&gt; for Unix domain sockets)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SIZE/OFF&lt;/code&gt; - file size or current offset&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NAME&lt;/code&gt; - the file path or network address&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="find-what-is-using-a-port"&gt;Find What Is Using a Port &lt;a class="headline-link" href="#find-what-is-using-a-port" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The most common use for &lt;code&gt;lsof&lt;/code&gt; is finding which process is listening on a given port. For that, use numeric output, limit the search to TCP, and filter to the &lt;code&gt;LISTEN&lt;/code&gt; state:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo lsof -nP -iTCP:80 -sTCP:LISTEN&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 1234 root 6u IPv4 34120 0t0 TCP *:80 (LISTEN)
nginx 1235 www-data 6u IPv4 34120 0t0 TCP *:80 (LISTEN)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output shows that nginx is listening on port 80. The &lt;code&gt;PID&lt;/code&gt; column gives you the process ID if you need to stop or restart it. The &lt;code&gt;-nP&lt;/code&gt; options keep addresses and port numbers numeric, which makes the output easier to read in scripts and troubleshooting sessions.&lt;/p&gt;
&lt;p&gt;To filter by both protocol and port number, specify the protocol before the port:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo lsof -nP -iTCP:443 -sTCP:LISTEN&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is useful when both TCP and UDP services share the same port number and you want to narrow the results to listening TCP sockets only.&lt;/p&gt;
&lt;h2 id="list-all-network-connections"&gt;List All Network Connections &lt;a class="headline-link" href="#list-all-network-connections" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To see all open network connections on the system, pass &lt;code&gt;-i&lt;/code&gt; without a port:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo lsof -i&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To narrow the results to a specific protocol, add &lt;code&gt;TCP&lt;/code&gt; or &lt;code&gt;UDP&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo lsof -i TCP&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 1234 root 6u IPv4 34120 0t0 TCP *:http (LISTEN)
sshd 2345 root 3u IPv4 39210 0t0 TCP *:ssh (LISTEN)
curl 5678 john 5u IPv4 56789 0t0 TCP workstation:54321-&amp;gt;93.184.216.34:http (ESTABLISHED)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Listening services show an asterisk for the address. Established connections show the remote address and port.&lt;/p&gt;
&lt;h2 id="list-files-opened-by-a-process"&gt;List Files Opened by a Process &lt;a class="headline-link" href="#list-files-opened-by-a-process" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To see all files opened by a specific process, pass the process ID with &lt;code&gt;-p&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo lsof -p &lt;span class="m"&gt;1234&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To exclude a process instead, prefix the PID with &lt;code&gt;^&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo lsof -p ^1234&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can also filter by process name with &lt;code&gt;-c&lt;/code&gt;. This matches any running process whose name starts with the given string:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo lsof -c nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="list-files-opened-by-a-user"&gt;List Files Opened by a User &lt;a class="headline-link" href="#list-files-opened-by-a-user" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To see all files a particular user has open, use &lt;code&gt;-u&lt;/code&gt; followed by the username:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lsof -u john&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To see files opened by everyone except that user, prefix the username with &lt;code&gt;^&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo lsof -u ^john&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is useful on multi-user systems when you want to audit what a specific account is accessing.&lt;/p&gt;
&lt;h2 id="find-which-process-has-a-file-open"&gt;Find Which Process Has a File Open &lt;a class="headline-link" href="#find-which-process-has-a-file-open" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Pass a file path directly to &lt;code&gt;lsof&lt;/code&gt; to see which processes currently have it open:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lsof /var/log/nginx/access.log&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 1234 root 5w REG 8,1 249856 654321 /var/log/nginx/access.log
nginx 1235 www-data 5w REG 8,1 249856 654321 /var/log/nginx/access.log&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This works for any file, including device files, sockets, and named pipes.&lt;/p&gt;
&lt;h2 id="list-all-open-files-in-a-directory"&gt;List All Open Files in a Directory &lt;a class="headline-link" href="#list-all-open-files-in-a-directory" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To list all files open within a directory and its subdirectories, use &lt;code&gt;+D&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo lsof +D /var/log&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For a non-recursive listing (top-level only), use lowercase &lt;code&gt;+d&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo lsof +d /var/log&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;+D&lt;/code&gt; is especially useful before unmounting a filesystem. If any process has a file open inside the mount point, &lt;code&gt;umount&lt;/code&gt; will refuse to proceed. Running &lt;code&gt;lsof +D /mountpoint&lt;/code&gt; tells you exactly which process is blocking it.&lt;/p&gt;
&lt;h2 id="find-deleted-files-still-holding-disk-space"&gt;Find Deleted Files Still Holding Disk Space &lt;a class="headline-link" href="#find-deleted-files-still-holding-disk-space" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When you delete a file that a running process still has open, the kernel keeps the data on disk until the process closes the file descriptor or exits. This is a common cause of the &amp;ldquo;disk is full but I cannot find any large files&amp;rdquo; problem.&lt;/p&gt;
&lt;p&gt;To find these held-open deleted files, use &lt;code&gt;+L1&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo lsof +L1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAME
python3 4567 john 3r REG 8,1 2097152 0 456 /tmp/data.bin (deleted)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;NLINK&lt;/code&gt; column shows &lt;code&gt;0&lt;/code&gt;, meaning the file has no directory entry left but is still open. Restarting the process listed under &lt;code&gt;COMMAND&lt;/code&gt; will release the space. For more ways to &lt;a href="https://linuxize.com/post/find-large-files-in-linux/"&gt;find large files on Linux&lt;/a&gt;
, including files that are still visible on disk, see that dedicated guide.&lt;/p&gt;
&lt;h2 id="get-only-process-ids"&gt;Get Only Process IDs &lt;a class="headline-link" href="#get-only-process-ids" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;-t&lt;/code&gt; option outputs only process IDs, with no headers or other columns. This is designed for scripting:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo lsof -t -iTCP:8080 -sTCP:LISTEN&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;3456&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A common pattern is to stop the process listening on a port:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;kill&lt;/span&gt; &lt;span class="k"&gt;$(&lt;/span&gt;sudo lsof -t -iTCP:8080 -sTCP:LISTEN&lt;span class="k"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Verify the process first with &lt;code&gt;sudo lsof -nP -iTCP:8080 -sTCP:LISTEN&lt;/code&gt; before killing it, so you know what you are stopping.&lt;/p&gt;
&lt;h2 id="combining-filters"&gt;Combining Filters &lt;a class="headline-link" href="#combining-filters" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;lsof&lt;/code&gt; treats multiple options as OR logic: the output includes files matching any of the conditions. To switch to AND logic (a result must satisfy all conditions), add &lt;code&gt;-a&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo lsof -a -u john -i TCP&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Without &lt;code&gt;-a&lt;/code&gt;, this command would return all TCP connections on the system plus all files opened by &lt;code&gt;john&lt;/code&gt;. With &lt;code&gt;-a&lt;/code&gt;, it returns only TCP connections that belong specifically to &lt;code&gt;john&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/lsof/"&gt;lsof cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lsof&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List all open files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lsof -nP -iTCP:PORT -sTCP:LISTEN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Find what is listening on a TCP port&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lsof -i TCP&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List all TCP connections&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lsof -nP -iTCP:443 -sTCP:LISTEN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Filter by protocol and port&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lsof -p PID&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Files opened by a process&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lsof -c nginx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Files opened by processes named nginx&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lsof -u john&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Files opened by a user&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lsof /path/to/file&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Processes that have a specific file open&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lsof +D /dir&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;All open files in a directory (recursive)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lsof +L1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Deleted files still held open&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lsof -t -iTCP:PORT -sTCP:LISTEN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Output only PIDs listening on a TCP port&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lsof -a -u john -i TCP&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;AND logic: TCP connections for a specific user&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Why does lsof require sudo?&lt;/strong&gt;&lt;br&gt;
Without root privileges, &lt;code&gt;lsof&lt;/code&gt; can only show files opened by your own processes. Running it with &lt;code&gt;sudo&lt;/code&gt; gives you visibility into all processes on the system. Some distributions also restrict access to &lt;code&gt;/proc&lt;/code&gt; for non-root users, which limits what &lt;code&gt;lsof&lt;/code&gt; can read without elevated permissions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between lsof and ss?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;lsof&lt;/code&gt; covers the full range of open files: regular files, directories, pipes, devices, and network sockets in a single view. The &lt;a href="https://linuxize.com/post/ss-command-in-linux/"&gt;&lt;code&gt;ss&lt;/code&gt; command&lt;/a&gt;
is purpose-built for network sockets and provides more detail about socket states and statistics. Use &lt;code&gt;lsof&lt;/code&gt; when you want to tie a network connection back to a specific file or see everything a process has open. Use &lt;code&gt;ss&lt;/code&gt; when you need to inspect socket state in detail.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I find which process is using a port?&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;sudo lsof -nP -iTCP:PORT -sTCP:LISTEN&lt;/code&gt;, replacing &lt;code&gt;PORT&lt;/code&gt; with the number you want to check. The &lt;a href="https://linuxize.com/post/ss-command-in-linux/"&gt;&lt;code&gt;ss&lt;/code&gt; command&lt;/a&gt;
with &lt;code&gt;ss -tlnp&lt;/code&gt; is another approach covered in the guide on how to &lt;a href="https://linuxize.com/post/check-listening-ports-linux/"&gt;check listening ports&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I monitor file access in real time with lsof?&lt;/strong&gt;&lt;br&gt;
No. &lt;code&gt;lsof&lt;/code&gt; takes a snapshot at the moment you run it. For real-time filesystem event monitoring, use &lt;code&gt;inotifywait&lt;/code&gt; from the &lt;code&gt;inotify-tools&lt;/code&gt; package.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;lsof shows a file path ending in (deleted). What does that mean?&lt;/strong&gt;&lt;br&gt;
The file was removed from the directory while a process still had it open. The data remains on disk until the process releases the file descriptor. This is the cause of the &amp;ldquo;disk full but no large files visible&amp;rdquo; problem described in the section above. Use &lt;code&gt;lsof +L1&lt;/code&gt; to list all such files and restart the holding process to free the space.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;lsof&lt;/code&gt; is one of the most practical diagnostic tools available on Linux. Whether you are tracking down a port conflict, auditing which files a user has open, or recovering disk space from deleted but held-open files, it gives you a direct view into what every process is accessing at any moment.&lt;/p&gt;
&lt;p&gt;For related tools, see the &lt;a href="https://linuxize.com/post/ps-command-in-linux/"&gt;&lt;code&gt;ps&lt;/code&gt; command guide&lt;/a&gt;
for process inspection and the &lt;a href="https://linuxize.com/post/ss-command-in-linux/"&gt;&lt;code&gt;ss&lt;/code&gt; command guide&lt;/a&gt;
for dedicated network socket statistics.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/lsof-command-in-linux/featured_hu_a0c996799050b150.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>sed Delete Lines: Remove Lines by Number, Pattern, or Range</title><link>https://linuxize.com/post/sed-delete-lines/</link><pubDate>Mon, 30 Mar 2026 14:00:00 +0200</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/sed-delete-lines/</guid><category>linux commands</category><description>Remove lines from files with sed using line numbers, patterns, ranges, and regular expressions. Covers preview mode, in-place editing, and common recipes.</description><content:encoded>&lt;p&gt;When working with text files, you will often need to remove specific lines, whether it is stripping comments from a configuration file, cleaning up blank lines in log output, or cutting a range of lines from a data dump. The &lt;code&gt;sed&lt;/code&gt; stream editor handles all of these cases from the command line, without opening the file in an editor.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sed&lt;/code&gt; processes input line by line, applies your commands, and writes the result to standard output. The original file stays untouched unless you explicitly tell &lt;code&gt;sed&lt;/code&gt; to edit in place. If you need to find and replace text rather than remove entire lines, see &lt;a href="https://linuxize.com/post/how-to-use-sed-to-find-and-replace-string-in-files/"&gt;How to Use sed to Find and Replace Strings in Files&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;This guide explains how to use the &lt;code&gt;sed&lt;/code&gt; delete command (&lt;code&gt;d&lt;/code&gt;) with practical examples covering line numbers, patterns, ranges, and regular expressions.&lt;/p&gt;
&lt;h2 id="how-the-delete-command-works"&gt;How the Delete Command Works &lt;a class="headline-link" href="#how-the-delete-command-works" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The general form of a &lt;code&gt;sed&lt;/code&gt; delete expression is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed &amp;#39;ADDRESSd&amp;#39; file&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;ADDRESS&lt;/code&gt; selects which lines to delete, and &lt;code&gt;d&lt;/code&gt; is the delete command. When &lt;code&gt;sed&lt;/code&gt; encounters a line that matches the address, it removes that line from the output entirely. Any line that does not match the address is printed as usual.&lt;/p&gt;
&lt;p&gt;For demonstration purposes, the examples in this guide use the following file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;colors.txt&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;red
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;green
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;blue
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;yellow
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;white
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;black
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;orange
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;purple&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="delete-by-line-number"&gt;Delete by Line Number &lt;a class="headline-link" href="#delete-by-line-number" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The simplest form of delete targets a specific line number. To remove the third line, place &lt;code&gt;3&lt;/code&gt; before the &lt;code&gt;d&lt;/code&gt; command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed &lt;span class="s1"&gt;&amp;#39;3d&amp;#39;&lt;/span&gt; colors.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;red
green
yellow
white
black
orange
purple&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Notice that &amp;ldquo;blue&amp;rdquo; (which was on line 3) is gone from the output, but the original &lt;code&gt;colors.txt&lt;/code&gt; file is unchanged. This is the default behavior of &lt;code&gt;sed&lt;/code&gt;, and it gives you a safe way to preview changes before committing them.&lt;/p&gt;
&lt;p&gt;Sometimes you need to remove the last line of a file without knowing how many lines it contains. The &lt;code&gt;$&lt;/code&gt; address represents the last line:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed &lt;span class="s1"&gt;&amp;#39;$d&amp;#39;&lt;/span&gt; colors.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;red
green
blue
yellow
white
black
orange&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here &amp;ldquo;purple&amp;rdquo; (the last line) has been removed from the output.&lt;/p&gt;
&lt;h2 id="delete-multiple-specific-lines"&gt;Delete Multiple Specific Lines &lt;a class="headline-link" href="#delete-multiple-specific-lines" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you need to remove several individual lines, separate the addresses with a semicolon. The following command deletes lines 2, 5, and 8 in a single pass:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed &lt;span class="s1"&gt;&amp;#39;2d;5d;8d&amp;#39;&lt;/span&gt; colors.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;red
blue
yellow
black
orange&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output is missing &amp;ldquo;green&amp;rdquo; (line 2), &amp;ldquo;white&amp;rdquo; (line 5), and &amp;ldquo;purple&amp;rdquo; (line 8). You can list as many addresses as needed this way.&lt;/p&gt;
&lt;h2 id="delete-a-range-of-lines"&gt;Delete a Range of Lines &lt;a class="headline-link" href="#delete-a-range-of-lines" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To delete a block of consecutive lines, specify a range with two numbers separated by a comma. The following command removes lines 3 through 6:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed &lt;span class="s1"&gt;&amp;#39;3,6d&amp;#39;&lt;/span&gt; colors.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;red
green
orange
purple&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Everything from &amp;ldquo;blue&amp;rdquo; (line 3) through &amp;ldquo;black&amp;rdquo; (line 6) is gone, and the remaining lines print normally.&lt;/p&gt;
&lt;p&gt;You can also combine a line number with &lt;code&gt;$&lt;/code&gt; to delete from a given line to the end of the file. This keeps only the first four lines:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed &lt;span class="s1"&gt;&amp;#39;5,$d&amp;#39;&lt;/span&gt; colors.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;red
green
blue
yellow&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Adding &lt;code&gt;!&lt;/code&gt; after the address inverts the selection, so &lt;code&gt;sed&lt;/code&gt; deletes every line that is &lt;em&gt;not&lt;/em&gt; in the range. The following command keeps only lines 3 through 5 and removes everything else:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed &lt;span class="s1"&gt;&amp;#39;3,5!d&amp;#39;&lt;/span&gt; colors.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;blue
yellow
white&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is a convenient way to extract a slice from a file without piping through &lt;code&gt;head&lt;/code&gt; and &lt;code&gt;tail&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="delete-every-nth-line"&gt;Delete Every Nth Line &lt;a class="headline-link" href="#delete-every-nth-line" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;GNU &lt;code&gt;sed&lt;/code&gt; supports the step address &lt;code&gt;first~step&lt;/code&gt;, which matches every Nth line starting from a given position. To delete every even-numbered line (2, 4, 6, &amp;hellip;):&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed &lt;span class="s1"&gt;&amp;#39;0~2d&amp;#39;&lt;/span&gt; colors.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;red
blue
white
orange&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first number is the starting offset (0 means &amp;ldquo;before the first line&amp;rdquo;, so the first match is line 2) and the second number is the step. In this case &lt;code&gt;sed&lt;/code&gt; deletes lines 2, 4, 6, and 8.&lt;/p&gt;
&lt;p&gt;To delete every third line starting from line 3:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed &lt;span class="s1"&gt;&amp;#39;3~3d&amp;#39;&lt;/span&gt; colors.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;red
green
yellow
white
orange
purple&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Lines 3 (&amp;ldquo;blue&amp;rdquo;) and 6 (&amp;ldquo;black&amp;rdquo;) are removed. This syntax is specific to GNU &lt;code&gt;sed&lt;/code&gt; and is not available in the BSD version shipped with macOS.&lt;/p&gt;
&lt;h2 id="delete-lines-matching-a-pattern"&gt;Delete Lines Matching a Pattern &lt;a class="headline-link" href="#delete-lines-matching-a-pattern" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One of the most common uses of &lt;code&gt;sed&lt;/code&gt; delete is removing lines that contain a specific string. Wrap the search pattern in forward slashes before the &lt;code&gt;d&lt;/code&gt; command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed &lt;span class="s1"&gt;&amp;#39;/blue/d&amp;#39;&lt;/span&gt; colors.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;red
green
yellow
white
black
orange
purple&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Every line containing the string &amp;ldquo;blue&amp;rdquo; is removed from the output. Keep in mind that this is a substring match, so a pattern like &lt;code&gt;/bl/d&lt;/code&gt; would also delete the line &amp;ldquo;black&amp;rdquo; because it contains &amp;ldquo;bl&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;If you want the match to be case-insensitive, add the &lt;code&gt;I&lt;/code&gt; flag after &lt;code&gt;d&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed &lt;span class="s1"&gt;&amp;#39;/Blue/Id&amp;#39;&lt;/span&gt; colors.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This removes lines containing &amp;ldquo;blue&amp;rdquo;, &amp;ldquo;Blue&amp;rdquo;, &amp;ldquo;BLUE&amp;rdquo;, or any other case variation.&lt;/p&gt;
&lt;h2 id="delete-lines-not-matching-a-pattern"&gt;Delete Lines Not Matching a Pattern &lt;a class="headline-link" href="#delete-lines-not-matching-a-pattern" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Adding &lt;code&gt;!&lt;/code&gt; after the pattern address inverts the match, so &lt;code&gt;sed&lt;/code&gt; deletes every line that does &lt;em&gt;not&lt;/em&gt; contain the pattern. The following command removes all lines that do not have the letter &amp;ldquo;e&amp;rdquo;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed &lt;span class="s1"&gt;&amp;#39;/e/!d&amp;#39;&lt;/span&gt; colors.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;red
green
blue
yellow
white
orange
purple&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Only &amp;ldquo;black&amp;rdquo; (line 6) was removed because it is the only line without an &amp;ldquo;e&amp;rdquo;. This works similarly to &lt;a href="https://linuxize.com/post/how-to-use-grep-command-to-search-files-in-linux/"&gt;grep&lt;/a&gt;
, but the advantage of &lt;code&gt;sed&lt;/code&gt; is that you can combine it with other editing commands in the same expression.&lt;/p&gt;
&lt;h2 id="delete-a-range-between-two-patterns"&gt;Delete a Range Between Two Patterns &lt;a class="headline-link" href="#delete-a-range-between-two-patterns" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can use two patterns separated by a comma to define a range. &lt;code&gt;sed&lt;/code&gt; starts deleting at the first line that matches the opening pattern and stops after the first line that matches the closing pattern. The following command removes everything from &amp;ldquo;green&amp;rdquo; through &amp;ldquo;white&amp;rdquo;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed &lt;span class="s1"&gt;&amp;#39;/green/,/white/d&amp;#39;&lt;/span&gt; colors.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;red
black
orange
purple&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Both the &amp;ldquo;green&amp;rdquo; and &amp;ldquo;white&amp;rdquo; lines are included in the deletion, along with &amp;ldquo;blue&amp;rdquo; and &amp;ldquo;yellow&amp;rdquo; between them.&lt;/p&gt;
&lt;p&gt;You can also mix a line number with a pattern. This deletes from line 1 through the first line that contains &amp;ldquo;blue&amp;rdquo;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed &lt;span class="s1"&gt;&amp;#39;1,/blue/d&amp;#39;&lt;/span&gt; colors.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;yellow
white
black
orange
purple&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This kind of mixed address is useful when you know where the range starts (a fixed line) but not where it ends.&lt;/p&gt;
&lt;h2 id="delete-empty-lines"&gt;Delete Empty Lines &lt;a class="headline-link" href="#delete-empty-lines" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Removing blank lines is one of the most common &lt;code&gt;sed&lt;/code&gt; tasks. To delete completely empty lines, use the pattern &lt;code&gt;^$&lt;/code&gt;, which matches lines where the beginning and end have nothing between them:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed &lt;span class="s1"&gt;&amp;#39;/^$/d&amp;#39;&lt;/span&gt; file.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This works well for truly empty lines, but it will not catch lines that contain only spaces or tabs. To remove those as well, use the &lt;code&gt;[[:space:]]&lt;/code&gt; character class:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed &lt;span class="s1"&gt;&amp;#39;/^[[:space:]]*$/d&amp;#39;&lt;/span&gt; file.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;*&lt;/code&gt; quantifier matches zero or more whitespace characters, so this pattern covers both empty lines and lines that appear blank but contain invisible whitespace.&lt;/p&gt;
&lt;h2 id="delete-lines-matching-a-regular-expression"&gt;Delete Lines Matching a Regular Expression &lt;a class="headline-link" href="#delete-lines-matching-a-regular-expression" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The pattern between the slashes is a regular expression, so you can use anchors, character classes, and quantifiers for more precise matching.&lt;/p&gt;
&lt;p&gt;A common example is stripping comment lines from a configuration file. The &lt;code&gt;^#&lt;/code&gt; pattern matches any line that starts with &lt;code&gt;#&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed &lt;span class="s1"&gt;&amp;#39;/^#/d&amp;#39;&lt;/span&gt; config.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To delete lines that end with a semicolon, anchor the pattern to the end of the line with &lt;code&gt;$&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed &lt;span class="s1"&gt;&amp;#39;/;$/d&amp;#39;&lt;/span&gt; source.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can also match by line length. The following command deletes lines that are shorter than 5 characters. The &lt;code&gt;\{0,4\}&lt;/code&gt; quantifier means &amp;ldquo;between 0 and 4 of any character&amp;rdquo;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed &lt;span class="s1"&gt;&amp;#39;/^.\{0,4\}$/d&amp;#39;&lt;/span&gt; file.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you find the backslash escaping awkward, use extended regular expressions with the &lt;code&gt;-E&lt;/code&gt; flag (or &lt;code&gt;-r&lt;/code&gt; on older systems). This lets you write the same expression without escaping the braces:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed -E &lt;span class="s1"&gt;&amp;#39;/^.{0,4}$/d&amp;#39;&lt;/span&gt; file.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="combining-delete-with-other-commands"&gt;Combining Delete with Other Commands &lt;a class="headline-link" href="#combining-delete-with-other-commands" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One of the strengths of &lt;code&gt;sed&lt;/code&gt; is that you can chain multiple operations in a single expression. For example, the following command first removes comment lines and then replaces &amp;ldquo;localhost&amp;rdquo; with &amp;ldquo;127.0.0.1&amp;rdquo; in whatever remains:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed &lt;span class="s1"&gt;&amp;#39;/^#/d; s/localhost/127.0.0.1/g&amp;#39;&lt;/span&gt; config.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The commands are separated by a semicolon and execute left to right. If a line is deleted by an earlier command, the later commands never see it, so the replacement only applies to non-comment lines.&lt;/p&gt;
&lt;h2 id="editing-files-in-place"&gt;Editing Files In Place &lt;a class="headline-link" href="#editing-files-in-place" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;All of the examples above print the modified text to standard output without changing the original file. When you are satisfied with the result, add the &lt;code&gt;-i&lt;/code&gt; flag to apply the changes directly:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed -i &lt;span class="s1"&gt;&amp;#39;/^$/d&amp;#39;&lt;/span&gt; file.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="note callout callout-warning"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"&gt;
&lt;path d="M10 20C4.477 20 0 15.523 0 10S4.477 0 10 0s10 4.477 10 10-4.477 10-10 10zm0-2c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm-.5-5h1c.276 0 .5.224.5.5v1c0 .276-.224.5-.5.5h-1c-.276 0-.5-.224-.5-.5v-1c0-.276.224-.5.5-.5zm0-8h1c.276 0 .5.224.5.5V8l-.5 3-1 .5L9 8V5.5c0-.276.224-.5.5-.5z"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;span class="callout-title"&gt;Warning&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;The &lt;code&gt;-i&lt;/code&gt; flag modifies the file permanently. Always preview the output without &lt;code&gt;-i&lt;/code&gt; first, or create a backup by passing a suffix: &lt;code&gt;sed -i.bak '/^$/d' file.txt&lt;/code&gt;. This saves the original as &lt;code&gt;file.txt.bak&lt;/code&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;On macOS, the BSD version of &lt;code&gt;sed&lt;/code&gt; requires an explicit extension argument even if you do not want a backup. Use &lt;code&gt;sed -i '' '/^$/d' file.txt&lt;/code&gt; for in-place editing without creating a backup file.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/sed/"&gt;sed cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Expression&lt;/th&gt;
&lt;th&gt;What it deletes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sed '3d'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Line 3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sed '$d'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Last line&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sed '2d;5d'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Lines 2 and 5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sed '3,6d'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Lines 3 through 6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sed '5,$d'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Line 5 to end of file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sed '3,5!d'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;All lines except 3 through 5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sed '0~2d'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Every even-numbered line&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sed '/pattern/d'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Lines matching pattern&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sed '/pattern/!d'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Lines not matching pattern&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sed '/start/,/end/d'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;From first match of start to first match of end&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sed '/^$/d'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Empty lines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sed '/^#/d'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Comment lines starting with #&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;How do I delete a line containing a specific word?&lt;/strong&gt;
Use &lt;code&gt;sed '/word/d' file.txt&lt;/code&gt;. This removes any line where &amp;ldquo;word&amp;rdquo; appears as a substring. If you want to match the whole word only (so that &amp;ldquo;keyword&amp;rdquo; is not affected), use word boundaries: &lt;code&gt;sed '/\bword\b/d' file.txt&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I delete lines from multiple files at once?&lt;/strong&gt;
Yes. Pass multiple filenames after the expression: &lt;code&gt;sed -i '/pattern/d' file1.txt file2.txt&lt;/code&gt;. To process files recursively, combine &lt;code&gt;sed&lt;/code&gt; with &lt;code&gt;find&lt;/code&gt;: &lt;code&gt;find . -name &amp;quot;*.log&amp;quot; -exec sed -i '/DEBUG/d' {} +&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;sed '/pattern/d'&lt;/code&gt; and &lt;code&gt;grep -v 'pattern'&lt;/code&gt;?&lt;/strong&gt;
Both remove matching lines from the output. The difference is that &lt;code&gt;sed&lt;/code&gt; can combine deletion with other editing commands in the same expression and supports in-place editing with &lt;code&gt;-i&lt;/code&gt;. If all you need is simple line filtering, &lt;code&gt;grep -v&lt;/code&gt; is shorter to type.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I delete a range of lines and save the result?&lt;/strong&gt;
You can either redirect the output to a new file (&lt;code&gt;sed '3,6d' file.txt &amp;gt; cleaned.txt&lt;/code&gt;) or edit in place with a backup (&lt;code&gt;sed -i.bak '3,6d' file.txt&lt;/code&gt;). Do not redirect to the same input file, because the shell will truncate it before &lt;code&gt;sed&lt;/code&gt; has a chance to read it.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;sed&lt;/code&gt; delete command gives you a fast way to remove lines by number, pattern, or range without opening a file in an editor. For replacing text within lines rather than removing them, see the companion guide on &lt;a href="https://linuxize.com/post/how-to-use-sed-to-find-and-replace-string-in-files/"&gt;sed find and replace&lt;/a&gt;
. If you need to work with individual columns or fields within a line, &lt;a href="https://linuxize.com/post/awk-command/"&gt;awk&lt;/a&gt;
is often the better tool for the job.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/sed-delete-lines/featured_hu_d65b0fae9a3264db.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>git clone: Clone a Repository</title><link>https://linuxize.com/post/git-clone-command/</link><pubDate>Fri, 20 Mar 2026 09:15:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/git-clone-command/</guid><category>git</category><category>linux commands</category><description>How to use git clone to copy a remote or local repository, clone a specific branch, and create shallow clones, with examples for HTTPS and SSH.</description><content:encoded>&lt;p&gt;&lt;code&gt;git clone&lt;/code&gt; copies an existing Git repository into a new directory on your local machine. It sets up tracking branches for each remote branch and creates a remote called &lt;code&gt;origin&lt;/code&gt; pointing back to the source.&lt;/p&gt;
&lt;p&gt;This guide explains how to use &lt;code&gt;git clone&lt;/code&gt; with the most common options and protocols.&lt;/p&gt;
&lt;h2 id="syntax"&gt;Syntax &lt;a class="headline-link" href="#syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The basic syntax of the &lt;code&gt;git clone&lt;/code&gt; command is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone [OPTIONS] REPOSITORY [DIRECTORY]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;REPOSITORY&lt;/code&gt; is the URL or path of the repository to clone. &lt;code&gt;DIRECTORY&lt;/code&gt; is optional; if omitted, Git uses the repository name as the directory name.&lt;/p&gt;
&lt;h2 id="clone-a-remote-repository"&gt;Clone a Remote Repository &lt;a class="headline-link" href="#clone-a-remote-repository" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The most common way to clone a repository is over HTTPS. For example, to clone a GitHub repository:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/user/repo.git&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This creates a &lt;code&gt;repo&lt;/code&gt; directory in the current working directory, initializes a &lt;code&gt;.git&lt;/code&gt; directory inside it, and checks out the default branch.&lt;/p&gt;
&lt;p&gt;You can also clone over SSH if you have an &lt;a href="https://linuxize.com/post/how-to-set-up-ssh-keys-on-ubuntu-20-04/"&gt;SSH key configured&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone git@github.com:user/repo.git&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;SSH is generally preferred for repositories you will push to, as it does not require entering credentials each time.&lt;/p&gt;
&lt;h2 id="clone-into-a-specific-directory"&gt;Clone into a Specific Directory &lt;a class="headline-link" href="#clone-into-a-specific-directory" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;git clone&lt;/code&gt; creates a directory named after the repository. To clone into a different directory, pass the target path as the second argument:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/user/repo.git my-project&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To clone into the current directory, use &lt;code&gt;.&lt;/code&gt; as the target:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/user/repo.git .&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="note callout callout-warning"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"&gt;
&lt;path d="M10 20C4.477 20 0 15.523 0 10S4.477 0 10 0s10 4.477 10 10-4.477 10-10 10zm0-2c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm-.5-5h1c.276 0 .5.224.5.5v1c0 .276-.224.5-.5.5h-1c-.276 0-.5-.224-.5-.5v-1c0-.276.224-.5.5-.5zm0-8h1c.276 0 .5.224.5.5V8l-.5 3-1 .5L9 8V5.5c0-.276.224-.5.5-.5z"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;span class="callout-title"&gt;Warning&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;Cloning into &lt;code&gt;.&lt;/code&gt; requires the current directory to be empty.&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="clone-a-specific-branch"&gt;Clone a Specific Branch &lt;a class="headline-link" href="#clone-a-specific-branch" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;git clone&lt;/code&gt; checks out the default branch (usually &lt;code&gt;main&lt;/code&gt; or &lt;code&gt;master&lt;/code&gt;). To clone and check out a different branch, use the &lt;code&gt;-b&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone -b develop https://github.com/user/repo.git&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The full repository history is still downloaded; only the checked-out branch differs. To limit the download to a single branch, combine &lt;code&gt;-b&lt;/code&gt; with &lt;code&gt;--single-branch&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone -b develop --single-branch https://github.com/user/repo.git&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="shallow-clone"&gt;Shallow Clone &lt;a class="headline-link" href="#shallow-clone" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A shallow clone downloads only a limited number of recent commits rather than the full history. This is useful for speeding up the clone of large repositories when you do not need the full commit history.&lt;/p&gt;
&lt;p&gt;To clone with only the latest commit:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone --depth &lt;span class="m"&gt;1&lt;/span&gt; https://github.com/user/repo.git&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To include the last 10 commits:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone --depth &lt;span class="m"&gt;10&lt;/span&gt; https://github.com/user/repo.git&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Shallow clones are commonly used in CI/CD pipelines to reduce download time. To convert a shallow clone to a full clone later, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git fetch --unshallow&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="clone-a-local-repository"&gt;Clone a Local Repository &lt;a class="headline-link" href="#clone-a-local-repository" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;git clone&lt;/code&gt; also works with local paths. This is useful for creating an isolated copy for testing:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone /path/to/local/repo new-copy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Destination directory is not empty&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;git clone URL .&lt;/code&gt; works only when the current directory is empty. If files already exist, clone into a new directory or move the existing files out of the way first.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Authentication failed over HTTPS&lt;/strong&gt;&lt;br&gt;
Most Git hosting services no longer accept account passwords for Git operations over HTTPS. Use a personal access token or configure a credential manager so Git can authenticate securely.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Permission denied (publickey)&lt;/strong&gt;&lt;br&gt;
This error usually means your SSH key is missing, not loaded into your SSH agent, or not added to your account on the Git hosting service. Verify your SSH setup before retrying the clone.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Host key verification failed&lt;/strong&gt;&lt;br&gt;
SSH could not verify the identity of the remote server. Confirm you are connecting to the correct host, then accept or update the host key in &lt;code&gt;~/.ssh/known_hosts&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/git/"&gt;Git cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git clone URL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Clone a repository via HTTPS or SSH&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git clone URL dir&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Clone into a specific directory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git clone URL .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Clone into the current (empty) directory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git clone -b branch URL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Clone and check out a specific branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git clone -b branch --single-branch URL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Clone only a specific branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git clone --depth 1 URL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Shallow clone: latest commit only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git clone --depth N URL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Shallow clone: last N commits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git clone /path/to/repo&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Clone a local repository&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between HTTPS and SSH cloning?&lt;/strong&gt;&lt;br&gt;
HTTPS cloning works out of the box but prompts for credentials unless you use a credential manager. SSH cloning requires a key pair to be configured but does not prompt for a password on each push or pull.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does &lt;code&gt;git clone&lt;/code&gt; download all branches?&lt;/strong&gt;&lt;br&gt;
Yes. All remote branches are fetched, but only the default branch is checked out locally. Use &lt;code&gt;git branch -r&lt;/code&gt; to list all remote branches, or &lt;code&gt;git checkout branch-name&lt;/code&gt; to switch to one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I clone a private repository?&lt;/strong&gt;&lt;br&gt;
For HTTPS, provide your username and a personal access token when prompted. For SSH, ensure your public key is added to your account on the hosting service.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I clone a specific tag instead of a branch?&lt;/strong&gt;&lt;br&gt;
Yes. Use &lt;code&gt;-b&lt;/code&gt; with the tag name: &lt;code&gt;git clone -b v1.0.0 https://github.com/user/repo.git&lt;/code&gt;. Git checks out that tag in a detached &lt;code&gt;HEAD&lt;/code&gt; state, so create a branch if you plan to make commits.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;git clone&lt;/code&gt; is the starting point for working with any existing Git repository. After cloning, you can inspect the commit history with &lt;a href="https://linuxize.com/post/git-log-command/"&gt;&lt;code&gt;git log&lt;/code&gt;&lt;/a&gt;
, review changes with &lt;a href="https://linuxize.com/post/git-diff-command/"&gt;&lt;code&gt;git diff&lt;/code&gt;&lt;/a&gt;
, learn when to use &lt;a href="https://linuxize.com/post/git-fetch-vs-git-pull/"&gt;git fetch vs git pull&lt;/a&gt;
, and &lt;a href="https://linuxize.com/post/how-to-configure-git-username-and-email/"&gt;configure your username and email&lt;/a&gt;
if you have not done so already.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/git-clone-command/featured_hu_fc06e2b2b8cbbfe5.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>jobs Command in Linux: List and Manage Background Jobs</title><link>https://linuxize.com/post/jobs-command-in-linux/</link><pubDate>Thu, 19 Mar 2026 07:00:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/jobs-command-in-linux/</guid><category>linux commands</category><description>The jobs command lists background and suspended processes in the current shell session. This guide covers syntax, options, job specifications, and practical examples.</description><content:encoded>&lt;p&gt;The &lt;code&gt;jobs&lt;/code&gt; command is a Bash built-in that lists all background and suspended processes associated with the current shell session. It shows the job ID, state, and the command that started each job.&lt;/p&gt;
&lt;p&gt;This article explains how to use the &lt;code&gt;jobs&lt;/code&gt; command, what each option does, and how job specifications work for targeting individual jobs.&lt;/p&gt;
&lt;h2 id="syntax"&gt;Syntax &lt;a class="headline-link" href="#syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The general syntax for the &lt;code&gt;jobs&lt;/code&gt; command is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;jobs [OPTIONS] [JOB_SPEC...]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When called without arguments, &lt;code&gt;jobs&lt;/code&gt; lists all active jobs in the current shell.&lt;/p&gt;
&lt;h2 id="listing-jobs"&gt;Listing Jobs &lt;a class="headline-link" href="#listing-jobs" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To see all background and suspended jobs, run &lt;code&gt;jobs&lt;/code&gt; without any arguments:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;jobs&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you have two processes (one running and one stopped), the output will look similar to this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;[1]- Stopped vim notes.txt
[2]+ Running ping google.com &amp;amp;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Each line shows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The job number in brackets (&lt;code&gt;[1]&lt;/code&gt;, &lt;code&gt;[2]&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;+&lt;/code&gt; or &lt;code&gt;-&lt;/code&gt; sign indicating the current and previous job (more on this below)&lt;/li&gt;
&lt;li&gt;The job state (&lt;code&gt;Running&lt;/code&gt;, &lt;code&gt;Stopped&lt;/code&gt;, &lt;code&gt;Done&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;The command that started the job&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To include the process ID (PID) in the output, use the &lt;code&gt;-l&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;jobs&lt;/span&gt; -l&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;[1]- 14205 Stopped vim notes.txt
[2]+ 14230 Running ping google.com &amp;amp;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The PID is useful when you need to send a signal to a process with the &lt;a href="https://linuxize.com/post/kill-command-in-linux/"&gt;&lt;code&gt;kill&lt;/code&gt;&lt;/a&gt;
command.&lt;/p&gt;
&lt;h2 id="job-states"&gt;Job States &lt;a class="headline-link" href="#job-states" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Jobs reported by the &lt;code&gt;jobs&lt;/code&gt; command can be in one of these states:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Running&lt;/code&gt; — the process is actively executing in the background.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Stopped&lt;/code&gt; — the process has been suspended, typically by pressing &lt;code&gt;Ctrl+Z&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Done&lt;/code&gt; — the process has finished. This state appears once and is then cleared from the list.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Terminated&lt;/code&gt; — the process was killed by a signal.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When a background job finishes, the shell displays its &lt;code&gt;Done&lt;/code&gt; status the next time you press Enter or run a command.&lt;/p&gt;
&lt;h2 id="job-specifications"&gt;Job Specifications &lt;a class="headline-link" href="#job-specifications" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Job specifications (job specs) let you target a specific job when using commands like &lt;code&gt;fg&lt;/code&gt;, &lt;code&gt;bg&lt;/code&gt;, &lt;a href="https://linuxize.com/post/kill-command-in-linux/"&gt;&lt;code&gt;kill&lt;/code&gt;&lt;/a&gt;
, or &lt;code&gt;disown&lt;/code&gt;. They always start with a percent sign (&lt;code&gt;%&lt;/code&gt;):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;%1&lt;/code&gt;, &lt;code&gt;%2&lt;/code&gt;, &amp;hellip; — refer to a job by its number.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%%&lt;/code&gt; or &lt;code&gt;%+&lt;/code&gt; — the current job (the most recently backgrounded or suspended job, marked with &lt;code&gt;+&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%-&lt;/code&gt; — the previous job (marked with &lt;code&gt;-&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%string&lt;/code&gt; — the job whose command starts with &lt;code&gt;string&lt;/code&gt;. For example, &lt;code&gt;%ping&lt;/code&gt; matches a job started with &lt;code&gt;ping google.com&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%?string&lt;/code&gt; — the job whose command contains &lt;code&gt;string&lt;/code&gt; anywhere. For example, &lt;code&gt;%?google&lt;/code&gt; also matches &lt;code&gt;ping google.com&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is a practical example. Start two background jobs:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sleep &lt;span class="m"&gt;300&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ping -c &lt;span class="m"&gt;100&lt;/span&gt; google.com &amp;gt; /dev/null &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Now list them:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;jobs&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;[1]- Running sleep 300 &amp;amp;
[2]+ Running ping -c 100 google.com &amp;gt; /dev/null &amp;amp;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can bring the &lt;code&gt;sleep&lt;/code&gt; job to the foreground by its number:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;fg&lt;/span&gt; %1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Or by the command prefix:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;fg&lt;/span&gt; %sleep&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Both are equivalent and bring job &lt;code&gt;[1]&lt;/code&gt; to the foreground.&lt;/p&gt;
&lt;h2 id="options"&gt;Options &lt;a class="headline-link" href="#options" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;jobs&lt;/code&gt; command accepts the following options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-l&lt;/code&gt; — List jobs with their process IDs in addition to the normal output.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-p&lt;/code&gt; — Print only the PID of each job&amp;rsquo;s process group leader. This is useful for scripting.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-r&lt;/code&gt; — List only running jobs.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-s&lt;/code&gt; — List only stopped (suspended) jobs.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-n&lt;/code&gt; — Show only jobs whose status has changed since the last notification.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To show only running jobs:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;jobs&lt;/span&gt; -r&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To get just the PIDs of all jobs:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;jobs&lt;/span&gt; -p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;14205
14230&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="using-jobs-in-interactive-shells"&gt;Using &lt;code&gt;jobs&lt;/code&gt; in Interactive Shells &lt;a class="headline-link" href="#using-jobs-in-interactive-shells" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;jobs&lt;/code&gt; command is primarily useful in an interactive shell where job control is enabled. In a regular shell script, job control is usually off, so &lt;code&gt;jobs&lt;/code&gt; may return no output even when background processes exist.&lt;/p&gt;
&lt;p&gt;If you need to manage background work in a script, track process IDs with &lt;code&gt;$!&lt;/code&gt; and use &lt;code&gt;wait&lt;/code&gt; with the PID instead of a job spec:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Start a background task&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;long_task &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;task_pid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Poll until it finishes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="nb"&gt;kill&lt;/span&gt; -0 &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$task_pid&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; 2&amp;gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Task is still running...&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; sleep &lt;span class="m"&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Task complete.&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To wait for several background tasks, store their PIDs and pass them to &lt;code&gt;wait&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;task_a &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;pid_a&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;task_b &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;pid_b&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;task_c &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;pid_c&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;wait&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$pid_a&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$pid_b&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$pid_c&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;All tasks complete.&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In an interactive shell, you can still wait for a job by its job spec:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;wait&lt;/span&gt; %1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;jobs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List all background and stopped jobs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;jobs -l&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List jobs with PIDs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;jobs -p&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Print only PIDs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;jobs -r&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List only running jobs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;jobs -s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List only stopped jobs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fg %1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Bring job 1 to the foreground&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bg %1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Resume job 1 in the background&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;kill %1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Terminate job 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;disown %1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Remove job 1 from the job table&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;wait&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Wait for all background jobs to finish&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;jobs&lt;/code&gt; and &lt;code&gt;ps&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;jobs&lt;/code&gt; shows only the processes started from the current shell session. The &lt;a href="https://linuxize.com/post/ps-command-in-linux/"&gt;&lt;code&gt;ps&lt;/code&gt;&lt;/a&gt;
command lists all processes running on the system, regardless of which shell started them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why does &lt;code&gt;jobs&lt;/code&gt; show nothing even though processes are running?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;jobs&lt;/code&gt; only tracks processes started from the current shell. If you started a process in a different terminal or via a system service, it will not appear in &lt;code&gt;jobs&lt;/code&gt;. Use &lt;code&gt;ps aux&lt;/code&gt; to find it instead.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I stop a background job?&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;kill %N&lt;/code&gt; where &lt;code&gt;N&lt;/code&gt; is the job number. For example, &lt;code&gt;kill %1&lt;/code&gt; sends &lt;code&gt;SIGTERM&lt;/code&gt; to job 1. If the job does not stop, use &lt;code&gt;kill -9 %1&lt;/code&gt; to force-terminate it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What do the &lt;code&gt;+&lt;/code&gt; and &lt;code&gt;-&lt;/code&gt; signs mean in &lt;code&gt;jobs&lt;/code&gt; output?&lt;/strong&gt;&lt;br&gt;
The &lt;code&gt;+&lt;/code&gt; marks the current job, the one that &lt;code&gt;fg&lt;/code&gt; and &lt;code&gt;bg&lt;/code&gt; will act on by default. The &lt;code&gt;-&lt;/code&gt; marks the previous job. When the current job finishes, the previous job becomes the new current job.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I keep a background job running after closing the terminal?&lt;/strong&gt;&lt;br&gt;
Use &lt;a href="https://linuxize.com/post/linux-nohup-command/"&gt;&lt;code&gt;nohup&lt;/code&gt;&lt;/a&gt;
before the command, or &lt;code&gt;disown&lt;/code&gt; after backgrounding it. For long-running interactive sessions, consider &lt;a href="https://linuxize.com/post/how-to-use-linux-screen/"&gt;Screen&lt;/a&gt;
or &lt;a href="https://linuxize.com/post/getting-started-with-tmux/"&gt;Tmux&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;jobs&lt;/code&gt; command lists all background and suspended processes in the current shell session. Use it together with &lt;code&gt;fg&lt;/code&gt;, &lt;code&gt;bg&lt;/code&gt;, and &lt;code&gt;kill&lt;/code&gt; to control jobs interactively. For a broader guide on running and managing background processes, see &lt;a href="https://linuxize.com/post/how-to-run-linux-commands-in-background/"&gt;How to Run Linux Commands in the Background&lt;/a&gt;
.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/jobs-command-in-linux/featured_hu_35645e644f4fbc41.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>git diff Command: Show Changes Between Commits</title><link>https://linuxize.com/post/git-diff-command/</link><pubDate>Tue, 17 Mar 2026 07:30:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/git-diff-command/</guid><category>git</category><category>linux commands</category><description>How to use git diff to compare working directory changes, staged files, commits, and branches — with practical examples and common options explained.</description><content:encoded>&lt;p&gt;Every change in a Git repository can be inspected before it is staged or committed. The &lt;code&gt;git diff&lt;/code&gt; command shows the exact lines that were added, removed, or modified — between your working directory, the staging area, and any two commits or branches.&lt;/p&gt;
&lt;p&gt;This guide explains how to use &lt;code&gt;git diff&lt;/code&gt; to review changes at every stage of your workflow.&lt;/p&gt;
&lt;h2 id="basic-usage"&gt;Basic Usage &lt;a class="headline-link" href="#basic-usage" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Run &lt;code&gt;git diff&lt;/code&gt; with no arguments to see all unstaged changes — differences between your working directory and the staging area:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git diff&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;diff --git a/app.py b/app.py
index 3b1a2c4..7d8e9f0 100644
--- a/app.py
+++ b/app.py
@@ -10,6 +10,7 @@ def main():
print(&amp;#34;Starting app&amp;#34;)
+ print(&amp;#34;Debug mode enabled&amp;#34;)
run()&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Lines starting with &lt;code&gt;+&lt;/code&gt; were added. Lines starting with &lt;code&gt;-&lt;/code&gt; were removed. Lines with no prefix are context — unchanged lines shown for reference.&lt;/p&gt;
&lt;p&gt;If nothing is shown, all changes are already staged or there are no changes at all.&lt;/p&gt;
&lt;h2 id="staged-changes"&gt;Staged Changes &lt;a class="headline-link" href="#staged-changes" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To see changes that are staged and ready to commit, use &lt;code&gt;--staged&lt;/code&gt; (or its synonym &lt;code&gt;--cached&lt;/code&gt;):&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git diff --staged&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This compares the staging area against the last commit. It shows exactly what will go into the next commit.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git diff --cached&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Both flags are equivalent. Use whichever you prefer.&lt;/p&gt;
&lt;h2 id="comparing-commits"&gt;Comparing Commits &lt;a class="headline-link" href="#comparing-commits" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Pass two commit hashes to compare them directly:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git diff abc1234 def5678&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To compare a commit against its parent, use the &lt;code&gt;^&lt;/code&gt; suffix:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git diff HEAD^ HEAD&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;HEAD&lt;/code&gt; refers to the latest commit. &lt;code&gt;HEAD^&lt;/code&gt; is one commit before it. You can go further back with &lt;code&gt;HEAD~2&lt;/code&gt;, &lt;code&gt;HEAD~3&lt;/code&gt;, and so on.&lt;/p&gt;
&lt;p&gt;To see what changed in the last commit:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git diff HEAD^ HEAD&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="comparing-branches"&gt;Comparing Branches &lt;a class="headline-link" href="#comparing-branches" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use the same syntax to compare two branches:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git diff main feature-branch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This shows all differences between the tips of the two branches.&lt;/p&gt;
&lt;p&gt;To see only what a branch adds relative to &lt;code&gt;main&lt;/code&gt; — excluding changes already in &lt;code&gt;main&lt;/code&gt; — use the three-dot notation:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git diff main...feature-branch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The three-dot form finds the common ancestor of both branches and diffs from there to the tip of &lt;code&gt;feature-branch&lt;/code&gt;. This is the most useful form for reviewing a pull request before merging.&lt;/p&gt;
&lt;h2 id="comparing-a-specific-file"&gt;Comparing a Specific File &lt;a class="headline-link" href="#comparing-a-specific-file" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To limit the diff to a single file, pass the path after &lt;code&gt;--&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git diff -- path/to/file.py&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;--&lt;/code&gt; separator tells Git the argument is a file path, not a branch name. Combine it with commit references to compare a file across commits:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git diff HEAD~3 HEAD -- path/to/file.py&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="summary-with-stat"&gt;Summary with &amp;ndash;stat &lt;a class="headline-link" href="#summary-with-stat" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To see a summary of which files changed and how many lines were added or removed — without the full diff — use &lt;code&gt;--stat&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git diff --stat&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt; app.py | 3 +++
config.yml | 1 -
2 files changed, 3 insertions(+), 1 deletion(-)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is useful for a quick overview before reviewing the full diff.&lt;/p&gt;
&lt;h2 id="word-level-diff"&gt;Word-Level Diff &lt;a class="headline-link" href="#word-level-diff" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;git diff&lt;/code&gt; highlights changed lines. To highlight only the changed words within a line, use &lt;code&gt;--word-diff&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git diff --word-diff&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;@@ -10,6 +10,6 @@ def main():
print(&amp;#34;[-Starting-]{+Running+} app&amp;#34;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Removed words appear in &lt;code&gt;[-brackets-]&lt;/code&gt; and added words in &lt;code&gt;{+braces+}&lt;/code&gt;. This is especially useful for prose or configuration files where only part of a line changes.&lt;/p&gt;
&lt;h2 id="ignoring-whitespace"&gt;Ignoring Whitespace &lt;a class="headline-link" href="#ignoring-whitespace" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To ignore whitespace-only changes, use &lt;code&gt;-w&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git diff -w&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Use &lt;code&gt;-b&lt;/code&gt; to ignore changes in the amount of whitespace (but not all whitespace):&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git diff -b&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;These options are useful when reviewing files that have been reformatted or indented differently.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/git/"&gt;Git cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git diff&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Unstaged changes in working directory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git diff --staged&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Staged changes ready to commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git diff HEAD^ HEAD&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Changes in the last commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git diff abc1234 def5678&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Diff between two commits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git diff main feature&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Diff between two branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git diff main...feature&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Changes in feature since branching from main&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git diff -- file&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Diff for a specific file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git diff --stat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Summary of changed files and line counts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git diff --word-diff&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Word-level diff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git diff -w&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ignore all whitespace changes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;git diff&lt;/code&gt; and &lt;code&gt;git diff --staged&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;git diff&lt;/code&gt; shows changes in your working directory that have not been staged yet. &lt;code&gt;git diff --staged&lt;/code&gt; shows changes that have been staged with &lt;code&gt;git add&lt;/code&gt; and are ready to commit. To see all changes — staged and unstaged combined — use &lt;code&gt;git diff HEAD&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What does the three-dot &lt;code&gt;...&lt;/code&gt; notation do in &lt;code&gt;git diff&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;git diff main...feature&lt;/code&gt; finds the common ancestor of &lt;code&gt;main&lt;/code&gt; and &lt;code&gt;feature&lt;/code&gt; and shows the diff from that ancestor to the tip of &lt;code&gt;feature&lt;/code&gt;. This isolates the changes that the feature branch introduces, ignoring any new commits in &lt;code&gt;main&lt;/code&gt; since the branch was created. In &lt;code&gt;git diff&lt;/code&gt;, the two-dot form is just another way to name the two revision endpoints, so &lt;code&gt;git diff main..feature&lt;/code&gt; is effectively the same as &lt;code&gt;git diff main feature&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I see only the file names that changed, not the full diff?&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;git diff --name-only&lt;/code&gt;. To include the change status (modified, added, deleted), use &lt;code&gt;git diff --name-status&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I compare my local branch against the remote?&lt;/strong&gt;&lt;br&gt;
Fetch first to update remote-tracking refs, then diff against the updated remote branch. To see what your current branch changes relative to &lt;code&gt;origin/main&lt;/code&gt;, use &lt;code&gt;git fetch &amp;amp;&amp;amp; git diff origin/main...HEAD&lt;/code&gt;. If you want a direct endpoint comparison instead, use &lt;code&gt;git fetch &amp;amp;&amp;amp; git diff origin/main HEAD&lt;/code&gt;. If you want a clearer overview of what &lt;code&gt;git fetch&lt;/code&gt; changes compared with &lt;code&gt;git pull&lt;/code&gt;, see our guide on &lt;a href="https://linuxize.com/post/git-fetch-vs-git-pull/"&gt;git fetch vs git pull&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I use &lt;code&gt;git diff&lt;/code&gt; to generate a patch file?&lt;/strong&gt;&lt;br&gt;
Yes. Redirect the output to a file: &lt;code&gt;git diff &amp;gt; changes.patch&lt;/code&gt;. Apply it on another machine with &lt;code&gt;git apply changes.patch&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;git diff&lt;/code&gt; is the primary tool for reviewing changes before you stage or commit them. Use &lt;code&gt;git diff&lt;/code&gt; for unstaged work, &lt;code&gt;git diff --staged&lt;/code&gt; before committing, and &lt;code&gt;git diff main...feature&lt;/code&gt; to review a branch before merging. For a history of committed changes, see the &lt;a href="https://linuxize.com/post/git-log-command/"&gt;git log guide&lt;/a&gt;
, and for syncing remote changes safely, see &lt;a href="https://linuxize.com/post/git-fetch-vs-git-pull/"&gt;git fetch vs git pull&lt;/a&gt;
.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/git-diff-command/featured_hu_1579dab33d91e54d.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>git log Command: View Commit History</title><link>https://linuxize.com/post/git-log-command/</link><pubDate>Mon, 16 Mar 2026 08:50:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/git-log-command/</guid><category>git</category><category>linux commands</category><description>How to use git log to browse commit history, filter by author, date, and keyword, view changed files, display branch graphs, and format output for scripts and terminals.</description><content:encoded>&lt;p&gt;Every commit in a Git repository is recorded in the project history. The &lt;code&gt;git log&lt;/code&gt; command lets you browse that history — showing who made each change, when, and why. It is one of the most frequently used Git commands and one of the most flexible.&lt;/p&gt;
&lt;p&gt;This guide explains how to use &lt;code&gt;git log&lt;/code&gt; to view, filter, and format commit history.&lt;/p&gt;
&lt;h2 id="basic-usage"&gt;Basic Usage &lt;a class="headline-link" href="#basic-usage" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Run &lt;code&gt;git log&lt;/code&gt; with no arguments to see the full commit history of the current branch, starting from the most recent commit:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;commit a3f1d2e4b5c6789012345678901234567890abcd
Author: Jane Smith &amp;lt;jane@example.com&amp;gt;
Date: Mon Mar 10 14:22:31 2026 +0100
Add user authentication module
commit 7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c
Author: John Doe &amp;lt;john@example.com&amp;gt;
Date: Fri Mar 7 09:15:04 2026 +0100
Fix login form validation&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Each entry shows the full commit hash, author name and email, date, and commit message. Press &lt;code&gt;q&lt;/code&gt; to exit the log view.&lt;/p&gt;
&lt;h2 id="compact-output-with-oneline"&gt;Compact Output with &amp;ndash;oneline &lt;a class="headline-link" href="#compact-output-with-oneline" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The default output is verbose. Use &lt;code&gt;--oneline&lt;/code&gt; to show one commit per line — the abbreviated hash and the subject line only:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log --oneline&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;a3f1d2e Add user authentication module
7b8c9d0 Fix login form validation
c1d2e3f Update README with setup instructions&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is useful for a quick overview of recent work.&lt;/p&gt;
&lt;h2 id="limiting-the-number-of-commits"&gt;Limiting the Number of Commits &lt;a class="headline-link" href="#limiting-the-number-of-commits" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To show only the last N commits, pass &lt;code&gt;-n&lt;/code&gt; followed by the number:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log -n &lt;span class="m"&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can also write it without the space:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log -5&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="filtering-by-author"&gt;Filtering by Author &lt;a class="headline-link" href="#filtering-by-author" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;--author&lt;/code&gt; to show only commits by a specific person. The value is matched as a substring against the author name or email:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log --author&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Jane&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To match multiple authors, pass &lt;code&gt;--author&lt;/code&gt; more than once:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log --author&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Jane&amp;#34;&lt;/span&gt; --author&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;John&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="filtering-by-date"&gt;Filtering by Date &lt;a class="headline-link" href="#filtering-by-date" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;--since&lt;/code&gt; and &lt;code&gt;--until&lt;/code&gt; to limit commits to a date range. These options accept a variety of formats:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log --since&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;2 weeks ago&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log --since&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;2026-03-01&amp;#34;&lt;/span&gt; --until&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;2026-03-15&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="searching-commit-messages"&gt;Searching Commit Messages &lt;a class="headline-link" href="#searching-commit-messages" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;--grep&lt;/code&gt; to find commits whose message contains a keyword:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log --grep&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;authentication&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The search is case-sensitive by default. Add &lt;code&gt;-i&lt;/code&gt; to make it case-insensitive:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log -i --grep&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;fix&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="viewing-changed-files"&gt;Viewing Changed Files &lt;a class="headline-link" href="#viewing-changed-files" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To see a summary of which files were changed in each commit without the full diff, use &lt;code&gt;--stat&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log --stat&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;commit a3f1d2e4b5c6789012345678901234567890abcd
Author: Jane Smith &amp;lt;jane@example.com&amp;gt;
Date: Mon Mar 10 14:22:31 2026 +0100
Add user authentication module
src/auth.py | 84 ++++++++++++++++++++++++++++++++++++++++++++++++
src/models.py | 12 +++++++
tests/test_auth.py | 45 +++++++++++++++++
3 files changed, 141 insertions(+)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To see the full diff for each commit, use &lt;code&gt;-p&lt;/code&gt; (or &lt;code&gt;--patch&lt;/code&gt;):&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log -p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Combine with &lt;code&gt;-n&lt;/code&gt; to limit the output:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log -p -3&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="viewing-history-of-a-specific-file"&gt;Viewing History of a Specific File &lt;a class="headline-link" href="#viewing-history-of-a-specific-file" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To see only the commits that touched a particular file, pass the file path after &lt;code&gt;--&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log -- path/to/file.py&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;--&lt;/code&gt; separator tells Git that what follows is a path, not a branch name. Add &lt;code&gt;-p&lt;/code&gt; to see the exact changes made to that file in each commit:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log -p -- path/to/file.py&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="branch-and-graph-view"&gt;Branch and Graph View &lt;a class="headline-link" href="#branch-and-graph-view" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To visualize how branches diverge and merge, use &lt;code&gt;--graph&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log --oneline --graph&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;* a3f1d2e Add user authentication module
* 7b8c9d0 Fix login form validation
| * 3e4f5a6 WIP: dark mode toggle
|/
* c1d2e3f Update README with setup instructions&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Add &lt;code&gt;--all&lt;/code&gt; to include all branches, not just the current one:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log --oneline --graph --all&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This gives a full picture of the repository&amp;rsquo;s branch and merge history.&lt;/p&gt;
&lt;h2 id="comparing-two-branches"&gt;Comparing Two Branches &lt;a class="headline-link" href="#comparing-two-branches" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To see commits that are in one branch but not another, use the &lt;code&gt;..&lt;/code&gt; notation:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log main..feature-branch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This shows commits reachable from &lt;code&gt;feature-branch&lt;/code&gt; that are not yet in &lt;code&gt;main&lt;/code&gt; — useful for reviewing what a branch adds before merging.&lt;/p&gt;
&lt;h2 id="custom-output-format"&gt;Custom Output Format &lt;a class="headline-link" href="#custom-output-format" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;--pretty=format:&lt;/code&gt; to define exactly what each log line shows. Some useful placeholders:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;%h&lt;/code&gt; — abbreviated commit hash&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%an&lt;/code&gt; — author name&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%ar&lt;/code&gt; — author date, relative&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%s&lt;/code&gt; — subject (first line of commit message)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log --pretty&lt;span class="o"&gt;=&lt;/span&gt;format:&lt;span class="s2"&gt;&amp;#34;%h %an %ar %s&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;a3f1d2e Jane Smith 5 days ago Add user authentication module
7b8c9d0 John Doe 8 days ago Fix login form validation&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="excluding-merge-commits"&gt;Excluding Merge Commits &lt;a class="headline-link" href="#excluding-merge-commits" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To hide merge commits and see only substantive changes, use &lt;code&gt;--no-merges&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git log --no-merges --oneline&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/git/"&gt;Git cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Full commit history&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log --oneline&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;One line per commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log -n 10&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Last 10 commits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log --author=&amp;quot;Name&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Filter by author&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log --since=&amp;quot;2 weeks ago&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Filter by date&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log --grep=&amp;quot;keyword&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Search commit messages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log --stat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show changed files per commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log -p&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show full diff per commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log -- file&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;History of a specific file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log --oneline --graph&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Visual branch graph&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log --oneline --graph --all&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Graph of all branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log main..feature&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Commits in feature not in main&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log --no-merges&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Exclude merge commits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log --pretty=format:&amp;quot;%h %an %s&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Custom output format&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;How do I search for a commit that changed a specific piece of code?&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;-S&lt;/code&gt; (the &amp;ldquo;pickaxe&amp;rdquo; option) to find commits that added or removed a specific string: &lt;code&gt;git log -S &amp;quot;function_name&amp;quot;&lt;/code&gt;. For regex patterns, use &lt;code&gt;-G &amp;quot;pattern&amp;quot;&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I see who last changed each line of a file?&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;git blame path/to/file&lt;/code&gt;. It annotates every line with the commit hash, author, and date of the last change.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;git log&lt;/code&gt; and &lt;code&gt;git reflog&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;git log&lt;/code&gt; shows the commit history of the current branch. &lt;code&gt;git reflog&lt;/code&gt; shows every movement of &lt;code&gt;HEAD&lt;/code&gt; — including commits that were reset, rebased, or are no longer reachable from any branch. It is the main recovery tool if you lose commits accidentally.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I find a commit by its message?&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;git log --grep=&amp;quot;search term&amp;quot;&lt;/code&gt;. For case-insensitive search add &lt;code&gt;-i&lt;/code&gt;. If you need to search the full commit message body as well as the subject, add &lt;code&gt;--all-match&lt;/code&gt; only when combining multiple &lt;code&gt;--grep&lt;/code&gt; patterns, or use &lt;code&gt;git log --grep=&amp;quot;search term&amp;quot; --format=full&lt;/code&gt; to inspect matching commits more closely. Use &lt;code&gt;-E&lt;/code&gt; only when you need extended regular expressions in the grep pattern.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I show a single commit in full detail?&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;git show &amp;lt;hash&amp;gt;&lt;/code&gt;. It prints the commit metadata and the full diff. To show just the files changed without the diff, use &lt;code&gt;git show --stat &amp;lt;hash&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;git log&lt;/code&gt; is the primary tool for understanding a project&amp;rsquo;s history. Start with &lt;code&gt;--oneline&lt;/code&gt; for a quick overview, use &lt;code&gt;--graph --all&lt;/code&gt; to visualize branches, and combine &lt;code&gt;--author&lt;/code&gt;, &lt;code&gt;--since&lt;/code&gt;, and &lt;code&gt;--grep&lt;/code&gt; to zero in on specific changes. For undoing commits found in the log, see the &lt;a href="https://linuxize.com/post/git-revert-commit/"&gt;git revert guide&lt;/a&gt;
or &lt;a href="https://linuxize.com/post/undo-last-git-commit/"&gt;how to undo the last commit&lt;/a&gt;
. If you need to move one specific change onto another branch, see &lt;a href="https://linuxize.com/post/git-cherry-pick/"&gt;git cherry-pick&lt;/a&gt;
.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/git-log-command/featured_hu_4b9e229e7718ad71.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>git stash: Save and Restore Uncommitted Changes</title><link>https://linuxize.com/post/git-stash/</link><pubDate>Sun, 15 Mar 2026 09:30:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/git-stash/</guid><category>git</category><category>linux commands</category><description>How to use git stash to temporarily save uncommitted changes, switch branches, and restore your work — with examples for stashing untracked files, named stashes, and partial stashes.</description><content:encoded>&lt;p&gt;When you are in the middle of a feature and need to switch branches to fix a bug or review someone else&amp;rsquo;s work, you have a problem: your changes are not ready to commit, but you cannot switch branches with a dirty working tree. &lt;code&gt;git stash&lt;/code&gt; solves this by saving your uncommitted changes to a temporary stack so you can restore them later.&lt;/p&gt;
&lt;p&gt;This guide explains how to use &lt;code&gt;git stash&lt;/code&gt; to save, list, apply, and delete stashed changes.&lt;/p&gt;
&lt;h2 id="basic-usage"&gt;Basic Usage &lt;a class="headline-link" href="#basic-usage" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The simplest form saves all modifications to tracked files and reverts the working tree to match the last commit:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git stash&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Saved working directory and index state WIP on main: abc1234 Add login page&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Your working tree is now clean. You can switch branches, pull updates, or apply a hotfix. When you are ready to return to your work, restore the stash.&lt;/p&gt;
&lt;p&gt;By default, &lt;code&gt;git stash&lt;/code&gt; saves both staged and unstaged changes to tracked files. It does not save untracked or ignored files unless you explicitly include them (see below).&lt;/p&gt;
&lt;h2 id="stashing-with-a-message"&gt;Stashing with a Message &lt;a class="headline-link" href="#stashing-with-a-message" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A plain &lt;code&gt;git stash&lt;/code&gt; entry shows the branch and last commit message, which becomes hard to read when you have multiple stashes. Use &lt;code&gt;-m&lt;/code&gt; to attach a descriptive label:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git stash push -m &lt;span class="s2"&gt;&amp;#34;WIP: user authentication form&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This makes it easy to identify the right stash when you list them later.&lt;/p&gt;
&lt;h2 id="listing-stashes"&gt;Listing Stashes &lt;a class="headline-link" href="#listing-stashes" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To see all saved stashes, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git stash list&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;stash@{0}: On main: WIP: user authentication form
stash@{1}: WIP on main: abc1234 Add login page&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Stashes are indexed from newest (&lt;code&gt;stash@{0}&lt;/code&gt;) to oldest. The index is used when you want to apply or drop a specific stash.&lt;/p&gt;
&lt;p&gt;To inspect the contents of a stash before applying it, use &lt;code&gt;git stash show&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git stash show stash@&lt;span class="o"&gt;{&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Add &lt;code&gt;-p&lt;/code&gt; to see the full diff:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git stash show -p stash@&lt;span class="o"&gt;{&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="applying-stashes"&gt;Applying Stashes &lt;a class="headline-link" href="#applying-stashes" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are two ways to restore a stash.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git stash pop&lt;/code&gt; applies the most recent stash and removes it from the stash list:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git stash pop&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;git stash apply&lt;/code&gt; applies a stash but keeps it in the list so you can apply it again or to another branch:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git stash apply&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To apply a specific stash by index, pass the stash reference:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git stash apply stash@&lt;span class="o"&gt;{&lt;/span&gt;1&lt;span class="o"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If applying the stash causes conflicts, resolve them the same way you would resolve a merge conflict, then stage the resolved files.&lt;/p&gt;
&lt;h2 id="stashing-untracked-and-ignored-files"&gt;Stashing Untracked and Ignored Files &lt;a class="headline-link" href="#stashing-untracked-and-ignored-files" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;git stash&lt;/code&gt; only saves changes to files that Git already tracks. New files you have not yet staged are left behind.&lt;/p&gt;
&lt;p&gt;Use &lt;code&gt;-u&lt;/code&gt; (or &lt;code&gt;--include-untracked&lt;/code&gt;) to include untracked files:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git stash -u&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To include both untracked and ignored files — for example, generated build artifacts or local config files — use &lt;code&gt;-a&lt;/code&gt; (or &lt;code&gt;--all&lt;/code&gt;):&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git stash -a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="partial-stash"&gt;Partial Stash &lt;a class="headline-link" href="#partial-stash" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you only want to stash some of your changes and leave others in the working tree, use the &lt;code&gt;-p&lt;/code&gt; (or &lt;code&gt;--patch&lt;/code&gt;) flag to interactively select which hunks to stash:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git stash -p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Git will step through each changed hunk and ask whether to stash it. Type &lt;code&gt;y&lt;/code&gt; to stash the hunk, &lt;code&gt;n&lt;/code&gt; to leave it, or &lt;code&gt;?&lt;/code&gt; for a full list of options.&lt;/p&gt;
&lt;h2 id="creating-a-branch-from-a-stash"&gt;Creating a Branch from a Stash &lt;a class="headline-link" href="#creating-a-branch-from-a-stash" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you have been working on a stash for a while and the branch has diverged enough to cause conflicts on apply, you can create a new branch from the stash directly:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git stash branch new-branch-name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This creates a new branch, checks it out at the commit where the stash was originally made, applies the stash, and drops it from the list if it applied cleanly. It is the safest way to resume stashed work that has grown out of sync with the base branch.&lt;/p&gt;
&lt;h2 id="deleting-stashes"&gt;Deleting Stashes &lt;a class="headline-link" href="#deleting-stashes" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To remove a specific stash once you no longer need it:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git stash drop stash@&lt;span class="o"&gt;{&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To delete all stashes at once:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git stash clear&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Use &lt;code&gt;clear&lt;/code&gt; with care — there is no undo.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/git/"&gt;Git cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stash staged and unstaged changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash push -m &amp;quot;message&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stash with a descriptive label&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash -u&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Include untracked files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash -a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Include untracked and ignored files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash -p&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Interactively choose what to stash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash list&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List all stashes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash show stash@{0}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show changed files in a stash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash show -p stash@{0}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show full diff of a stash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash pop&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Apply and remove the latest stash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash apply stash@{0}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Apply a stash without removing it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash branch branch-name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a branch from the latest stash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash drop stash@{0}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Delete a specific stash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash clear&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Delete all stashes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;git stash pop&lt;/code&gt; and &lt;code&gt;git stash apply&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;pop&lt;/code&gt; applies the stash and removes it from the stash list. &lt;code&gt;apply&lt;/code&gt; restores the changes but keeps the stash entry so you can apply it again — for example, to multiple branches. Use &lt;code&gt;pop&lt;/code&gt; for normal day-to-day use and &lt;code&gt;apply&lt;/code&gt; when you need to reuse the stash.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does &lt;code&gt;git stash&lt;/code&gt; save untracked files?&lt;/strong&gt;&lt;br&gt;
No, not by default. Run &lt;code&gt;git stash -u&lt;/code&gt; to include untracked files, or &lt;code&gt;git stash -a&lt;/code&gt; to also include files that match your &lt;a href="https://linuxize.com/post/gitignore-ignoring-files-in-git/"&gt;&lt;code&gt;.gitignore&lt;/code&gt;&lt;/a&gt;
patterns.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I stash only specific files?&lt;/strong&gt;&lt;br&gt;
Yes. In modern Git, you can pass pathspecs to &lt;code&gt;git stash push&lt;/code&gt;, for example: &lt;code&gt;git stash push -m &amp;quot;label&amp;quot; -- path/to/file&lt;/code&gt;. If you need a more portable workflow, use &lt;code&gt;git stash -p&lt;/code&gt; to interactively select which hunks to stash.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I recover a dropped stash?&lt;/strong&gt;&lt;br&gt;
If you accidentally ran &lt;code&gt;git stash drop&lt;/code&gt; or &lt;code&gt;git stash clear&lt;/code&gt;, the underlying commit may still exist for a while. Run &lt;code&gt;git fsck --no-reflogs | grep &amp;quot;dangling commit&amp;quot;&lt;/code&gt; to list unreachable commits, then &lt;code&gt;git show &amp;lt;hash&amp;gt;&lt;/code&gt; to inspect them. If you find the right stash commit, you can recreate it with &lt;code&gt;git stash store -m &amp;quot;recovered stash&amp;quot; &amp;lt;hash&amp;gt;&lt;/code&gt; and then apply it normally.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I apply a stash to a different branch?&lt;/strong&gt;&lt;br&gt;
Yes. Switch to the target branch with &lt;code&gt;git switch branch-name&lt;/code&gt;, then run &lt;code&gt;git stash apply stash@{0}&lt;/code&gt;. If there are no conflicts, the changes are applied cleanly. If the branches have diverged significantly, consider &lt;code&gt;git stash branch&lt;/code&gt; to create a fresh branch from the stash instead.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;git stash&lt;/code&gt; is the cleanest way to set aside incomplete work without creating a throwaway commit. Use &lt;code&gt;git stash push -m&lt;/code&gt; to keep your stash list readable, prefer &lt;code&gt;pop&lt;/code&gt; for one-time restores, and use &lt;code&gt;git stash branch&lt;/code&gt; when applying becomes messy. For a broader overview of Git workflows, see the &lt;a href="https://linuxize.com/cheatsheet/git/"&gt;Git cheatsheet&lt;/a&gt;
or the &lt;a href="https://linuxize.com/post/git-revert-commit/"&gt;git revert guide&lt;/a&gt;
.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/git-stash/featured_hu_a46f95b11f8c338a.webp" medium="image" type="image/webp" width="1200" height="636"/></item><item><title>How to Create a systemd Service File in Linux</title><link>https://linuxize.com/post/how-to-create-a-systemd-service/</link><pubDate>Tue, 10 Mar 2026 09:00:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/how-to-create-a-systemd-service/</guid><category>linux commands</category><description>Create a systemd service file in Linux with step-by-step instructions for unit file structure, service types, restart policies, and service management with systemctl.</description><content:encoded>&lt;p&gt;systemd is the init system used by most modern Linux distributions, including Ubuntu, Debian, Fedora, and RHEL. It manages system processes, handles service dependencies, and starts services automatically at boot.&lt;/p&gt;
&lt;p&gt;A systemd service file — also called a unit file — tells systemd how to start, stop, and manage a process. This guide explains how to create a systemd service file, install it on the system, and manage it with &lt;a href="https://linuxize.com/post/systemctl-command-in-linux/"&gt;&lt;code&gt;systemctl&lt;/code&gt;&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Create a service file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo nano /etc/systemd/system/myservice.service&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reload systemd after changes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl daemon-reload&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enable service at boot&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl enable myservice&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Start the service&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl start myservice&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enable and start at once&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl enable --now myservice&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check service status&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl status myservice&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stop the service&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl stop myservice&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Disable at boot&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl disable myservice&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;View service logs&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo journalctl -u myservice&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;View live logs&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo journalctl -fu myservice&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="understanding-systemd-unit-files"&gt;Understanding systemd Unit Files &lt;a class="headline-link" href="#understanding-systemd-unit-files" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Service files are plain text files with an &lt;code&gt;.service&lt;/code&gt; extension. They are stored in one of two locations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/etc/systemd/system/&lt;/code&gt; — system-wide services, managed by root. Files here take priority over package-installed units.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/usr/lib/systemd/system/&lt;/code&gt; or &lt;code&gt;/lib/systemd/system/&lt;/code&gt; — units installed by packages, depending on the distribution. Do not edit these directly; copy them to &lt;code&gt;/etc/systemd/system/&lt;/code&gt; to override.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A service file is divided into three sections:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;[Unit]&lt;/code&gt; — describes the service and declares dependencies.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[Service]&lt;/code&gt; — defines how to start, stop, and run the process.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[Install]&lt;/code&gt; — controls how and when the service is enabled.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="creating-a-simple-service-file"&gt;Creating a Simple Service File &lt;a class="headline-link" href="#creating-a-simple-service-file" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In this example, we will create a service that runs a custom Bash script. First, create the script you want to run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nano /usr/local/bin/myapp.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Add the following content to the script:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/usr/local/bin/myapp.sh&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;myapp started&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; /var/log/myapp.log
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# your application logic here&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;exec&lt;/span&gt; /usr/local/bin/myapp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Make the script executable:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chmod +x /usr/local/bin/myapp.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Now create the service file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nano /etc/systemd/system/myapp.service&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Add the following content:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/systemd/system/myapp.service&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;My Custom Application&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;After&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;network.target&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;simple&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/local/bin/myapp.sh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;on-failure&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;RestartSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Install]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;multi-user.target&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;After saving the file, reload systemd to pick up the new unit:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl daemon-reload&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Enable and start the service:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; --now myapp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Check that it is running:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl status myapp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;● myapp.service - My Custom Application
Loaded: loaded (/etc/systemd/system/myapp.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2026-03-10 09:00:00 CET; 2s ago
Main PID: 1234 (myapp.sh)
Tasks: 1 (limit: 4915)
CGroup: /system.slice/myapp.service
└─1234 /bin/bash /usr/local/bin/myapp.sh&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="unit-file-sections-explained"&gt;Unit File Sections Explained &lt;a class="headline-link" href="#unit-file-sections-explained" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="unit-section"&gt;[Unit] Section &lt;a class="headline-link" href="#unit-section" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;[Unit]&lt;/code&gt; section contains metadata and dependency declarations.&lt;/p&gt;
&lt;p&gt;Common directives:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Description=&lt;/code&gt; — a short human-readable name shown in &lt;code&gt;systemctl status&lt;/code&gt; output.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;After=&lt;/code&gt; — start this service only after the listed units are active. Does not create a dependency; use &lt;code&gt;Requires=&lt;/code&gt; for hard dependencies.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Requires=&lt;/code&gt; — this service requires the listed units. If they fail, this service fails too.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Wants=&lt;/code&gt; — like &lt;code&gt;Requires=&lt;/code&gt;, but the service still starts even if the listed units fail.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Documentation=&lt;/code&gt; — a URL or man page reference for the service.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="service-section"&gt;[Service] Section &lt;a class="headline-link" href="#service-section" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;[Service]&lt;/code&gt; section defines the process and how systemd manages it.&lt;/p&gt;
&lt;p&gt;Common directives:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Type=&lt;/code&gt; — the startup type. See &lt;a href="#service-types"&gt;Service Types&lt;/a&gt;
below.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ExecStart=&lt;/code&gt; — the command to run when the service starts. Must be an absolute path.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ExecStop=&lt;/code&gt; — the command to run when the service stops. If omitted, systemd sends &lt;code&gt;SIGTERM&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ExecReload=&lt;/code&gt; — the command to reload the service configuration without restarting.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Restart=&lt;/code&gt; — when to restart automatically. See &lt;a href="#restart-policies"&gt;Restart Policies&lt;/a&gt;
below.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RestartSec=&lt;/code&gt; — how many seconds to wait before restarting. Default is 100ms.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;User=&lt;/code&gt; — run the process as this user instead of root.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Group=&lt;/code&gt; — run the process as this group.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WorkingDirectory=&lt;/code&gt; — set the working directory for the process.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Environment=&lt;/code&gt; — set environment variables: &lt;code&gt;Environment=&amp;quot;KEY=value&amp;quot;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;EnvironmentFile=&lt;/code&gt; — read environment variables from a file.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="install-section"&gt;[Install] Section &lt;a class="headline-link" href="#install-section" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;[Install]&lt;/code&gt; section controls how the service is enabled.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;WantedBy=multi-user.target&lt;/code&gt; — the most common value. Enables the service for normal multi-user (non-graphical) boot.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WantedBy=graphical.target&lt;/code&gt; — use this if the service requires a graphical environment.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="service-types"&gt;Service Types &lt;a class="headline-link" href="#service-types" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;Type=&lt;/code&gt; directive tells systemd how the process behaves at startup.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;simple&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Default. The process started by &lt;code&gt;ExecStart&lt;/code&gt; is the main process.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;forking&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The process forks and the parent exits. systemd tracks the child. Use with traditional daemons.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;oneshot&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The process runs once and exits. systemd waits for it to finish before marking the service as active.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;notify&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Like &lt;code&gt;simple&lt;/code&gt;, but the process notifies systemd when it is ready using &lt;code&gt;sd_notify()&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;idle&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Like &lt;code&gt;simple&lt;/code&gt;, but the process is delayed until all active jobs finish.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;For most custom scripts and applications, &lt;code&gt;Type=simple&lt;/code&gt; is the right choice.&lt;/p&gt;
&lt;h2 id="restart-policies"&gt;Restart Policies &lt;a class="headline-link" href="#restart-policies" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;Restart=&lt;/code&gt; directive controls when systemd automatically restarts the service.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Restarts when&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;no&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Never (default).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;always&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The process exits for any reason.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;on-failure&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The process exits with a non-zero code, is killed by a signal, or times out.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;on-abnormal&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Killed by a signal or times out, but not clean exit.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;on-success&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Only if the process exits cleanly (exit code 0).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;For long-running services, &lt;code&gt;Restart=on-failure&lt;/code&gt; is the most common choice. Use &lt;code&gt;Restart=always&lt;/code&gt; for services that must stay running under all circumstances.&lt;/p&gt;
&lt;h2 id="running-a-service-as-a-non-root-user"&gt;Running a Service as a Non-Root User &lt;a class="headline-link" href="#running-a-service-as-a-non-root-user" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Running services as root is a security risk. Use the &lt;code&gt;User=&lt;/code&gt; and &lt;code&gt;Group=&lt;/code&gt; directives to run the service as a dedicated user:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="ini"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/systemd/system/myapp.service&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-slate-200 text-slate-700 dark:bg-slate-600 dark:text-slate-300"&gt;ini&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;My Custom Application&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;After&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;network.target&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;simple&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;User&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;myappuser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;myappuser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/local/bin/myapp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;on-failure&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;WorkingDirectory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/opt/myapp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Environment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;NODE_ENV=production&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Install]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;multi-user.target&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Create the system user before enabling the service:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo useradd -r -s /usr/sbin/nologin myappuser&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Service fails to start — &amp;ldquo;Failed to start myapp.service&amp;rdquo;&lt;/strong&gt;&lt;br&gt;
Check the logs with &lt;a href="https://linuxize.com/post/journalctl-command-in-linux/"&gt;&lt;code&gt;journalctl&lt;/code&gt;&lt;/a&gt;
: &lt;code&gt;sudo journalctl -u myapp --since &amp;quot;5 minutes ago&amp;quot;&lt;/code&gt;. The output shows the exact error message from the process.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes to the service file have no effect&lt;/strong&gt;&lt;br&gt;
You must run &lt;code&gt;sudo systemctl daemon-reload&lt;/code&gt; after every edit to the unit file. systemd reads the file at reload time, not at start time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;ExecStart= must be an absolute path&amp;rdquo;&lt;/strong&gt;&lt;br&gt;
The &lt;code&gt;ExecStart=&lt;/code&gt; value must start with &lt;code&gt;/&lt;/code&gt;. Use the full path to the binary — for example &lt;code&gt;/usr/bin/python3&lt;/code&gt; not &lt;code&gt;python3&lt;/code&gt;. Use &lt;code&gt;which python3&lt;/code&gt; to find the absolute path.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Service starts but immediately exits&lt;/strong&gt;&lt;br&gt;
The process may be crashing on startup. Check &lt;code&gt;sudo journalctl -u myapp -n 50&lt;/code&gt; for error output. If &lt;code&gt;Type=simple&lt;/code&gt;, make sure &lt;code&gt;ExecStart=&lt;/code&gt; runs the process in the foreground — not a script that launches a background process and exits.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Service does not start at boot despite being enabled&lt;/strong&gt;&lt;br&gt;
Confirm the &lt;code&gt;[Install]&lt;/code&gt; section has a valid &lt;code&gt;WantedBy=&lt;/code&gt; target and that &lt;code&gt;systemctl enable&lt;/code&gt; was run after &lt;code&gt;daemon-reload&lt;/code&gt;. Check with &lt;code&gt;systemctl is-enabled myapp&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Where should I put my service file?&lt;/strong&gt;&lt;br&gt;
Put custom service files in &lt;code&gt;/etc/systemd/system/&lt;/code&gt;. Files there take priority over package-installed units in &lt;code&gt;/usr/lib/systemd/system/&lt;/code&gt; and persist across package upgrades.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;enable&lt;/code&gt; and &lt;code&gt;start&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;systemctl start&lt;/code&gt; starts the service immediately for the current session only. &lt;code&gt;systemctl enable&lt;/code&gt; creates a symlink so the service starts automatically at boot. To do both at once, use &lt;code&gt;systemctl enable --now myservice&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I view logs for my service?&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;sudo journalctl -u myservice&lt;/code&gt; to see all logs. Add &lt;code&gt;-f&lt;/code&gt; to follow live output, or &lt;code&gt;--since &amp;quot;1 hour ago&amp;quot;&lt;/code&gt; to limit the time range. See the &lt;a href="https://linuxize.com/post/journalctl-command-in-linux/"&gt;&lt;code&gt;journalctl&lt;/code&gt; guide&lt;/a&gt;
for full usage.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I run a service as a regular user without root?&lt;/strong&gt;&lt;br&gt;
Yes, using user-level systemd units stored in &lt;code&gt;~/.config/systemd/user/&lt;/code&gt;. Manage them with &lt;code&gt;systemctl --user enable myservice&lt;/code&gt;. They run when the user logs in and stop when they log out (unless lingering is enabled with &lt;code&gt;loginctl enable-linger username&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I reload a service after changing its configuration?&lt;/strong&gt;&lt;br&gt;
If the service supports it, use &lt;code&gt;sudo systemctl reload myservice&lt;/code&gt; — this sends &lt;code&gt;SIGHUP&lt;/code&gt; or runs &lt;code&gt;ExecReload=&lt;/code&gt; without restarting the process. Otherwise, use &lt;code&gt;sudo systemctl restart myservice&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Creating a systemd service file gives you full control over how and when your process runs — including automatic restarts, boot integration, and user isolation. Once the file is in place, use &lt;code&gt;systemctl enable --now&lt;/code&gt; to activate it and &lt;a href="https://linuxize.com/post/journalctl-command-in-linux/"&gt;&lt;code&gt;journalctl -u&lt;/code&gt;&lt;/a&gt;
to monitor it. For scheduling tasks that run once at a set time rather than continuously, consider &lt;a href="https://linuxize.com/post/scheduling-cron-jobs-with-crontab/"&gt;cron jobs&lt;/a&gt;
as an alternative.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/how-to-create-a-systemd-service/featured_hu_c60a83c745c5f94.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>ss Command in Linux: Display Socket Statistics</title><link>https://linuxize.com/post/ss-command-in-linux/</link><pubDate>Thu, 05 Mar 2026 09:00:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/ss-command-in-linux/</guid><category>linux commands</category><description>The ss command displays socket statistics and open ports and is the modern replacement for netstat. This guide explains how to list TCP, UDP, and Unix sockets, filter by port and state, and identify which process owns a socket.</description><content:encoded>&lt;p&gt;&lt;code&gt;ss&lt;/code&gt; is a command-line utility for displaying socket statistics on Linux. It is the modern replacement for the deprecated &lt;a href="https://linuxize.com/post/netstat-command-in-linux/"&gt;&lt;code&gt;netstat&lt;/code&gt;&lt;/a&gt;
command and is faster, more detailed, and available by default on all current Linux distributions.&lt;/p&gt;
&lt;p&gt;This guide explains how to use &lt;code&gt;ss&lt;/code&gt; to list open sockets, filter results by protocol and port, and identify which process is using a given connection.&lt;/p&gt;
&lt;h2 id="ss-syntax"&gt;ss Syntax &lt;a class="headline-link" href="#ss-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss [OPTIONS] [FILTER]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When invoked without options, &lt;code&gt;ss&lt;/code&gt; displays all non-listening sockets that have an established connection.&lt;/p&gt;
&lt;h2 id="list-all-sockets"&gt;List All Sockets &lt;a class="headline-link" href="#list-all-sockets" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To list all sockets regardless of state, use the &lt;code&gt;-a&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output includes columns for the socket type (&lt;code&gt;Netid&lt;/code&gt;), state, receive and send queue sizes, local address and port, and peer address and port:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp ESTAB 0 0 192.168.1.10:ssh 192.168.1.5:52710
tcp LISTEN 0 128 0.0.0.0:http 0.0.0.0:*
udp UNCONN 0 0 0.0.0.0:bootpc 0.0.0.0:*&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="filter-by-socket-type"&gt;Filter by Socket Type &lt;a class="headline-link" href="#filter-by-socket-type" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="tcp-sockets--t"&gt;TCP Sockets (&lt;code&gt;-t&lt;/code&gt;) &lt;a class="headline-link" href="#tcp-sockets--t" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To list only TCP sockets:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -t&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To include listening TCP sockets as well, combine with &lt;code&gt;-a&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -ta&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="udp-sockets--u"&gt;UDP Sockets (&lt;code&gt;-u&lt;/code&gt;) &lt;a class="headline-link" href="#udp-sockets--u" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To list only UDP sockets:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -ua&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="unix-domain-sockets--x"&gt;Unix Domain Sockets (&lt;code&gt;-x&lt;/code&gt;) &lt;a class="headline-link" href="#unix-domain-sockets--x" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To list Unix domain sockets used for inter-process communication:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -xa&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="show-listening-sockets"&gt;Show Listening Sockets &lt;a class="headline-link" href="#show-listening-sockets" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;-l&lt;/code&gt; option shows only sockets that are in the listening state:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -tl&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The most commonly used combination is &lt;code&gt;-tulpn&lt;/code&gt;, which shows all TCP and UDP listening sockets with process names and numeric addresses:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -tulpn&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:((&amp;#34;sshd&amp;#34;,pid=1234,fd=3))
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:((&amp;#34;nginx&amp;#34;,pid=5678,fd=6))
udp UNCONN 0 0 0.0.0.0:68 0.0.0.0:* users:((&amp;#34;dhclient&amp;#34;,pid=910,fd=6))&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Each option in the combination does the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-t&lt;/code&gt; — show TCP sockets&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-u&lt;/code&gt; — show UDP sockets&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-l&lt;/code&gt; — show listening sockets only&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-p&lt;/code&gt; — show the process name and PID&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-n&lt;/code&gt; — show numeric addresses and ports instead of resolving hostnames and service names&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="show-process-information"&gt;Show Process Information &lt;a class="headline-link" href="#show-process-information" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;-p&lt;/code&gt; option adds the process name and PID to the output. This requires root privileges to see processes owned by other users:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ss -tp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
ESTAB 0 0 192.168.1.10:ssh 192.168.1.5:52710 users:((&amp;#34;sshd&amp;#34;,pid=2341,fd=5))&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="use-numeric-output"&gt;Use Numeric Output &lt;a class="headline-link" href="#use-numeric-output" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;ss&lt;/code&gt; resolves port numbers to service names (for example, port &lt;code&gt;22&lt;/code&gt; becomes &lt;code&gt;ssh&lt;/code&gt;). The &lt;code&gt;-n&lt;/code&gt; option disables this and shows raw port numbers:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -tn&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is useful when you need to match exact port numbers in scripts or when name resolution is slow.&lt;/p&gt;
&lt;h2 id="filter-by-port"&gt;Filter by Port &lt;a class="headline-link" href="#filter-by-port" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To find which process is using a specific port, filter by destination or source port. For example, to list all sockets using port &lt;code&gt;80&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -tulpn &lt;span class="p"&gt;|&lt;/span&gt; grep :80&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can also use the built-in filter syntax:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -tnp &lt;span class="s1"&gt;&amp;#39;dport = :443&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To filter by source port:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -tnp &lt;span class="s1"&gt;&amp;#39;sport = :22&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="filter-by-connection-state"&gt;Filter by Connection State &lt;a class="headline-link" href="#filter-by-connection-state" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;ss&lt;/code&gt; supports filtering by connection state. Common states include &lt;code&gt;ESTABLISHED&lt;/code&gt;, &lt;code&gt;LISTEN&lt;/code&gt;, &lt;code&gt;TIME-WAIT&lt;/code&gt;, and &lt;code&gt;CLOSE-WAIT&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To show only established TCP connections:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -tn state ESTABLISHED&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To show only sockets in the &lt;code&gt;TIME-WAIT&lt;/code&gt; state:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -tn state TIME-WAIT&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="filter-by-address"&gt;Filter by Address &lt;a class="headline-link" href="#filter-by-address" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To show sockets connected to or from a specific IP address:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -tn dst 192.168.1.5&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To filter by source address:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -tn src 192.168.1.10&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can combine address and port filters:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -tnp dst 192.168.1.5 &lt;span class="nv"&gt;dport&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; :22&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="show-ipv4-or-ipv6-only"&gt;Show IPv4 or IPv6 Only &lt;a class="headline-link" href="#show-ipv4-or-ipv6-only" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To restrict output to IPv4 sockets, use &lt;code&gt;-4&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -tln -4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To show only IPv6 sockets, use &lt;code&gt;-6&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -tln -6&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="show-summary-statistics"&gt;Show Summary Statistics &lt;a class="headline-link" href="#show-summary-statistics" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;-s&lt;/code&gt; option prints a summary of socket counts by type and state without listing individual sockets:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Total: 312
TCP: 14 (estab 4, closed 3, orphaned 0, timewait 3)
Transport Total IP IPv6
RAW 1 0 1
UDP 6 4 2
TCP 11 7 4
INET 18 11 7
FRAG 0 0 0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is useful for a quick overview of the network state on a busy server.&lt;/p&gt;
&lt;h2 id="practical-examples"&gt;Practical Examples &lt;a class="headline-link" href="#practical-examples" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The following examples cover common diagnostics you will use together with tools like &lt;a href="https://linuxize.com/post/linux-ip-command/"&gt;&lt;code&gt;ip&lt;/code&gt;&lt;/a&gt;
, &lt;a href="https://linuxize.com/post/ifconfig-command/"&gt;&lt;code&gt;ifconfig&lt;/code&gt;&lt;/a&gt;
, and &lt;a href="https://linuxize.com/post/check-listening-ports-linux/"&gt;&lt;code&gt;check listening ports&lt;/code&gt;&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;Find which process is listening on port 8080:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ss -tlpn &lt;span class="nv"&gt;sport&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; :8080&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;List all established SSH connections to your server:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -tn state ESTABLISHED &lt;span class="s1"&gt;&amp;#39;( dport = :22 or sport = :22 )&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Show all connections to a remote host:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -tn dst 203.0.113.10&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Count established TCP connections:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ss -tn state ESTABLISHED &lt;span class="p"&gt;|&lt;/span&gt; tail -n +2 &lt;span class="p"&gt;|&lt;/span&gt; wc -l&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/ss/"&gt;ss cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ss -a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List all sockets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ss -t&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List TCP sockets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ss -u&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List UDP sockets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ss -x&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List Unix domain sockets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ss -l&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show listening sockets only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ss -tulpn&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Listening TCP/UDP with process and numeric output&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ss -tp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;TCP sockets with process names&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ss -tn&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;TCP sockets with numeric addresses&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ss -s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show socket summary statistics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ss -tn state ESTABLISHED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show established TCP connections&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ss -tnp dport = :80&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Filter by destination port&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ss -tn dst 192.168.1.5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Filter by remote address&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ss -4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;IPv4 sockets only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ss -6&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;IPv6 sockets only&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;ss -p&lt;/code&gt; does not show process names&lt;/strong&gt;&lt;br&gt;
Process information for sockets owned by other users requires elevated privileges. Use &lt;code&gt;sudo ss -tp&lt;/code&gt; or &lt;code&gt;sudo ss -tulpn&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Filters return no results&lt;/strong&gt;&lt;br&gt;
Use quoted filter expressions such as &lt;code&gt;ss -tn 'dport = :443'&lt;/code&gt;, and verify whether you should filter by &lt;code&gt;sport&lt;/code&gt; or &lt;code&gt;dport&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Service names hide numeric ports&lt;/strong&gt;&lt;br&gt;
If output shows service names (&lt;code&gt;ssh&lt;/code&gt;, &lt;code&gt;http&lt;/code&gt;) instead of port numbers, add &lt;code&gt;-n&lt;/code&gt; to keep numeric ports and avoid lookup ambiguity.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Output is too broad on busy servers&lt;/strong&gt;&lt;br&gt;
Start with protocol and state filters (&lt;code&gt;-t&lt;/code&gt;, &lt;code&gt;-u&lt;/code&gt;, &lt;code&gt;state ESTABLISHED&lt;/code&gt;) and then add address or port filters to narrow results.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You need command-level context, not only sockets&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;ss&lt;/code&gt; with &lt;a href="https://linuxize.com/post/ps-command-in-linux/"&gt;&lt;code&gt;ps&lt;/code&gt;&lt;/a&gt;
or &lt;a href="https://linuxize.com/post/pgrep-command-in-linux/"&gt;&lt;code&gt;pgrep&lt;/code&gt;&lt;/a&gt;
when you need additional process detail.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;ss&lt;/code&gt; and &lt;code&gt;netstat&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;ss&lt;/code&gt; is the modern replacement for &lt;code&gt;netstat&lt;/code&gt;. It reads directly from kernel socket structures, making it significantly faster on systems with many connections. &lt;code&gt;netstat&lt;/code&gt; is part of the &lt;code&gt;net-tools&lt;/code&gt; package, which is deprecated and not installed by default on most current distributions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why do I need &lt;code&gt;sudo&lt;/code&gt; with &lt;code&gt;ss -p&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
Without root privileges, &lt;code&gt;ss&lt;/code&gt; can only show process information for sockets owned by your own user. To see process names and PIDs for all sockets, run &lt;code&gt;ss&lt;/code&gt; with &lt;code&gt;sudo&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What does &lt;code&gt;Recv-Q&lt;/code&gt; and &lt;code&gt;Send-Q&lt;/code&gt; mean in the output?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;Recv-Q&lt;/code&gt; is the number of bytes received but not yet read by the application. &lt;code&gt;Send-Q&lt;/code&gt; is the number of bytes sent but not yet acknowledged by the remote host. Non-zero values on a listening socket or consistently high values can indicate a performance issue.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I find which process is using a specific port?&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;sudo ss -tulpn | grep :&amp;lt;port&amp;gt;&lt;/code&gt;. The &lt;code&gt;-p&lt;/code&gt; flag adds process information and &lt;code&gt;-n&lt;/code&gt; keeps port numbers numeric so the grep match is reliable.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;ss&lt;/code&gt; is the standard tool for inspecting socket connections on modern Linux systems. The &lt;code&gt;-tulpn&lt;/code&gt; combination covers most day-to-day needs, while the state and address filters make it easy to narrow results on busy servers. For related network diagnostics, see the &lt;a href="https://linuxize.com/post/linux-ip-command/"&gt;&lt;code&gt;ip&lt;/code&gt;&lt;/a&gt;
and &lt;a href="https://linuxize.com/post/ifconfig-command/"&gt;&lt;code&gt;ifconfig&lt;/code&gt;&lt;/a&gt;
command guides, or &lt;a href="https://linuxize.com/post/check-listening-ports-linux/"&gt;check listening ports&lt;/a&gt;
for a broader overview.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/ss-command-in-linux/featured_hu_bb7941c70f47f9c1.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>uniq Command in Linux: Remove and Count Duplicate Lines</title><link>https://linuxize.com/post/uniq-command-in-linux/</link><pubDate>Wed, 04 Mar 2026 08:01:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/uniq-command-in-linux/</guid><category>linux commands</category><description>The uniq command removes or counts duplicate adjacent lines in a file. This guide explains how to filter duplicates, count occurrences, and use uniq with sort in pipelines.</description><content:encoded>&lt;p&gt;&lt;code&gt;uniq&lt;/code&gt; is a command-line utility that filters adjacent duplicate lines from sorted input and writes the result to standard output. It is most commonly used together with &lt;a href="https://linuxize.com/post/sort-command-in-linux/"&gt;&lt;code&gt;sort&lt;/code&gt;&lt;/a&gt;
to remove or count duplicates across an entire file.&lt;/p&gt;
&lt;p&gt;This guide explains how to use the &lt;code&gt;uniq&lt;/code&gt; command with practical examples.&lt;/p&gt;
&lt;h2 id="uniq-command-syntax"&gt;uniq Command Syntax &lt;a class="headline-link" href="#uniq-command-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The syntax for the &lt;code&gt;uniq&lt;/code&gt; command is as follows:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uniq [OPTIONS] [INPUT [OUTPUT]]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If no input file is specified, &lt;code&gt;uniq&lt;/code&gt; reads from standard input. The optional &lt;code&gt;OUTPUT&lt;/code&gt; argument redirects the result to a file instead of standard output.&lt;/p&gt;
&lt;h2 id="removing-duplicate-lines"&gt;Removing Duplicate Lines &lt;a class="headline-link" href="#removing-duplicate-lines" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;uniq&lt;/code&gt; removes adjacent duplicate lines, keeping one copy of each. Because it only compares consecutive lines, the input must be sorted first — otherwise only back-to-back duplicates are removed.&lt;/p&gt;
&lt;p&gt;Given a file with repeated entries:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;fruits.txt&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apple
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apple
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;banana
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cherry
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;banana
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cherry
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cherry&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Running &lt;code&gt;uniq&lt;/code&gt; on the unsorted file removes only the back-to-back duplicates (&lt;code&gt;apple apple&lt;/code&gt; and &lt;code&gt;cherry cherry&lt;/code&gt;), but leaves the second &lt;code&gt;banana&lt;/code&gt; and the second &lt;code&gt;cherry&lt;/code&gt; intact:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uniq fruits.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;apple
banana
cherry
banana
cherry&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To remove all duplicates regardless of position, sort the file first:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sort fruits.txt &lt;span class="p"&gt;|&lt;/span&gt; uniq&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;apple
banana
cherry&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="counting-occurrences"&gt;Counting Occurrences &lt;a class="headline-link" href="#counting-occurrences" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To prefix each output line with the number of times it appears, use the &lt;code&gt;-c&lt;/code&gt; (&lt;code&gt;--count&lt;/code&gt;) option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sort fruits.txt &lt;span class="p"&gt;|&lt;/span&gt; uniq -c&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt; 2 apple
2 banana
3 cherry&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The count and the line are separated by whitespace. This is especially useful for finding the most frequent lines in a file. To rank them from most to least common, pipe the output back to &lt;code&gt;sort&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sort fruits.txt &lt;span class="p"&gt;|&lt;/span&gt; uniq -c &lt;span class="p"&gt;|&lt;/span&gt; sort -rn&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt; 3 cherry
2 banana
2 apple&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="showing-only-duplicate-lines"&gt;Showing Only Duplicate Lines &lt;a class="headline-link" href="#showing-only-duplicate-lines" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To print only lines that appear more than once (one copy per group), use the &lt;code&gt;-d&lt;/code&gt; (&lt;code&gt;--repeated&lt;/code&gt;) option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sort fruits.txt &lt;span class="p"&gt;|&lt;/span&gt; uniq -d&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;apple
banana
cherry&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To print every instance of a repeated line rather than just one, use &lt;code&gt;-D&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sort fruits.txt &lt;span class="p"&gt;|&lt;/span&gt; uniq -D&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;apple
apple
banana
banana
cherry
cherry
cherry&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="showing-only-unique-lines"&gt;Showing Only Unique Lines &lt;a class="headline-link" href="#showing-only-unique-lines" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To print only lines that appear exactly once (no duplicates), use the &lt;code&gt;-u&lt;/code&gt; (&lt;code&gt;--unique&lt;/code&gt;) option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sort fruits.txt &lt;span class="p"&gt;|&lt;/span&gt; uniq -u&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If every line appears more than once, the output is empty. In the example above, all three fruits are duplicated, so nothing is printed.&lt;/p&gt;
&lt;h2 id="ignoring-case"&gt;Ignoring Case &lt;a class="headline-link" href="#ignoring-case" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;uniq&lt;/code&gt; comparisons are case-sensitive, so &lt;code&gt;Apple&lt;/code&gt; and &lt;code&gt;apple&lt;/code&gt; are treated as different lines. To compare lines case-insensitively, use the &lt;code&gt;-i&lt;/code&gt; (&lt;code&gt;--ignore-case&lt;/code&gt;) option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sort -f file.txt &lt;span class="p"&gt;|&lt;/span&gt; uniq -i&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="skipping-fields-and-characters"&gt;Skipping Fields and Characters &lt;a class="headline-link" href="#skipping-fields-and-characters" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;uniq&lt;/code&gt; can be told to skip leading fields or characters before comparing lines.&lt;/p&gt;
&lt;p&gt;To skip the first N whitespace-separated fields, use &lt;code&gt;-f N&lt;/code&gt; (&lt;code&gt;--skip-fields=N&lt;/code&gt;). This is useful when lines share a common prefix (such as a timestamp) that should not be part of the comparison:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;log.txt&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2026-01-01 ERROR disk full
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2026-01-02 ERROR disk full
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2026-01-03 WARNING low memory&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uniq -f &lt;span class="m"&gt;1&lt;/span&gt; log.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;2026-01-01 ERROR disk full
2026-01-03 WARNING low memory&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first field (the date) is skipped, so the two &lt;code&gt;ERROR disk full&lt;/code&gt; lines are treated as duplicates.&lt;/p&gt;
&lt;p&gt;To skip the first N characters instead of fields, use &lt;code&gt;-s N&lt;/code&gt; (&lt;code&gt;--skip-chars=N&lt;/code&gt;). To limit the comparison to the first N characters per line, use &lt;code&gt;-w N&lt;/code&gt; (&lt;code&gt;--check-chars=N&lt;/code&gt;).&lt;/p&gt;
&lt;h2 id="combining-uniq-with-other-commands"&gt;Combining uniq with Other Commands &lt;a class="headline-link" href="#combining-uniq-with-other-commands" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;uniq&lt;/code&gt; works well in pipelines with &lt;a href="https://linuxize.com/post/how-to-use-grep-command-to-search-files-in-linux/"&gt;&lt;code&gt;grep&lt;/code&gt;&lt;/a&gt;
, &lt;a href="https://linuxize.com/post/linux-cut-command/"&gt;&lt;code&gt;cut&lt;/code&gt;&lt;/a&gt;
, &lt;a href="https://linuxize.com/post/sort-command-in-linux/"&gt;&lt;code&gt;sort&lt;/code&gt;&lt;/a&gt;
, and &lt;a href="https://linuxize.com/post/linux-wc-command/"&gt;&lt;code&gt;wc&lt;/code&gt;&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;To count the number of unique lines in a file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sort file.txt &lt;span class="p"&gt;|&lt;/span&gt; uniq &lt;span class="p"&gt;|&lt;/span&gt; wc -l&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To find the top 10 most common words in a text file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep -Eo &lt;span class="s1"&gt;&amp;#39;[[:alnum:]]+&amp;#39;&lt;/span&gt; file.txt &lt;span class="p"&gt;|&lt;/span&gt; sort &lt;span class="p"&gt;|&lt;/span&gt; uniq -c &lt;span class="p"&gt;|&lt;/span&gt; sort -rn &lt;span class="p"&gt;|&lt;/span&gt; head -10&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To list unique IP addresses from an access log:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;awk &lt;span class="s1"&gt;&amp;#39;{print $1}&amp;#39;&lt;/span&gt; /var/log/nginx/access.log &lt;span class="p"&gt;|&lt;/span&gt; sort &lt;span class="p"&gt;|&lt;/span&gt; uniq&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To find lines that appear in one file but not another (using &lt;code&gt;-u&lt;/code&gt; against merged sorted files):&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sort file1.txt file2.txt &lt;span class="p"&gt;|&lt;/span&gt; uniq -u&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sort file.txt | uniq&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Remove all duplicate lines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sort file.txt | uniq -c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Count occurrences of each line&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sort file.txt | uniq -c | sort -rn&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rank lines by frequency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sort file.txt | uniq -d&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show only duplicate lines (one per group)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sort file.txt | uniq -D&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show all instances of duplicate lines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sort file.txt | uniq -u&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show only lines that appear exactly once&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uniq -i file.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Compare lines case-insensitively&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uniq -f 2 file.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Skip first 2 fields when comparing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uniq -s 5 file.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Skip first 5 characters when comparing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uniq -w 10 file.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Compare only first 10 characters&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Duplicates are not removed&lt;/strong&gt;
&lt;code&gt;uniq&lt;/code&gt; only removes adjacent duplicate lines. If the file is not sorted, non-consecutive duplicates are not detected. Always sort the input first: &lt;code&gt;sort file.txt | uniq&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;-c&lt;/code&gt; output has inconsistent spacing&lt;/strong&gt;
The count is right-aligned and padded with spaces. If you need to process the output further, use &lt;code&gt;awk&lt;/code&gt; to normalize spacing while preserving the full line text: &lt;code&gt;sort file.txt | uniq -c | awk '{count=$1; $1=\&amp;quot;\&amp;quot;; sub(/^ +/, \&amp;quot;\&amp;quot;); print count, $0}'&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Case variants are treated as different lines&lt;/strong&gt;
Use the &lt;code&gt;-i&lt;/code&gt; option to compare case-insensitively. Also sort with &lt;code&gt;-f&lt;/code&gt; so that case-insensitive duplicates are adjacent before &lt;code&gt;uniq&lt;/code&gt; processes them: &lt;code&gt;sort -f file.txt | uniq -i&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;sort -u&lt;/code&gt; and &lt;code&gt;sort | uniq&lt;/code&gt;?&lt;/strong&gt;
Both produce the same output for simple deduplication. &lt;code&gt;sort -u&lt;/code&gt; is slightly more efficient. &lt;code&gt;sort | uniq&lt;/code&gt; is more flexible because &lt;code&gt;uniq&lt;/code&gt; supports options like &lt;code&gt;-c&lt;/code&gt; (count occurrences) and &lt;code&gt;-d&lt;/code&gt; (show only duplicates) that &lt;code&gt;sort -u&lt;/code&gt; does not.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does &lt;code&gt;uniq&lt;/code&gt; modify the input file?&lt;/strong&gt;
No. &lt;code&gt;uniq&lt;/code&gt; reads from a file or standard input and writes to standard output. The original file is never modified. To save the result, use redirection: &lt;code&gt;sort file.txt | uniq &amp;gt; deduped.txt&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I count unique lines in a file?&lt;/strong&gt;
Pipe through &lt;code&gt;sort&lt;/code&gt;, &lt;code&gt;uniq&lt;/code&gt;, and &lt;a href="https://linuxize.com/post/linux-wc-command/"&gt;&lt;code&gt;wc&lt;/code&gt;&lt;/a&gt;
: &lt;code&gt;sort file.txt | uniq | wc -l&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I find lines that only appear in one of two files?&lt;/strong&gt;
Merge both files and use &lt;code&gt;uniq -u&lt;/code&gt;: &lt;code&gt;sort file1.txt file2.txt | uniq -u&lt;/code&gt;. Lines shared by both files become duplicates in the merged sorted stream and are suppressed. Lines that exist in only one file remain unique and are printed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can &lt;code&gt;uniq&lt;/code&gt; work on columns instead of full lines?&lt;/strong&gt;
Yes. Use &lt;code&gt;-f N&lt;/code&gt; to skip the first N fields, &lt;code&gt;-s N&lt;/code&gt; to skip the first N characters, or &lt;code&gt;-w N&lt;/code&gt; to limit comparison to the first N characters. This lets you deduplicate based on a portion of each line.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;uniq&lt;/code&gt; command is a focused tool for filtering and counting duplicate lines. It is most effective when used after &lt;a href="https://linuxize.com/post/sort-command-in-linux/"&gt;&lt;code&gt;sort&lt;/code&gt;&lt;/a&gt;
in a pipeline and pairs naturally with &lt;a href="https://linuxize.com/post/linux-wc-command/"&gt;&lt;code&gt;wc&lt;/code&gt;&lt;/a&gt;
, &lt;a href="https://linuxize.com/post/how-to-use-grep-command-to-search-files-in-linux/"&gt;&lt;code&gt;grep&lt;/code&gt;&lt;/a&gt;
, and &lt;a href="https://linuxize.com/post/linux-head-command/"&gt;&lt;code&gt;head&lt;/code&gt;&lt;/a&gt;
for text analysis tasks.&lt;/p&gt;
&lt;p&gt;If you have any questions, feel free to leave a comment below.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/uniq-command-in-linux/featured_hu_233454934590ca66.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>top Command in Linux: Monitor Processes in Real Time</title><link>https://linuxize.com/post/top-command-in-linux/</link><pubDate>Sat, 28 Feb 2026 14:10:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/top-command-in-linux/</guid><category>linux commands</category><description>The top command displays running processes and system resource usage in real time. This guide covers sorting, filtering, load metrics, and key interactive controls.</description><content:encoded>&lt;p&gt;&lt;code&gt;top&lt;/code&gt; is a command-line utility that displays running processes and system resource usage in real time. It helps you inspect CPU usage, memory consumption, load averages, and process activity from a single interactive view.&lt;/p&gt;
&lt;p&gt;This guide explains how to use &lt;code&gt;top&lt;/code&gt; to monitor your system and quickly identify resource-heavy processes.&lt;/p&gt;
&lt;h2 id="top-command-syntax"&gt;top Command Syntax &lt;a class="headline-link" href="#top-command-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The syntax for the &lt;code&gt;top&lt;/code&gt; command is as follows:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;top [OPTIONS]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Run &lt;code&gt;top&lt;/code&gt; without arguments to open the interactive monitor:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;top&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="understanding-the-top-output"&gt;Understanding the top Output &lt;a class="headline-link" href="#understanding-the-top-output" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The screen is split into two areas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Summary area&lt;/strong&gt; — system-wide metrics displayed in the header lines&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Task area&lt;/strong&gt; — per-process metrics listed below the header&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A typical &lt;code&gt;top&lt;/code&gt; header looks like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;top - 14:32:01 up 3 days, 4:12, 2 users, load average: 0.45, 0.31, 0.28
Tasks: 213 total, 1 running, 212 sleeping, 0 stopped, 0 zombie
%Cpu(s): 3.2 us, 1.1 sy, 0.0 ni, 95.3 id, 0.2 wa, 0.0 hi, 0.1 si, 0.0 st
MiB Mem : 15886.7 total, 8231.4 free, 4912.5 used, 2742.8 buff/cache
MiB Swap: 2048.0 total, 2048.0 free, 0.0 used. 10374.2 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1234 www-data 20 0 123456 45678 9012 S 4.3 0.3 0:42.31 nginx
987 mysql 20 0 987654 321098 12345 S 1.7 2.0 3:12.04 mysqld
5678 root 20 0 65432 5678 3456 S 0.0 0.0 0:00.12 sshd&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="cpu-state-percentages"&gt;CPU State Percentages &lt;a class="headline-link" href="#cpu-state-percentages" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;%Cpu(s)&lt;/code&gt; line breaks CPU time into the following states:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;us&lt;/code&gt; — time running user-space (non-kernel) processes&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sy&lt;/code&gt; — time running kernel processes&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ni&lt;/code&gt; — time running user processes with a manually adjusted nice value&lt;/li&gt;
&lt;li&gt;&lt;code&gt;id&lt;/code&gt; — idle time&lt;/li&gt;
&lt;li&gt;&lt;code&gt;wa&lt;/code&gt; — time waiting for I/O to complete&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hi&lt;/code&gt; — time handling hardware interrupt requests&lt;/li&gt;
&lt;li&gt;&lt;code&gt;si&lt;/code&gt; — time handling software interrupt requests&lt;/li&gt;
&lt;li&gt;&lt;code&gt;st&lt;/code&gt; — time stolen from this virtual machine by the hypervisor (relevant on VMs)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;High &lt;code&gt;wa&lt;/code&gt; typically points to a disk or network I/O bottleneck. High &lt;code&gt;us&lt;/code&gt; or &lt;code&gt;sy&lt;/code&gt; points to CPU pressure. For memory details, see the &lt;a href="https://linuxize.com/post/free-command-in-linux/"&gt;&lt;code&gt;free&lt;/code&gt;&lt;/a&gt;
command. For load average context, see &lt;a href="https://linuxize.com/post/linux-uptime-command/"&gt;&lt;code&gt;uptime&lt;/code&gt;&lt;/a&gt;
.&lt;/p&gt;
&lt;h3 id="task-area-columns"&gt;Task Area Columns &lt;a class="headline-link" href="#task-area-columns" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Column&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PID&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Process ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;USER&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Owner of the process&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Scheduling priority assigned by the kernel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;NI&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Nice value (-20 = highest priority, 19 = lowest)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;VIRT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Total virtual memory the process has mapped&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;RES&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Resident set size — physical RAM currently in use&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SHR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Shared memory with other processes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;S&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Process state: &lt;code&gt;R&lt;/code&gt; running, &lt;code&gt;S&lt;/code&gt; sleeping, &lt;code&gt;D&lt;/code&gt; uninterruptible, &lt;code&gt;Z&lt;/code&gt; zombie&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;%CPU&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CPU usage since the last refresh&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;%MEM&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Percentage of physical RAM in use&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TIME+&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Total CPU time consumed since the process started&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;COMMAND&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Process name or full command line (toggle with &lt;code&gt;c&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="common-interactive-controls"&gt;Common Interactive Controls &lt;a class="headline-link" href="#common-interactive-controls" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Press these keys while &lt;code&gt;top&lt;/code&gt; is running:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Key&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;q&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Quit &lt;code&gt;top&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;h&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show help&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;k&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Kill a process by PID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;r&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Renice a process&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;P&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sort by CPU usage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;M&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sort by memory usage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;N&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sort by PID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;T&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sort by running time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Toggle per-CPU core display&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Toggle full command line&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;u&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Filter by user&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="refresh-interval-and-batch-mode"&gt;Refresh Interval and Batch Mode &lt;a class="headline-link" href="#refresh-interval-and-batch-mode" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To change the refresh interval (seconds), use &lt;code&gt;-d&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;top -d &lt;span class="m"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To run &lt;code&gt;top&lt;/code&gt; in batch mode (non-interactive), use &lt;code&gt;-b&lt;/code&gt;. This is useful for scripts and logs:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;top -b -n &lt;span class="m"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To capture multiple snapshots:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;top -b -n &lt;span class="m"&gt;5&lt;/span&gt; -d &lt;span class="m"&gt;1&lt;/span&gt; &amp;gt; top-snapshot.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="filtering-and-sorting"&gt;Filtering and Sorting &lt;a class="headline-link" href="#filtering-and-sorting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Start &lt;code&gt;top&lt;/code&gt; with a user filter:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;top -u root&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To monitor a specific process by PID, use &lt;code&gt;-p&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;top -p &lt;span class="m"&gt;1234&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Pass a comma-separated list to monitor multiple PIDs at once:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;top -p 1234,5678&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To show individual threads instead of processes, use &lt;code&gt;-H&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;top -H&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Thread view is useful when profiling multi-threaded applications — each thread appears as a separate row with its own CPU and memory usage.&lt;/p&gt;
&lt;p&gt;Inside &lt;code&gt;top&lt;/code&gt;, use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;P&lt;/code&gt; to sort by CPU&lt;/li&gt;
&lt;li&gt;&lt;code&gt;M&lt;/code&gt; to sort by memory&lt;/li&gt;
&lt;li&gt;&lt;code&gt;u&lt;/code&gt; to show a specific user&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For deeper process filtering, combine &lt;code&gt;top&lt;/code&gt; with &lt;a href="https://linuxize.com/post/ps-command-in-linux/"&gt;&lt;code&gt;ps&lt;/code&gt;&lt;/a&gt;
, &lt;a href="https://linuxize.com/post/pgrep-command-in-linux/"&gt;&lt;code&gt;pgrep&lt;/code&gt;&lt;/a&gt;
, and &lt;a href="https://linuxize.com/post/kill-command-in-linux/"&gt;&lt;code&gt;kill&lt;/code&gt;&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;top&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Start interactive process monitor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;top -d 2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Refresh every 2 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;top -u user&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show only a specific user&amp;rsquo;s processes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;top -p PID&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Monitor a specific process by PID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;top -H&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show individual threads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;top -b -n 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Single non-interactive snapshot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;top -b -n 5 -d 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Collect 5 snapshots at 1-second intervals&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;top&lt;/code&gt; is not installed&lt;/strong&gt;
Install the &lt;code&gt;procps&lt;/code&gt; package (&lt;code&gt;procps-ng&lt;/code&gt; on some distributions), then run &lt;code&gt;top&lt;/code&gt; again.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Display refresh is too fast or too slow&lt;/strong&gt;
Use &lt;code&gt;-d&lt;/code&gt; to tune the refresh rate, for example &lt;code&gt;top -d 2&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cannot kill or renice a process&lt;/strong&gt;
You may not own the process. Use &lt;code&gt;sudo&lt;/code&gt; or run as a user with sufficient privileges.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;top&lt;/code&gt; and &lt;code&gt;htop&lt;/code&gt;?&lt;/strong&gt;
&lt;code&gt;top&lt;/code&gt; is available by default on most Linux systems and is lightweight. &lt;code&gt;htop&lt;/code&gt; provides a richer interactive UI with color coding, mouse support, and easier navigation, but requires a separate installation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What does load average mean?&lt;/strong&gt;
Load average shows the average number of runnable or uninterruptible tasks over the last 1, 5, and 15 minutes. A value above the number of CPU cores indicates the system is under pressure. See &lt;a href="https://linuxize.com/post/linux-uptime-command/"&gt;&lt;code&gt;uptime&lt;/code&gt;&lt;/a&gt;
for more detail.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is a zombie process?&lt;/strong&gt;
A zombie process has finished execution but its entry remains in the process table because the parent process has not yet read its exit status. A small number of zombie processes is harmless; a growing count may indicate a bug in the parent application.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What do &lt;code&gt;VIRT&lt;/code&gt;, &lt;code&gt;RES&lt;/code&gt;, and &lt;code&gt;SHR&lt;/code&gt; mean?&lt;/strong&gt;
&lt;code&gt;VIRT&lt;/code&gt; is the total virtual address space the process has reserved. &lt;code&gt;RES&lt;/code&gt; is the actual physical RAM currently in use. &lt;code&gt;SHR&lt;/code&gt; is the portion of &lt;code&gt;RES&lt;/code&gt; that is shared with other processes (for example, shared libraries). &lt;code&gt;RES&lt;/code&gt; minus &lt;code&gt;SHR&lt;/code&gt; gives the memory used exclusively by that process.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I save top output to a file?&lt;/strong&gt;
Yes. Use batch mode, for example: &lt;code&gt;top -b -n 1 &amp;gt; top.txt&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;top&lt;/code&gt; command is one of the fastest ways to inspect process activity and system load in real time. Learn the interactive keys and sort options to diagnose performance issues quickly.&lt;/p&gt;
&lt;p&gt;If you have any questions, feel free to leave a comment below.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/top-command-in-linux/featured_hu_f190482b8311c81a.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>sort Command in Linux: Sort Lines of Text</title><link>https://linuxize.com/post/sort-command-in-linux/</link><pubDate>Fri, 27 Feb 2026 09:30:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/sort-command-in-linux/</guid><category>linux commands</category><description>The sort command sorts lines of text files alphabetically or numerically. This guide covers sorting by column, reverse order, unique lines, and combining sort with other commands.</description><content:encoded>&lt;p&gt;&lt;code&gt;sort&lt;/code&gt; is a command-line utility that sorts lines of text from files or standard input and writes the result to standard output. By default, &lt;code&gt;sort&lt;/code&gt; arranges lines alphabetically, but it supports numeric sorting, reverse order, sorting by specific fields, and more.&lt;/p&gt;
&lt;p&gt;This guide explains how to use the &lt;code&gt;sort&lt;/code&gt; command with practical examples.&lt;/p&gt;
&lt;h2 id="sort-command-syntax"&gt;sort Command Syntax &lt;a class="headline-link" href="#sort-command-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The syntax for the &lt;code&gt;sort&lt;/code&gt; command is as follows:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sort [OPTIONS] [FILE]...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If no file is specified, &lt;code&gt;sort&lt;/code&gt; reads from standard input. When multiple files are given, their contents are merged and sorted together.&lt;/p&gt;
&lt;h2 id="sorting-lines-alphabetically"&gt;Sorting Lines Alphabetically &lt;a class="headline-link" href="#sorting-lines-alphabetically" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;sort&lt;/code&gt; sorts lines in ascending alphabetical order. To sort a file, pass the file name as an argument:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sort file.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For example, given a file with the following content:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;file.txt&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;banana
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apple
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cherry
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;date&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Running &lt;code&gt;sort&lt;/code&gt; produces:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;apple
banana
cherry
date&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The original file is not modified. &lt;code&gt;sort&lt;/code&gt; writes the sorted output to standard output. To save the result to a file, use output redirection:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sort file.txt &amp;gt; sorted.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="sorting-in-reverse-order"&gt;Sorting in Reverse Order &lt;a class="headline-link" href="#sorting-in-reverse-order" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To sort in descending order, use the &lt;code&gt;-r&lt;/code&gt; (&lt;code&gt;--reverse&lt;/code&gt;) option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sort -r file.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;date
cherry
banana
apple&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="sorting-numerically"&gt;Sorting Numerically &lt;a class="headline-link" href="#sorting-numerically" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Alphabetical sorting does not work correctly for numbers. For example, &lt;code&gt;10&lt;/code&gt; would sort before &lt;code&gt;2&lt;/code&gt; because &lt;code&gt;1&lt;/code&gt; comes before &lt;code&gt;2&lt;/code&gt; alphabetically. Use the &lt;code&gt;-n&lt;/code&gt; (&lt;code&gt;--numeric-sort&lt;/code&gt;) option to sort numerically:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sort -n numbers.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Given the file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;numbers.txt&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;10
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;30
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;2
5
10
30&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To sort numerically in reverse (largest first), combine &lt;code&gt;-n&lt;/code&gt; and &lt;code&gt;-r&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sort -nr numbers.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;30
10
5
2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="sorting-by-a-specific-column"&gt;Sorting by a Specific Column &lt;a class="headline-link" href="#sorting-by-a-specific-column" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;sort&lt;/code&gt; uses the entire line as the sort key. To sort by a specific field (column), use the &lt;code&gt;-k&lt;/code&gt; (&lt;code&gt;--key&lt;/code&gt;) option followed by the field number.&lt;/p&gt;
&lt;p&gt;Fields are separated by whitespace by default. For example, to sort the following file by the second column (file size):&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;files.txt&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;report.pdf 2500
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;notes.txt 80
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;archive.tar 15000
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;readme.md 200&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sort -k2 -n files.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;notes.txt 80
readme.md 200
report.pdf 2500
archive.tar 15000&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To use a different field separator, specify it with the &lt;code&gt;-t&lt;/code&gt; option. For example, to sort &lt;code&gt;/etc/passwd&lt;/code&gt; by the third field (UID), using &lt;code&gt;:&lt;/code&gt; as the separator:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sort -t: -k3 -n /etc/passwd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="removing-duplicate-lines"&gt;Removing Duplicate Lines &lt;a class="headline-link" href="#removing-duplicate-lines" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To output only unique lines (removing adjacent duplicates after sorting), use the &lt;code&gt;-u&lt;/code&gt; (&lt;code&gt;--unique&lt;/code&gt;) option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sort -u file.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Given a file with repeated entries:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;file.txt&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apple
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;banana
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apple
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cherry
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;banana&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;apple
banana
cherry&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is equivalent to running &lt;code&gt;sort file.txt | uniq&lt;/code&gt;. See our guide to the &lt;a href="https://linuxize.com/post/uniq-command-in-linux/"&gt;uniq command&lt;/a&gt;
for more on how it handles duplicate lines.&lt;/p&gt;
&lt;h2 id="ignoring-case"&gt;Ignoring Case &lt;a class="headline-link" href="#ignoring-case" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;sort&lt;/code&gt; is case-sensitive. Uppercase letters sort before lowercase. To sort case-insensitively, use the &lt;code&gt;-f&lt;/code&gt; (&lt;code&gt;--ignore-case&lt;/code&gt;) option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sort -f file.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="checking-if-a-file-is-already-sorted"&gt;Checking if a File Is Already Sorted &lt;a class="headline-link" href="#checking-if-a-file-is-already-sorted" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To verify that a file is already sorted, use the &lt;code&gt;-c&lt;/code&gt; (&lt;code&gt;--check&lt;/code&gt;) option. It exits silently if the file is sorted, or prints an error and exits with a non-zero status if it is not:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sort -c file.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;sort: file.txt:2: disorder: banana&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is useful in scripts to validate input before processing.&lt;/p&gt;
&lt;h2 id="sorting-human-readable-sizes"&gt;Sorting Human-Readable Sizes &lt;a class="headline-link" href="#sorting-human-readable-sizes" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When working with output from commands like &lt;code&gt;du&lt;/code&gt;, sizes are expressed in human-readable form such as &lt;code&gt;1K&lt;/code&gt;, &lt;code&gt;2M&lt;/code&gt;, or &lt;code&gt;3G&lt;/code&gt;. Standard numeric sort does not handle these correctly. Use the &lt;code&gt;-h&lt;/code&gt; (&lt;code&gt;--human-numeric-sort&lt;/code&gt;) option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;du -sh /var/* &lt;span class="p"&gt;|&lt;/span&gt; sort -h&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;4.0K /var/backups
16K /var/cache
1.2M /var/log
3.4G /var/lib&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="combining-sort-with-other-commands"&gt;Combining sort with Other Commands &lt;a class="headline-link" href="#combining-sort-with-other-commands" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;sort&lt;/code&gt; is commonly used in pipelines with other commands.&lt;/p&gt;
&lt;p&gt;To count and rank the most frequent words in a file, combine &lt;a href="https://linuxize.com/post/how-to-use-grep-command-to-search-files-in-linux/"&gt;&lt;code&gt;grep&lt;/code&gt;&lt;/a&gt;
, &lt;code&gt;sort&lt;/code&gt;, and &lt;a href="https://linuxize.com/post/uniq-command-in-linux/"&gt;&lt;code&gt;uniq&lt;/code&gt;&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep -Eo &lt;span class="s1"&gt;&amp;#39;[[:alnum:]_]+&amp;#39;&lt;/span&gt; file.txt &lt;span class="p"&gt;|&lt;/span&gt; sort &lt;span class="p"&gt;|&lt;/span&gt; uniq -c &lt;span class="p"&gt;|&lt;/span&gt; sort -rn&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To display the ten largest files in a directory, combine &lt;code&gt;sort&lt;/code&gt; with &lt;a href="https://linuxize.com/post/linux-head-command/"&gt;&lt;code&gt;head&lt;/code&gt;&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;du -sh /var/* &lt;span class="p"&gt;|&lt;/span&gt; sort -rh &lt;span class="p"&gt;|&lt;/span&gt; head -10&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To extract and sort a specific field from a CSV using &lt;a href="https://linuxize.com/post/linux-cut-command/"&gt;&lt;code&gt;cut&lt;/code&gt;&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cut -d&lt;span class="s1"&gt;&amp;#39;,&amp;#39;&lt;/span&gt; -f2 data.csv &lt;span class="p"&gt;|&lt;/span&gt; sort&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sort file.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sort alphabetically (ascending)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sort -r file.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sort in reverse order&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sort -n file.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sort numerically&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sort -nr file.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sort numerically, largest first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sort -k2 file.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sort by the second field&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sort -t: -k3 file.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sort by field 3 using &lt;code&gt;:&lt;/code&gt; as separator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sort -u file.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sort and remove duplicate lines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sort -f file.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sort case-insensitively&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sort -h file.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sort human-readable sizes (1K, 2M, 3G)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sort -c file.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Check if file is already sorted&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/sort/"&gt;sort cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Numbers sort in wrong order&lt;/strong&gt;&lt;br&gt;
You are using alphabetical sort on numeric data. Add the &lt;code&gt;-n&lt;/code&gt; option to sort numerically: &lt;code&gt;sort -n file.txt&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Human-readable sizes sort incorrectly&lt;/strong&gt;&lt;br&gt;
Sizes like &lt;code&gt;1K&lt;/code&gt;, &lt;code&gt;2M&lt;/code&gt;, and &lt;code&gt;3G&lt;/code&gt; require &lt;code&gt;-h&lt;/code&gt; (&lt;code&gt;--human-numeric-sort&lt;/code&gt;). Standard &lt;code&gt;-n&lt;/code&gt; only handles plain integers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Uppercase entries appear before lowercase&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sort&lt;/code&gt; is case-sensitive by default. Use &lt;code&gt;-f&lt;/code&gt; to sort case-insensitively, or use &lt;code&gt;LC_ALL=C sort&lt;/code&gt; to enforce byte-order sorting.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Output looks correct on screen but differs from file&lt;/strong&gt;&lt;br&gt;
Output redirection with &lt;code&gt;&amp;gt;&lt;/code&gt; truncates the file before reading. Never redirect to the same file you are sorting: &lt;code&gt;sort file.txt &amp;gt; file.txt&lt;/code&gt; will empty the file. Use a temporary file or the &lt;code&gt;sponge&lt;/code&gt; utility from &lt;code&gt;moreutils&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Does sort modify the original file?&lt;/strong&gt;&lt;br&gt;
No. &lt;code&gt;sort&lt;/code&gt; writes to standard output and never modifies the input file. Use &lt;code&gt;sort file.txt &amp;gt; sorted.txt&lt;/code&gt; or &lt;code&gt;sort -o file.txt file.txt&lt;/code&gt; to save the output.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I sort a file and save it in place?&lt;/strong&gt;&lt;br&gt;
Use the &lt;code&gt;-o&lt;/code&gt; option: &lt;code&gt;sort -o file.txt file.txt&lt;/code&gt;. Unlike &lt;code&gt;&amp;gt; file.txt&lt;/code&gt;, the &lt;code&gt;-o&lt;/code&gt; option is safe to use with the same input and output file.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I sort by the last column?&lt;/strong&gt;&lt;br&gt;
Use a negative field number with the &lt;code&gt;-k&lt;/code&gt; option: &lt;code&gt;sort -k-1&lt;/code&gt; sorts by the last field. Alternatively, use &lt;code&gt;awk&lt;/code&gt; to reorder columns before sorting.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;sort -u&lt;/code&gt; and &lt;code&gt;sort | uniq&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sort -u&lt;/code&gt; is slightly more efficient as it removes duplicates during sorting. &lt;code&gt;sort | uniq&lt;/code&gt; is more flexible because &lt;code&gt;uniq&lt;/code&gt; supports options like &lt;code&gt;-c&lt;/code&gt; (count occurrences) and &lt;code&gt;-d&lt;/code&gt; (show only duplicates).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I sort lines randomly?&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;sort -R&lt;/code&gt; (random sort) or the &lt;code&gt;shuf&lt;/code&gt; command: &lt;code&gt;shuf file.txt&lt;/code&gt;. Both produce a random permutation of the input lines.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;sort&lt;/code&gt; command is a versatile tool for ordering lines of text in files or command output. It is most powerful when combined with other commands like &lt;a href="https://linuxize.com/post/how-to-use-grep-command-to-search-files-in-linux/"&gt;&lt;code&gt;grep&lt;/code&gt;&lt;/a&gt;
, &lt;a href="https://linuxize.com/post/linux-cut-command/"&gt;&lt;code&gt;cut&lt;/code&gt;&lt;/a&gt;
, and &lt;a href="https://linuxize.com/post/linux-head-command/"&gt;&lt;code&gt;head&lt;/code&gt;&lt;/a&gt;
in pipelines.&lt;/p&gt;
&lt;p&gt;If you have any questions, feel free to leave a comment below.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/sort-command-in-linux/featured_hu_700aab42c42f2d.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>journalctl Command in Linux: Query and Filter System Logs</title><link>https://linuxize.com/post/journalctl-command-in-linux/</link><pubDate>Thu, 26 Feb 2026 10:00:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/journalctl-command-in-linux/</guid><category>linux commands</category><description>journalctl queries the systemd journal and lets you filter logs by unit, time, priority, boot, and process. This guide covers the most useful journalctl options with practical examples.</description><content:encoded>&lt;p&gt;&lt;code&gt;journalctl&lt;/code&gt; is a command-line utility for querying and displaying logs collected by &lt;code&gt;systemd-journald&lt;/code&gt;, the systemd logging daemon. It gives you structured access to all system logs — kernel messages, service output, authentication events, and more — from a single interface.&lt;/p&gt;
&lt;p&gt;This guide explains how to use &lt;code&gt;journalctl&lt;/code&gt; to view, filter, and manage system logs.&lt;/p&gt;
&lt;h2 id="journalctl-command-syntax"&gt;journalctl Command Syntax &lt;a class="headline-link" href="#journalctl-command-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The general syntax for the &lt;code&gt;journalctl&lt;/code&gt; command is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl [OPTIONS] [MATCHES]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When invoked without any options, &lt;code&gt;journalctl&lt;/code&gt; displays all collected logs starting from the oldest entry, piped through a pager (usually &lt;code&gt;less&lt;/code&gt;). Press &lt;code&gt;q&lt;/code&gt; to exit.&lt;/p&gt;
&lt;p&gt;Only the root user or members of the &lt;code&gt;adm&lt;/code&gt; or &lt;code&gt;systemd-journal&lt;/code&gt; groups can read system logs. Regular users can view their own user journal with the &lt;code&gt;--user&lt;/code&gt; flag.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;journalctl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show all logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;journalctl -f&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Follow new log entries in real time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;journalctl -n 50&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show last 50 lines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;journalctl -r&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show logs newest first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;journalctl -e&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Jump to end of logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;journalctl -u nginx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Logs for a specific unit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;journalctl -u nginx -f&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Follow unit logs in real time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;journalctl -b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Current boot logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;journalctl -b -1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Previous boot logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;journalctl --list-boots&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List all boots&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;journalctl -p err&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Errors and above&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;journalctl -p warning --since &amp;quot;1 hour ago&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Recent warnings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;journalctl -k&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Kernel messages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;journalctl --since &amp;quot;yesterday&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Logs since yesterday&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;journalctl --since &amp;quot;2026-02-01&amp;quot; --until &amp;quot;2026-02-02&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Logs in a time window&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;journalctl -g &amp;quot;failed&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Search by pattern&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;journalctl -o json-pretty&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;JSON output&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;journalctl --disk-usage&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show journal disk usage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;journalctl --vacuum-size=500M&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Reduce journal to 500 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/journalctl/"&gt;journalctl cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="viewing-system-logs"&gt;Viewing System Logs &lt;a class="headline-link" href="#viewing-system-logs" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To view all system logs, run &lt;code&gt;journalctl&lt;/code&gt; without any options:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To show the most recent entries first, use the &lt;code&gt;-r&lt;/code&gt; flag:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -r&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To jump directly to the end of the log, use &lt;code&gt;-e&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -e&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To show the last N lines (similar to &lt;a href="https://linuxize.com/post/linux-tail-command/"&gt;&lt;code&gt;tail&lt;/code&gt;&lt;/a&gt;
), use the &lt;code&gt;-n&lt;/code&gt; flag:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -n &lt;span class="m"&gt;50&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To disable the pager and print directly to the terminal, use &lt;code&gt;--no-pager&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl --no-pager&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="following-logs-in-real-time"&gt;Following Logs in Real Time &lt;a class="headline-link" href="#following-logs-in-real-time" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To stream new log entries as they arrive (similar to &lt;code&gt;tail -f&lt;/code&gt;), use the &lt;code&gt;-f&lt;/code&gt; flag:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -f&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is one of the most useful options for monitoring a running service or troubleshooting an active issue. Press &lt;code&gt;Ctrl+C&lt;/code&gt; to stop.&lt;/p&gt;
&lt;h2 id="filtering-by-systemd-unit"&gt;Filtering by Systemd Unit &lt;a class="headline-link" href="#filtering-by-systemd-unit" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To view logs for a specific systemd service, use the &lt;code&gt;-u&lt;/code&gt; flag followed by the unit name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -u nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can combine &lt;code&gt;-u&lt;/code&gt; with other filters. For example, to follow nginx logs in real time:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -u nginx -f&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To view logs for multiple units at once, specify &lt;code&gt;-u&lt;/code&gt; more than once:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -u nginx -u php-fpm&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To print the last 100 lines for a service without the pager:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -u nginx -n &lt;span class="m"&gt;100&lt;/span&gt; --no-pager&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For more on starting and stopping services, see &lt;a href="https://linuxize.com/post/start-stop-restart-nginx/"&gt;how to start, stop, and restart Nginx&lt;/a&gt;
and &lt;a href="https://linuxize.com/post/start-stop-restart-apache/"&gt;Apache&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="filtering-by-time"&gt;Filtering by Time &lt;a class="headline-link" href="#filtering-by-time" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;--since&lt;/code&gt; and &lt;code&gt;--until&lt;/code&gt; to limit log output to a specific time range.&lt;/p&gt;
&lt;p&gt;To show logs since a specific date and time:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl --since &lt;span class="s2"&gt;&amp;#34;2026-02-01 10:00&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To show logs within a window:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl --since &lt;span class="s2"&gt;&amp;#34;2026-02-01 10:00&amp;#34;&lt;/span&gt; --until &lt;span class="s2"&gt;&amp;#34;2026-02-01 12:00&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;journalctl&lt;/code&gt; accepts many natural time expressions:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl --since &lt;span class="s2"&gt;&amp;#34;1 hour ago&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl --since &lt;span class="s2"&gt;&amp;#34;yesterday&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl --since today&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can combine time filters with unit filters. For example, to view nginx logs from the past hour:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -u nginx --since &lt;span class="s2"&gt;&amp;#34;1 hour ago&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="filtering-by-priority"&gt;Filtering by Priority &lt;a class="headline-link" href="#filtering-by-priority" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;systemd uses the standard syslog priority levels. Use the &lt;code&gt;-p&lt;/code&gt; flag to filter by severity:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -p err&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output will include the specified priority and all higher-severity levels. The available priority levels from highest to lowest are:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;&lt;code&gt;emerg&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;System is unusable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;alert&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Immediate action required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;crit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Critical conditions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;code&gt;err&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Error conditions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;code&gt;warning&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Warning conditions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;code&gt;notice&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Normal but significant events&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;code&gt;info&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Informational messages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;&lt;code&gt;debug&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Debug-level messages&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;To view only warnings and above from the last hour:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -p warning --since &lt;span class="s2"&gt;&amp;#34;1 hour ago&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="filtering-by-boot"&gt;Filtering by Boot &lt;a class="headline-link" href="#filtering-by-boot" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The journal stores logs from multiple boots. Use &lt;code&gt;-b&lt;/code&gt; to filter by boot session.&lt;/p&gt;
&lt;p&gt;To view logs from the current boot:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -b&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To view logs from the previous boot:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -b -1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To list all available boot sessions with their IDs and timestamps:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl --list-boots&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output will look something like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;-2 abc123def456 Mon 2026-02-24 08:12:01 CET—Mon 2026-02-24 18:43:22 CET
-1 def456abc789 Tue 2026-02-25 09:05:14 CET—Tue 2026-02-25 21:11:03 CET
0 789abcdef012 Wed 2026-02-26 08:30:41 CET—Wed 2026-02-26 14:00:00 CET&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To view logs for a specific boot ID:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -b abc123def456&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To view errors from the previous boot:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -b -1 -p err&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="kernel-messages"&gt;Kernel Messages &lt;a class="headline-link" href="#kernel-messages" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To view kernel messages only (equivalent to &lt;a href="https://linuxize.com/post/dmesg-command-in-linux/"&gt;&lt;code&gt;dmesg&lt;/code&gt;&lt;/a&gt;
), use the &lt;code&gt;-k&lt;/code&gt; flag:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -k&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To view kernel messages from the current boot:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -k -b&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To view kernel errors from the previous boot:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -k -p err -b -1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="filtering-by-process"&gt;Filtering by Process &lt;a class="headline-link" href="#filtering-by-process" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In addition to filtering by unit, you can filter logs by process name, executable path, PID, or user ID using journal fields.&lt;/p&gt;
&lt;p&gt;To filter by process name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl &lt;span class="nv"&gt;_COMM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;sshd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To filter by executable path:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl &lt;span class="nv"&gt;_EXE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/sbin/sshd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To filter by PID:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl &lt;span class="nv"&gt;_PID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1234&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To filter by user ID:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl &lt;span class="nv"&gt;_UID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Multiple fields can be combined to narrow the results further.&lt;/p&gt;
&lt;h2 id="searching-log-messages"&gt;Searching Log Messages &lt;a class="headline-link" href="#searching-log-messages" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To search log messages by a pattern, use the &lt;code&gt;-g&lt;/code&gt; flag followed by a regular expression:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -g &lt;span class="s2"&gt;&amp;#34;failed&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To search within a specific unit:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -u ssh -g &lt;span class="s2"&gt;&amp;#34;invalid user&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can also pipe &lt;code&gt;journalctl&lt;/code&gt; output to &lt;a href="https://linuxize.com/post/how-to-use-grep-command-to-search-files-in-linux/"&gt;&lt;code&gt;grep&lt;/code&gt;&lt;/a&gt;
for more complex matching:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -u nginx -n &lt;span class="m"&gt;500&lt;/span&gt; --no-pager &lt;span class="p"&gt;|&lt;/span&gt; grep -i &lt;span class="s2"&gt;&amp;#34;upstream&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="output-formats"&gt;Output Formats &lt;a class="headline-link" href="#output-formats" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;journalctl&lt;/code&gt; displays logs in a human-readable format. Use the &lt;code&gt;-o&lt;/code&gt; flag to change the output format.&lt;/p&gt;
&lt;p&gt;To display logs with ISO 8601 timestamps:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -o short-iso&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To display logs as JSON (useful for scripting and log shipping):&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -o json-pretty&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To display message text only, without metadata:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -o cat&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The most commonly used output formats are:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;short&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Default human-readable format&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;short-iso&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ISO 8601 timestamps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;short-precise&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Microsecond-precision timestamps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;One JSON object per line&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;json-pretty&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Formatted JSON&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Message text only&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="managing-journal-size"&gt;Managing Journal Size &lt;a class="headline-link" href="#managing-journal-size" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The journal stores logs on disk under &lt;code&gt;/var/log/journal/&lt;/code&gt;. To check how much disk space the journal is using:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl --disk-usage&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Archived and active journals take up 512.0M in the file system.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To reduce the journal size, use the &lt;code&gt;--vacuum-size&lt;/code&gt;, &lt;code&gt;--vacuum-time&lt;/code&gt;, or &lt;code&gt;--vacuum-files&lt;/code&gt; options:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl --vacuum-size&lt;span class="o"&gt;=&lt;/span&gt;500M&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl --vacuum-time&lt;span class="o"&gt;=&lt;/span&gt;30d&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl --vacuum-files&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;These commands remove old archived journal files until the specified limit is met. To configure a permanent size limit, edit &lt;code&gt;/etc/systemd/journald.conf&lt;/code&gt; and set &lt;code&gt;SystemMaxUse=&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="practical-troubleshooting-workflow"&gt;Practical Troubleshooting Workflow &lt;a class="headline-link" href="#practical-troubleshooting-workflow" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When a service fails, we can use a short sequence to isolate the issue quickly. First, check service state with &lt;a href="https://linuxize.com/post/systemctl-command-in-linux/"&gt;&lt;code&gt;systemctl&lt;/code&gt;&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl status nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Then inspect recent error-level logs for that unit:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo journalctl -u nginx -p err -n &lt;span class="m"&gt;100&lt;/span&gt; --no-pager&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the problem started after reboot, inspect previous boot logs:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo journalctl -u nginx -b -1 -p err --no-pager&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To narrow the time window around the incident:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo journalctl -u nginx --since &lt;span class="s2"&gt;&amp;#34;30 minutes ago&amp;#34;&lt;/span&gt; --no-pager&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you need pattern matching across many lines, pipe to &lt;a href="https://linuxize.com/post/how-to-use-grep-command-to-search-files-in-linux/"&gt;&lt;code&gt;grep&lt;/code&gt;&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo journalctl -u nginx -n &lt;span class="m"&gt;500&lt;/span&gt; --no-pager &lt;span class="p"&gt;|&lt;/span&gt; grep -Ei &lt;span class="s2"&gt;&amp;#34;error|failed|timeout&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;No journal files were found&amp;rdquo;&lt;/strong&gt;&lt;br&gt;
The systemd journal may not be persistent on your system. Check if &lt;code&gt;/var/log/journal/&lt;/code&gt; exists. If it does not, create it with &lt;code&gt;mkdir -p /var/log/journal&lt;/code&gt; and restart &lt;code&gt;systemd-journald&lt;/code&gt;. Alternatively, set &lt;code&gt;Storage=persistent&lt;/code&gt; in &lt;code&gt;/etc/systemd/journald.conf&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;Permission denied&amp;rdquo; reading logs&lt;/strong&gt;&lt;br&gt;
Regular users can only access their own user journal. To read system logs, run &lt;code&gt;journalctl&lt;/code&gt; with &lt;code&gt;sudo&lt;/code&gt;, or add your user to the &lt;code&gt;adm&lt;/code&gt; or &lt;code&gt;systemd-journal&lt;/code&gt; group: &lt;code&gt;usermod -aG systemd-journal USERNAME&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;-g&lt;/code&gt; pattern search returns no results&lt;/strong&gt;&lt;br&gt;
The &lt;code&gt;-g&lt;/code&gt; flag uses PCRE2 regular expressions. Make sure the pattern is correct and that your &lt;code&gt;journalctl&lt;/code&gt; version supports &lt;code&gt;-g&lt;/code&gt; (available on modern systemd releases). As an alternative, pipe the output to &lt;code&gt;grep&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Logs missing after reboot&lt;/strong&gt;&lt;br&gt;
The journal is stored in memory by default on some distributions. To enable persistent storage across reboots, set &lt;code&gt;Storage=persistent&lt;/code&gt; in &lt;code&gt;/etc/systemd/journald.conf&lt;/code&gt; and restart &lt;code&gt;systemd-journald&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Journal consuming too much disk space&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;journalctl --disk-usage&lt;/code&gt; to check the current size, then &lt;code&gt;journalctl --vacuum-size=500M&lt;/code&gt; to trim old entries. For a permanent limit, configure &lt;code&gt;SystemMaxUse=&lt;/code&gt; in &lt;code&gt;/etc/systemd/journald.conf&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between journalctl and /var/log/syslog?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;/var/log/syslog&lt;/code&gt; is a plain text file written by &lt;code&gt;rsyslog&lt;/code&gt; or &lt;code&gt;syslog-ng&lt;/code&gt;. &lt;code&gt;journalctl&lt;/code&gt; reads the binary systemd journal, which stores structured metadata alongside each message. The journal offers better filtering, field-based queries, and persistent boot tracking.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I view logs for a service that keeps restarting?&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;journalctl -u servicename -f&lt;/code&gt; to follow logs in real time, or &lt;code&gt;journalctl -u servicename -n 200&lt;/code&gt; to view the most recent entries. Adding &lt;code&gt;-p err&lt;/code&gt; will surface only error-level messages.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I check logs from before the current boot?&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;journalctl -b -1&lt;/code&gt; for the previous boot, or &lt;code&gt;journalctl --list-boots&lt;/code&gt; to see all available boot sessions and then &lt;code&gt;journalctl -b BOOTID&lt;/code&gt; to query a specific one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I export logs to a file?&lt;/strong&gt;&lt;br&gt;
Yes. Use &lt;code&gt;journalctl --no-pager &amp;gt; output.log&lt;/code&gt; for plain text, or &lt;code&gt;journalctl -o json-pretty &amp;gt; output.json&lt;/code&gt; for structured JSON. You can combine this with any filter flags.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I reduce the amount of disk space used by the journal?&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;journalctl --vacuum-size=500M&lt;/code&gt; to immediately trim archived logs to 500 MB. For a persistent limit, set &lt;code&gt;SystemMaxUse=500M&lt;/code&gt; in &lt;code&gt;/etc/systemd/journald.conf&lt;/code&gt; and restart the journal daemon with &lt;code&gt;systemctl restart systemd-journald&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;journalctl&lt;/code&gt; is a powerful and flexible tool for querying the systemd journal. Whether you are troubleshooting a failing service, reviewing kernel messages, or auditing authentication events, mastering its filter options saves significant time. If you have any questions, feel free to leave a comment below.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/journalctl-command-in-linux/featured_hu_84ca571a8c25b7ea.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>Linux patch Command: Apply Diff Files</title><link>https://linuxize.com/post/patch-command-in-linux/</link><pubDate>Sun, 22 Feb 2026 18:00:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/patch-command-in-linux/</guid><category>linux commands</category><description>The patch command applies diff files to original files in Linux. This guide covers basic usage, strip paths, dry run, backup, and reversing patches with examples.</description><content:encoded>&lt;p&gt;The &lt;code&gt;patch&lt;/code&gt; command applies a set of changes described in a diff file to one or more original files. It is the standard way to distribute and apply source code changes, security fixes, and configuration updates in Linux, and pairs directly with the &lt;a href="https://linuxize.com/post/diff-command-in-linux/"&gt;&lt;code&gt;diff&lt;/code&gt;&lt;/a&gt;
command.&lt;/p&gt;
&lt;p&gt;This guide explains how to use the &lt;code&gt;patch&lt;/code&gt; command in Linux with practical examples.&lt;/p&gt;
&lt;h2 id="syntax"&gt;Syntax &lt;a class="headline-link" href="#syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The general syntax of the &lt;code&gt;patch&lt;/code&gt; command is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;patch [OPTIONS] [ORIGINALFILE] [PATCHFILE]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can pass the patch file using the &lt;code&gt;-i&lt;/code&gt; option or pipe it through standard input:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;patch [OPTIONS] -i patchfile [ORIGINALFILE]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;patch [OPTIONS] [ORIGINALFILE] &amp;lt; patchfile&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="patch-options"&gt;patch Options &lt;a class="headline-link" href="#patch-options" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Long form&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-i FILE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--input=FILE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Read the patch from FILE instead of stdin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-p N&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--strip=N&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Strip N leading path components from file names in the patch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-R&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--reverse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Reverse the patch (undo a previously applied patch)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--backup&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Back up the original file before patching&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--dry-run&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Test the patch without making any changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-d DIR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--directory=DIR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Change to DIR before doing anything&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-N&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--forward&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Skip patches that appear to be already applied&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-l&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--ignore-whitespace&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ignore whitespace differences when matching lines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-f&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--force&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Force apply even if the patch does not match cleanly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-u&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--unified&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Interpret the patch as a unified diff&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="create-and-apply-a-basic-patch"&gt;Create and Apply a Basic Patch &lt;a class="headline-link" href="#create-and-apply-a-basic-patch" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The most common workflow is to use &lt;code&gt;diff&lt;/code&gt; to generate a patch file and &lt;code&gt;patch&lt;/code&gt; to apply it.&lt;/p&gt;
&lt;p&gt;Start with two versions of a file. Here is the original:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;hello.py&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;print(&amp;#34;Hello, World!&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;print(&amp;#34;Version 1&amp;#34;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;And the updated version:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;hello_new.py&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;print(&amp;#34;Hello, Linux!&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;print(&amp;#34;Version 2&amp;#34;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Use &lt;a href="https://linuxize.com/post/diff-command-in-linux/"&gt;&lt;code&gt;diff&lt;/code&gt;&lt;/a&gt;
with the &lt;code&gt;-u&lt;/code&gt; flag to generate a unified diff and save it to a patch file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;diff -u hello.py hello_new.py &amp;gt; hello.patch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;hello.patch&lt;/code&gt; file will contain the following differences:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;--- hello.py 2026-02-21 10:00:00.000000000 +0100
+++ hello_new.py 2026-02-21 10:05:00.000000000 +0100
@@ -1,2 +1,2 @@
-print(&amp;#34;Hello, World!&amp;#34;)
-print(&amp;#34;Version 1&amp;#34;)
+print(&amp;#34;Hello, Linux!&amp;#34;)
+print(&amp;#34;Version 2&amp;#34;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To apply the patch to the original file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;patch hello.py hello.patch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;patching file hello.py&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;hello.py&lt;/code&gt; now contains the updated content from &lt;code&gt;hello_new.py&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="dry-run-before-applying"&gt;Dry Run Before Applying &lt;a class="headline-link" href="#dry-run-before-applying" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;--dry-run&lt;/code&gt; to test whether a patch will apply cleanly without actually modifying any files:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;patch --dry-run hello.py hello.patch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;patching file hello.py&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If the patch cannot be applied cleanly, &lt;code&gt;patch&lt;/code&gt; reports the conflict without touching any files. This is useful before applying patches from external sources or when you are unsure whether a patch has already been applied.&lt;/p&gt;
&lt;h2 id="back-up-the-original-file"&gt;Back Up the Original File &lt;a class="headline-link" href="#back-up-the-original-file" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use the &lt;code&gt;-b&lt;/code&gt; option to create a backup of the original file before applying the patch. The backup is saved with a &lt;code&gt;.orig&lt;/code&gt; extension:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;patch -b hello.py hello.patch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;patching file hello.py&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After running this command, &lt;code&gt;hello.py.orig&lt;/code&gt; contains the original unpatched file. You can restore it manually if needed.&lt;/p&gt;
&lt;h2 id="strip-path-components-with--p"&gt;Strip Path Components with -p &lt;a class="headline-link" href="#strip-path-components-with--p" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When a patch file is generated from a different directory structure than the one where you apply it, the file paths inside the patch may not match your local paths. Use &lt;code&gt;-p N&lt;/code&gt; to strip N leading path components from the paths recorded in the patch.&lt;/p&gt;
&lt;p&gt;For example, a patch generated with &lt;code&gt;git diff&lt;/code&gt; will reference files like:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;--- a/src/utils/hello.py
+++ b/src/utils/hello.py&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To apply this patch from the project root, use &lt;code&gt;-p1&lt;/code&gt; to strip the &lt;code&gt;a/&lt;/code&gt; and &lt;code&gt;b/&lt;/code&gt; prefixes:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;patch -p1 &amp;lt; hello.patch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;-p1&lt;/code&gt; is the standard option for patches generated by &lt;code&gt;git diff&lt;/code&gt; and by &lt;code&gt;diff -u&lt;/code&gt; from the root of a project directory. Without it, &lt;code&gt;patch&lt;/code&gt; would look for a file named &lt;code&gt;a/src/utils/hello.py&lt;/code&gt; on disk, which does not exist.&lt;/p&gt;
&lt;h2 id="reverse-a-patch"&gt;Reverse a Patch &lt;a class="headline-link" href="#reverse-a-patch" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use the &lt;code&gt;-R&lt;/code&gt; option to undo a previously applied patch and restore the original file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;patch -R hello.py hello.patch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;patching file hello.py&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The file is restored to its state before the patch was applied.&lt;/p&gt;
&lt;h2 id="apply-a-multi-file-patch"&gt;Apply a Multi-File Patch &lt;a class="headline-link" href="#apply-a-multi-file-patch" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A single patch file can contain changes to multiple files. In this case, you do not specify a target file on the command line — &lt;code&gt;patch&lt;/code&gt; reads the file names from the diff headers inside the patch:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;patch -p1 &amp;lt; project.patch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;patch&lt;/code&gt; processes each file name from the diff headers and applies the corresponding changes. Use &lt;code&gt;-p1&lt;/code&gt; when the patch was produced by &lt;code&gt;git diff&lt;/code&gt; or &lt;code&gt;diff -u&lt;/code&gt; from the project root.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Apply a patch&lt;/td&gt;
&lt;td&gt;&lt;code&gt;patch original.txt changes.patch&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apply from stdin&lt;/td&gt;
&lt;td&gt;&lt;code&gt;patch -p1 &amp;lt; changes.patch&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Specify patch file with &lt;code&gt;-i&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;patch -i changes.patch original.txt&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dry run (test without applying)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;patch --dry-run -p1 &amp;lt; changes.patch&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Back up original before patching&lt;/td&gt;
&lt;td&gt;&lt;code&gt;patch -b original.txt changes.patch&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strip one path prefix (git patches)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;patch -p1 &amp;lt; changes.patch&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reverse a patch&lt;/td&gt;
&lt;td&gt;&lt;code&gt;patch -R original.txt changes.patch&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ignore whitespace differences&lt;/td&gt;
&lt;td&gt;&lt;code&gt;patch -l original.txt changes.patch&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apply to a specific directory&lt;/td&gt;
&lt;td&gt;&lt;code&gt;patch -d /path/to/dir -p1 &amp;lt; changes.patch&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Hunk #1 FAILED at line N.&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The patch does not match the current content of the file. This usually means the file has already been modified since the patch was created, or you are applying the patch against the wrong version. &lt;code&gt;patch&lt;/code&gt; creates a &lt;code&gt;.rej&lt;/code&gt; file containing the failed hunk so you can review and apply the change manually.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Reversed (or previously applied) patch detected! Assume -R?&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;patch&lt;/code&gt; has detected that the changes in the patch are already present in the file — the patch may have been applied before. Answer &lt;code&gt;y&lt;/code&gt; to reverse the patch or &lt;code&gt;n&lt;/code&gt; to skip it. Use &lt;code&gt;-N&lt;/code&gt; (&lt;code&gt;--forward&lt;/code&gt;) to automatically skip already-applied patches without prompting.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;patch: **** malformed patch at line N&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The patch file is corrupted or not in a recognized format. Make sure the patch was generated with &lt;code&gt;diff -u&lt;/code&gt; (unified format). Non-unified formats require the &lt;code&gt;-c&lt;/code&gt; (context) or specific format flag to be passed to &lt;code&gt;patch&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;File paths in the patch do not match files on disk.&lt;/strong&gt;&lt;br&gt;
Adjust the &lt;code&gt;-p N&lt;/code&gt; value. Run &lt;code&gt;patch --dry-run -p0 &amp;lt; changes.patch&lt;/code&gt; first, then increment &lt;code&gt;N&lt;/code&gt; (&lt;code&gt;-p1&lt;/code&gt;, &lt;code&gt;-p2&lt;/code&gt;) until &lt;code&gt;patch&lt;/code&gt; finds the correct files.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;How do I create a patch file?&lt;/strong&gt;&lt;br&gt;
Use the &lt;code&gt;diff&lt;/code&gt; command with the &lt;code&gt;-u&lt;/code&gt; flag: &lt;code&gt;diff -u original.txt updated.txt &amp;gt; changes.patch&lt;/code&gt;. The &lt;code&gt;-u&lt;/code&gt; flag produces a unified diff, which is the format &lt;code&gt;patch&lt;/code&gt; works with by default. See the &lt;a href="https://linuxize.com/post/diff-command-in-linux/"&gt;diff command guide&lt;/a&gt;
for details.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What does &lt;code&gt;-p1&lt;/code&gt; mean?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;-p1&lt;/code&gt; tells &lt;code&gt;patch&lt;/code&gt; to strip one leading path component from file names in the patch. Patches generated by &lt;code&gt;git diff&lt;/code&gt; prefix file paths with &lt;code&gt;a/&lt;/code&gt; and &lt;code&gt;b/&lt;/code&gt;, so &lt;code&gt;-p1&lt;/code&gt; removes that prefix before &lt;code&gt;patch&lt;/code&gt; looks for the file on disk.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I undo a patch I already applied?&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;patch -R originalfile patchfile&lt;/code&gt;. &lt;code&gt;patch&lt;/code&gt; reads the diff in reverse and restores the original content.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is a &lt;code&gt;.rej&lt;/code&gt; file?&lt;/strong&gt;&lt;br&gt;
When &lt;code&gt;patch&lt;/code&gt; cannot apply one or more sections of a patch (called hunks), it writes the failed hunks to a file with a &lt;code&gt;.rej&lt;/code&gt; extension alongside the original file. You can open the &lt;code&gt;.rej&lt;/code&gt; file and apply those changes manually.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;patch&lt;/code&gt; and &lt;code&gt;git apply&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
Both apply diff files, but &lt;code&gt;git apply&lt;/code&gt; is designed for use inside a Git repository and integrates with the Git index. &lt;code&gt;patch&lt;/code&gt; is a standalone POSIX tool that works on any file regardless of version control.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;patch&lt;/code&gt; command is the standard tool for applying diff files in Linux. Use &lt;code&gt;--dry-run&lt;/code&gt; to verify a patch before applying it, &lt;code&gt;-b&lt;/code&gt; to keep a backup of the original, and &lt;code&gt;-R&lt;/code&gt; to reverse changes when needed.&lt;/p&gt;
&lt;p&gt;If you have any questions, feel free to leave a comment below.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/patch-command-in-linux/featured_hu_79809047ef86d29c.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>Understanding the /etc/fstab File in Linux</title><link>https://linuxize.com/post/etc-fstab-file/</link><pubDate>Wed, 18 Feb 2026 13:00:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/etc-fstab-file/</guid><category>mount</category><category>linux commands</category><description>The /etc/fstab file defines how filesystems and storage devices are mounted at boot. This guide explains the fstab format, field meanings, mount options, and how to add new entries safely.</description><content:encoded>&lt;p&gt;The &lt;code&gt;/etc/fstab&lt;/code&gt; file (filesystem table) is a system configuration file that defines how filesystems, partitions, and storage devices are mounted at boot time. The system reads this file during startup and mounts each entry automatically.&lt;/p&gt;
&lt;p&gt;Understanding &lt;code&gt;/etc/fstab&lt;/code&gt; is essential when you need to add a new disk, &lt;a href="https://linuxize.com/post/create-a-linux-swap-file/"&gt;create a swap file&lt;/a&gt;
, &lt;a href="https://linuxize.com/post/how-to-mount-an-nfs-share-in-linux/"&gt;mount a network share&lt;/a&gt;
, or change mount options for an existing filesystem.&lt;/p&gt;
&lt;p&gt;This guide explains the &lt;code&gt;/etc/fstab&lt;/code&gt; file format, what each field means, common mount options, and how to add new entries safely.&lt;/p&gt;
&lt;h2 id="etcfstab-format"&gt;/etc/fstab Format &lt;a class="headline-link" href="#etcfstab-format" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;/etc/fstab&lt;/code&gt; file is a plain text file with one entry per line. Each line defines a filesystem to mount. Lines beginning with &lt;code&gt;#&lt;/code&gt; are comments and are ignored by the system.&lt;/p&gt;
&lt;p&gt;To view the contents of the file safely, use &lt;a href="https://linuxize.com/post/less-command-in-linux/"&gt;&lt;code&gt;less&lt;/code&gt;&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;less /etc/fstab&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;A typical &lt;code&gt;/etc/fstab&lt;/code&gt; file looks like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;# &amp;lt;file system&amp;gt; &amp;lt;mount point&amp;gt; &amp;lt;type&amp;gt; &amp;lt;options&amp;gt; &amp;lt;dump&amp;gt; &amp;lt;pass&amp;gt;
UUID=a1b2c3d4-e5f6-7890-abcd-ef1234567890 / ext4 errors=remount-ro 0 1
UUID=b2c3d4e5-f6a7-8901-bcde-f12345678901 /home ext4 defaults 0 2
UUID=c3d4e5f6-a7b8-9012-cdef-123456789012 none swap sw 0 0
tmpfs /tmp tmpfs defaults,noatime 0 0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Each entry contains six space-separated fields:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;UUID=a1b2c3d4... /home ext4 defaults 0 2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[---------------] [---] [--] [------] - -
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| | | | | |
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| | | | | +-&amp;gt; 6. Pass (fsck order)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| | | | +----&amp;gt; 5. Dump (backup flag)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| | | +-----------&amp;gt; 4. Options
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| | +------------------&amp;gt; 3. Type
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| +-------------------------&amp;gt; 2. Mount point
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;+---------------------------------------------&amp;gt; 1. File system&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="field-descriptions"&gt;Field Descriptions &lt;a class="headline-link" href="#field-descriptions" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;File system&lt;/strong&gt; - The device or partition to mount. This can be specified as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A UUID: &lt;code&gt;UUID=a1b2c3d4-e5f6-7890-abcd-ef1234567890&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;A disk label: &lt;code&gt;LABEL=home&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;A device path: &lt;code&gt;/dev/sda1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;A network path: &lt;code&gt;192.168.1.10:/export/share&lt;/code&gt; (for NFS)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Using UUIDs is recommended because device paths like &lt;code&gt;/dev/sda1&lt;/code&gt; can change if disks are added or removed. To find the UUID of a partition, run &lt;code&gt;blkid&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo blkid&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Mount point&lt;/strong&gt; - The directory where the filesystem is attached. The directory must already exist. Common mount points include &lt;code&gt;/&lt;/code&gt;, &lt;code&gt;/home&lt;/code&gt;, &lt;code&gt;/boot&lt;/code&gt;, and &lt;code&gt;/mnt/data&lt;/code&gt;. For swap entries, this field is set to &lt;code&gt;none&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Type&lt;/strong&gt; - The filesystem type. Common values include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ext4&lt;/code&gt; - The default Linux filesystem&lt;/li&gt;
&lt;li&gt;&lt;code&gt;xfs&lt;/code&gt; - High-performance filesystem used on RHEL-based distributions&lt;/li&gt;
&lt;li&gt;&lt;code&gt;btrfs&lt;/code&gt; - Copy-on-write filesystem with snapshot support&lt;/li&gt;
&lt;li&gt;&lt;code&gt;swap&lt;/code&gt; - Swap partition or file&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tmpfs&lt;/code&gt; - Temporary filesystem stored in memory&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nfs&lt;/code&gt; - Network File System&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vfat&lt;/code&gt; - FAT32 filesystem (USB drives, EFI partitions)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;auto&lt;/code&gt; - Let the kernel detect the filesystem type automatically&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Options&lt;/strong&gt; - A comma-separated list of mount options. See the &lt;a href="#common-mount-options"&gt;Common Mount Options&lt;/a&gt;
section below for details.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Dump&lt;/strong&gt; - Used by the &lt;code&gt;dump&lt;/code&gt; backup utility. A value of &lt;code&gt;0&lt;/code&gt; means the filesystem is not included in backups. A value of &lt;code&gt;1&lt;/code&gt; means it is. Most modern systems do not use &lt;code&gt;dump&lt;/code&gt;, so this is typically set to &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Pass&lt;/strong&gt; - The order in which &lt;code&gt;fsck&lt;/code&gt; checks filesystems at boot. The root filesystem should be &lt;code&gt;1&lt;/code&gt;. Other filesystems should be &lt;code&gt;2&lt;/code&gt; so they are checked after root. A value of &lt;code&gt;0&lt;/code&gt; means the filesystem is not checked.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="common-mount-options"&gt;Common Mount Options &lt;a class="headline-link" href="#common-mount-options" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The fourth field in each fstab entry is a comma-separated list of mount options. The following options are the most commonly used:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;defaults&lt;/code&gt; - Uses the standard default options (&lt;code&gt;rw&lt;/code&gt;, &lt;code&gt;suid&lt;/code&gt;, &lt;code&gt;dev&lt;/code&gt;, &lt;code&gt;exec&lt;/code&gt;, &lt;code&gt;auto&lt;/code&gt;, &lt;code&gt;nouser&lt;/code&gt;, &lt;code&gt;async&lt;/code&gt;). Some effective behaviors can still vary by filesystem and kernel settings.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ro&lt;/code&gt; - Mount the filesystem as read-only.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rw&lt;/code&gt; - Mount the filesystem as read-write.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;noatime&lt;/code&gt; - Do not update file access times. This can improve performance, especially on SSDs.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nodiratime&lt;/code&gt; - Do not update directory access times.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;noexec&lt;/code&gt; - Do not allow execution of binaries on the filesystem.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nosuid&lt;/code&gt; - Do not allow set-user-ID or set-group-ID bits to take effect.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nodev&lt;/code&gt; - Do not interpret character or block special devices on the filesystem.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nofail&lt;/code&gt; - Do not report errors if the device does not exist at boot. Useful for removable drives and network shares.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;auto&lt;/code&gt; - Mount the filesystem automatically at boot (default behavior).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;noauto&lt;/code&gt; - Do not mount automatically at boot. The filesystem can still be mounted manually with &lt;code&gt;mount&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;user&lt;/code&gt; - Allow a regular user to mount the filesystem.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;errors=remount-ro&lt;/code&gt; - Remount the filesystem as read-only if an error occurs. Common on root filesystem entries.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;_netdev&lt;/code&gt; - The filesystem requires network access. The system waits for the network to be available before mounting. Use this for NFS, CIFS, and iSCSI mounts.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x-systemd.automount&lt;/code&gt; - Mount the filesystem on first access instead of at boot. Managed by systemd.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can combine multiple options separated by commas:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;UUID=a1b2c3d4... /data ext4 defaults,noatime,nofail 0 2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="adding-an-entry-to-etcfstab"&gt;Adding an Entry to /etc/fstab &lt;a class="headline-link" href="#adding-an-entry-to-etcfstab" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before editing &lt;code&gt;/etc/fstab&lt;/code&gt;, always create a backup:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo cp /etc/fstab /etc/fstab.bak&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="step-1-find-the-uuid"&gt;Step 1: Find the UUID &lt;a class="headline-link" href="#step-1-find-the-uuid" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Identify the UUID of the partition you want to mount:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo blkid /dev/sdb1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;/dev/sdb1: UUID=&amp;#34;d4e5f6a7-b8c9-0123-def0-123456789abc&amp;#34; TYPE=&amp;#34;ext4&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="step-2-create-the-mount-point"&gt;Step 2: Create the Mount Point &lt;a class="headline-link" href="#step-2-create-the-mount-point" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Create the directory where the filesystem will be mounted:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mkdir -p /mnt/data&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="step-3-add-the-entry"&gt;Step 3: Add the Entry &lt;a class="headline-link" href="#step-3-add-the-entry" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Open &lt;code&gt;/etc/fstab&lt;/code&gt; in a &lt;a href="https://linuxize.com/post/how-to-use-nano-text-editor/"&gt;text editor&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nano /etc/fstab&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Add a new line at the end of the file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/fstab&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;d4e5f6a7-b8c9-0123-def0-123456789abc /mnt/data ext4 defaults,nofail &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="step-4-reload-and-test-the-entry"&gt;Step 4: Reload and Test the Entry &lt;a class="headline-link" href="#step-4-reload-and-test-the-entry" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;On systemd-based systems, reload the generated mount units after editing &lt;code&gt;/etc/fstab&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl daemon-reload&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Then verify the file syntax and mount relationships:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo findmnt --verify&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Instead of rebooting, use &lt;code&gt;mount -a&lt;/code&gt; to mount fstab entries that are not already mounted and do not use the &lt;code&gt;noauto&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mount -a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If the command produces no output, the entry is correct. If there is an error, fix the fstab entry before rebooting, as an incorrect fstab can prevent the system from booting normally.&lt;/p&gt;
&lt;p&gt;Verify the filesystem is &lt;a href="https://linuxize.com/post/how-to-mount-and-unmount-file-systems-in-linux/"&gt;mounted&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;df -h /mnt/data&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="common-fstab-examples"&gt;Common fstab Examples &lt;a class="headline-link" href="#common-fstab-examples" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="swap-file"&gt;Swap File &lt;a class="headline-link" href="#swap-file" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To add a &lt;a href="https://linuxize.com/post/create-a-linux-swap-file/"&gt;swap file&lt;/a&gt;
to fstab:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/fstab&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/swapfile none swap sw &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="nfs-network-share"&gt;NFS Network Share &lt;a class="headline-link" href="#nfs-network-share" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To mount an &lt;a href="https://linuxize.com/post/how-to-mount-an-nfs-share-in-linux/"&gt;NFS share&lt;/a&gt;
that requires network access:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/fstab&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;192.168.1.10:/export/share /mnt/nfs nfs defaults,_netdev,nofail &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="cifssmb-windows-share"&gt;CIFS/SMB Windows Share &lt;a class="headline-link" href="#cifssmb-windows-share" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To mount a &lt;a href="https://linuxize.com/post/how-to-mount-cifs-windows-share-on-linux/"&gt;Windows/Samba share&lt;/a&gt;
with a credentials file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/fstab&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;//192.168.1.20/share /mnt/smb cifs &lt;span class="nv"&gt;credentials&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/etc/samba/creds,_netdev,nofail &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Set strict permissions on the credentials file so other users cannot read it:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chmod &lt;span class="m"&gt;600&lt;/span&gt; /etc/samba/creds&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="usb-or-external-drive"&gt;USB or External Drive &lt;a class="headline-link" href="#usb-or-external-drive" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To mount a removable drive that may not always be attached:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/fstab&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;e5f6a7b8-c9d0-1234-ef01-23456789abcd /mnt/usb ext4 defaults,nofail,noauto &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;nofail&lt;/code&gt; option prevents boot errors when the drive is not connected. The &lt;code&gt;noauto&lt;/code&gt; option prevents automatic mounting; mount it manually with &lt;code&gt;sudo mount /mnt/usb&lt;/code&gt; when needed.&lt;/p&gt;
&lt;h3 id="tmpfs-for-tmp"&gt;tmpfs for /tmp &lt;a class="headline-link" href="#tmpfs-for-tmp" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To mount &lt;code&gt;/tmp&lt;/code&gt; as a temporary filesystem in memory:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;/etc/fstab&lt;/span&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tmpfs /tmp tmpfs defaults,noatime,size&lt;span class="o"&gt;=&lt;/span&gt;2G &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;View fstab contents&lt;/td&gt;
&lt;td&gt;&lt;code&gt;less /etc/fstab&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Back up fstab&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo cp /etc/fstab /etc/fstab.bak&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Find partition UUIDs&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo blkid&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reload systemd mount units&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo systemctl daemon-reload&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verify fstab syntax&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo findmnt --verify&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mount all fstab entries&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo mount -a&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check mounted filesystems&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mount&lt;/code&gt; or &lt;code&gt;df -h&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check filesystem type&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lsblk -f&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Restore fstab from backup&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo cp /etc/fstab.bak /etc/fstab&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;System does not boot after editing fstab&lt;/strong&gt;&lt;br&gt;
An incorrect fstab entry can cause a boot failure. Boot into recovery mode or a live USB, mount the root filesystem, and fix or restore &lt;code&gt;/etc/fstab&lt;/code&gt; from the backup. Always test with &lt;code&gt;sudo mount -a&lt;/code&gt; before rebooting.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;mount -a&lt;/code&gt; reports &amp;ldquo;wrong fs type&amp;rdquo; or &amp;ldquo;bad superblock&amp;rdquo;&lt;/strong&gt;&lt;br&gt;
The filesystem type in the fstab entry does not match the actual filesystem on the device. Use &lt;code&gt;sudo blkid&lt;/code&gt; or &lt;code&gt;lsblk -f&lt;/code&gt; to check the correct type.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Network share fails to mount at boot&lt;/strong&gt;&lt;br&gt;
Add the &lt;code&gt;_netdev&lt;/code&gt; option to tell the system to wait for network availability before mounting. For systemd-based systems, &lt;code&gt;x-systemd.automount&lt;/code&gt; can also help with timing issues.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;mount point does not exist&amp;rdquo;&lt;/strong&gt;&lt;br&gt;
The directory specified in the second field does not exist. Create it with &lt;code&gt;mkdir -p /path/to/mountpoint&lt;/code&gt; before running &lt;code&gt;mount -a&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UUID changed after reformatting a partition&lt;/strong&gt;&lt;br&gt;
Reformatting a partition assigns a new UUID. Run &lt;code&gt;sudo blkid&lt;/code&gt; to find the new UUID and update the fstab entry accordingly.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What happens if I make an error in /etc/fstab?&lt;/strong&gt;&lt;br&gt;
If the entry references a non-existent device without the &lt;code&gt;nofail&lt;/code&gt; option, the system may drop to an emergency shell during boot. Always use &lt;code&gt;nofail&lt;/code&gt; for non-essential filesystems and test with &lt;code&gt;sudo mount -a&lt;/code&gt; before rebooting.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Should I use UUID or device path (/dev/sda1)?&lt;/strong&gt;&lt;br&gt;
Use UUID. Device paths can change if you add or remove disks, or if the boot order changes. UUIDs are unique to each filesystem and do not change unless you reformat the partition.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What does the &lt;code&gt;nofail&lt;/code&gt; option do?&lt;/strong&gt;&lt;br&gt;
It tells the system to continue booting even if the device is not present or cannot be mounted. Without &lt;code&gt;nofail&lt;/code&gt;, a missing device causes the system to drop to an emergency shell.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I remove an fstab entry?&lt;/strong&gt;&lt;br&gt;
Open &lt;code&gt;/etc/fstab&lt;/code&gt; with &lt;code&gt;sudo nano /etc/fstab&lt;/code&gt;, delete or comment out the line (add &lt;code&gt;#&lt;/code&gt; at the beginning), save the file, and then unmount the filesystem with &lt;code&gt;sudo umount /mount/point&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;noauto&lt;/code&gt; and &lt;code&gt;nofail&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;noauto&lt;/code&gt; prevents the filesystem from being mounted automatically at boot; you must mount it manually. &lt;code&gt;nofail&lt;/code&gt; still mounts automatically but does not cause a boot error if the device is missing.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;/etc/fstab&lt;/code&gt; file controls how filesystems are mounted at boot. Each entry specifies the device, mount point, filesystem type, options, and check order. Always back up fstab before editing, use UUIDs instead of device paths, and test changes with &lt;code&gt;sudo mount -a&lt;/code&gt; before rebooting.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/etc-fstab-file/featured_hu_ef49871765b3c4f8.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>traceroute Command in Linux</title><link>https://linuxize.com/post/traceroute-command-in-linux/</link><pubDate>Sat, 07 Feb 2026 16:00:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/traceroute-command-in-linux/</guid><category>linux commands</category><description>Trace the path packets take to a host with the traceroute command. Examples for ICMP (-I), TCP (-T), max hops (-m), and no-DNS (-n) modes.</description><content:encoded>&lt;p&gt;The &lt;code&gt;traceroute&lt;/code&gt; command is a network diagnostic tool that displays the path packets take from your system to a destination host. It shows each hop (router) along the route and the time it takes for packets to reach each one.&lt;/p&gt;
&lt;p&gt;Network administrators use &lt;code&gt;traceroute&lt;/code&gt; to identify where packets are being delayed or dropped, making it essential for troubleshooting connectivity issues, latency problems, and routing failures.&lt;/p&gt;
&lt;p&gt;This guide covers how to use the &lt;code&gt;traceroute&lt;/code&gt; command with practical examples and explanations of the most common options.&lt;/p&gt;
&lt;h2 id="syntax"&gt;Syntax &lt;a class="headline-link" href="#syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The general syntax for the &lt;code&gt;traceroute&lt;/code&gt; command is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;traceroute [OPTIONS] DESTINATION&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;OPTIONS&lt;/code&gt; - Flags that modify the behavior of the command.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DESTINATION&lt;/code&gt; - The target hostname or IP address to trace.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="installing-traceroute"&gt;Installing traceroute &lt;a class="headline-link" href="#installing-traceroute" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;traceroute&lt;/code&gt; command is not installed by default on all Linux distributions. To check if it is available on your system, type:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;traceroute --version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If &lt;code&gt;traceroute&lt;/code&gt; is not present, the command will print &amp;ldquo;traceroute: command not found&amp;rdquo;. You can install it using your distribution&amp;rsquo;s package manager.&lt;/p&gt;
&lt;h3 id="install-traceroute-on-ubuntu-debian-and-derivatives"&gt;Install traceroute on Ubuntu, Debian, and Derivatives &lt;a class="headline-link" href="#install-traceroute-on-ubuntu-debian-and-derivatives" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo apt install traceroute&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="install-traceroute-on-fedora-rhel-and-derivatives"&gt;Install traceroute on Fedora, RHEL, and Derivatives &lt;a class="headline-link" href="#install-traceroute-on-fedora-rhel-and-derivatives" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install traceroute&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="install-traceroute-on-arch-linux"&gt;Install traceroute on Arch Linux &lt;a class="headline-link" href="#install-traceroute-on-arch-linux" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo pacman -S traceroute&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="how-traceroute-works"&gt;How traceroute works &lt;a class="headline-link" href="#how-traceroute-works" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When you run &lt;code&gt;traceroute&lt;/code&gt;, it sends packets with incrementally increasing TTL (Time to Live) values, starting at 1. Each router along the path decrements the TTL by 1. When the TTL reaches 0, the router discards the packet and sends back an ICMP &amp;ldquo;Time Exceeded&amp;rdquo; message.&lt;/p&gt;
&lt;p&gt;By increasing the TTL with each round of packets, &lt;code&gt;traceroute&lt;/code&gt; discovers each hop along the route until the packets reach the final destination.&lt;/p&gt;
&lt;p&gt;By default, &lt;code&gt;traceroute&lt;/code&gt; sends three UDP packets per hop (on Linux) and displays the round-trip time for each packet.&lt;/p&gt;
&lt;h2 id="basic-usage"&gt;Basic Usage &lt;a class="headline-link" href="#basic-usage" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To trace the route to a destination, run &lt;code&gt;traceroute&lt;/code&gt; followed by the hostname or IP address:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;traceroute google.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output should look something like this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;traceroute to google.com (142.250.185.78), 30 hops max, 60 byte packets
1 router.local (192.168.1.1) 1.234 ms 1.102 ms 1.056 ms
2 10.0.0.1 (10.0.0.1) 12.345 ms 12.234 ms 12.123 ms
3 isp-gateway.example.net (203.0.113.1) 15.678 ms 15.567 ms 15.456 ms
4 core-router.example.net (198.51.100.1) 20.123 ms 20.012 ms 19.901 ms
5 google-peer.example.net (192.0.2.1) 22.345 ms 22.234 ms 22.123 ms
6 142.250.185.78 (142.250.185.78) 25.678 ms 25.567 ms 25.456 ms&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="understanding-the-output"&gt;Understanding the Output &lt;a class="headline-link" href="#understanding-the-output" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Each line in the &lt;code&gt;traceroute&lt;/code&gt; output represents a hop along the route. Let us break down what each field means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hop number&lt;/strong&gt; - The sequential number of the router in the path (1, 2, 3, etc.).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hostname&lt;/strong&gt; - The DNS name of the router, if available.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IP address&lt;/strong&gt; - The IP address of the router in parentheses.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Round-trip times&lt;/strong&gt; - Three time measurements in milliseconds, one for each probe packet sent to that hop.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first line shows the destination, maximum number of hops (default 30), and packet size (default 60 bytes).&lt;/p&gt;
&lt;h3 id="interpreting-the-results"&gt;Interpreting the Results &lt;a class="headline-link" href="#interpreting-the-results" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Asterisks (&lt;code&gt;* * *&lt;/code&gt;)&lt;/strong&gt; indicate that no response was received for that hop. This can happen when:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The router is configured to not respond to traceroute probes.&lt;/li&gt;
&lt;li&gt;A firewall is blocking the packets.&lt;/li&gt;
&lt;li&gt;The packets were lost due to network congestion.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Increasing latency&lt;/strong&gt; at a specific hop suggests a bottleneck or congested link at that point in the network.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Consistent high latency&lt;/strong&gt; from a certain hop onward indicates the issue is at or before that router.&lt;/p&gt;
&lt;h2 id="common-options"&gt;Common Options &lt;a class="headline-link" href="#common-options" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;traceroute&lt;/code&gt; command accepts several options to customize its behavior:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-n&lt;/code&gt; - Do not resolve IP addresses to hostnames. This speeds up the output by skipping DNS lookups.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-m max_ttl&lt;/code&gt; - Set the maximum number of hops (default is 30).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-q nqueries&lt;/code&gt; - Set the number of probe packets per hop (default is 3).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-w waittime&lt;/code&gt; - Set the time in seconds to wait for a response (default is 5).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-I&lt;/code&gt; - Use ICMP ECHO packets instead of UDP (may require root privileges).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-T&lt;/code&gt; - Use TCP SYN packets instead of UDP (may require root privileges).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-p port&lt;/code&gt; - Set the destination port for UDP or TCP probes.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-s source_addr&lt;/code&gt; - Use the specified source IP address.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-i interface&lt;/code&gt; - Send packets through the specified network interface.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="skip-dns-resolution"&gt;Skip DNS Resolution &lt;a class="headline-link" href="#skip-dns-resolution" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To speed up the trace and display only IP addresses, use the &lt;code&gt;-n&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;traceroute -n google.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The output shows numeric IP addresses without hostnames:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;traceroute to google.com (142.250.185.78), 30 hops max, 60 byte packets
1 192.168.1.1 1.234 ms 1.102 ms 1.056 ms
2 10.0.0.1 12.345 ms 12.234 ms 12.123 ms
3 203.0.113.1 15.678 ms 15.567 ms 15.456 ms&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is useful when DNS resolution is slow or when you only need IP addresses.&lt;/p&gt;
&lt;h2 id="change-maximum-hops"&gt;Change Maximum Hops &lt;a class="headline-link" href="#change-maximum-hops" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, &lt;code&gt;traceroute&lt;/code&gt; stops after 30 hops. To change this limit, use the &lt;code&gt;-m&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;traceroute -m &lt;span class="m"&gt;15&lt;/span&gt; google.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This limits the trace to 15 hops maximum.&lt;/p&gt;
&lt;h2 id="change-number-of-probes"&gt;Change Number of Probes &lt;a class="headline-link" href="#change-number-of-probes" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To send a different number of probe packets per hop, use the &lt;code&gt;-q&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;traceroute -q &lt;span class="m"&gt;1&lt;/span&gt; google.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This sends only one probe per hop, resulting in faster but less detailed output.&lt;/p&gt;
&lt;h2 id="use-icmp-instead-of-udp"&gt;Use ICMP Instead of UDP &lt;a class="headline-link" href="#use-icmp-instead-of-udp" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, Linux &lt;code&gt;traceroute&lt;/code&gt; uses UDP packets. Some networks block UDP, so you can use ICMP ECHO packets instead:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo traceroute -I google.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="note callout callout-info"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" &gt;
&lt;path d="M 16 3 C 8.832031 3 3 8.832031 3 16 C 3 23.167969 8.832031 29 16 29 C 23.167969 29 29 23.167969 29 16 C 29 8.832031 23.167969 3 16 3 Z M 16 5 C 22.085938 5 27 9.914063 27 16 C 27 22.085938 22.085938 27 16 27 C 9.914063 27 5 22.085938 5 16 C 5 9.914063 9.914063 5 16 5 Z M 15 10 L 15 12 L 17 12 L 17 10 Z M 15 14 L 15 22 L 17 22 L 17 14 Z "&gt;&lt;/path&gt;
&lt;/svg&gt;&lt;span class="callout-title"&gt;Info&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;The &lt;code&gt;-I&lt;/code&gt; option may require root privileges, depending on your kernel and system configuration.&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="use-tcp-instead-of-udp"&gt;Use TCP Instead of UDP &lt;a class="headline-link" href="#use-tcp-instead-of-udp" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For networks that block both UDP and ICMP, you can use TCP SYN packets:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo traceroute -T google.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can also specify a port, such as port 443 for HTTPS:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo traceroute -T -p &lt;span class="m"&gt;443&lt;/span&gt; google.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is useful for tracing routes through firewalls that only allow specific TCP ports.&lt;/p&gt;
&lt;h2 id="trace-ipv6-routes"&gt;Trace IPv6 Routes &lt;a class="headline-link" href="#trace-ipv6-routes" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To trace IPv6 routes, use the &lt;code&gt;-6&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;traceroute -6 ipv6.google.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="specify-source-interface"&gt;Specify Source Interface &lt;a class="headline-link" href="#specify-source-interface" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If your system has multiple network interfaces, you can specify which one to use:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;traceroute -i eth0 google.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Or specify the source IP address:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;traceroute -s 192.168.1.100 google.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="traceroute-vs-tracepath"&gt;Traceroute vs tracepath &lt;a class="headline-link" href="#traceroute-vs-tracepath" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Linux systems often include &lt;code&gt;tracepath&lt;/code&gt;, which is similar to &lt;code&gt;traceroute&lt;/code&gt; but does not require root privileges and automatically discovers the MTU (Maximum Transmission Unit) along the path.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;traceroute&lt;/th&gt;
&lt;th&gt;tracepath&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Root required&lt;/td&gt;
&lt;td&gt;Yes (for ICMP/TCP)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Protocol&lt;/td&gt;
&lt;td&gt;UDP, ICMP, TCP&lt;/td&gt;
&lt;td&gt;UDP only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MTU discovery&lt;/td&gt;
&lt;td&gt;Manual or &lt;code&gt;--mtu&lt;/code&gt; option&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Customization&lt;/td&gt;
&lt;td&gt;Many options&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Use &lt;code&gt;tracepath&lt;/code&gt; for quick traces without root access:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tracepath google.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Use &lt;code&gt;traceroute&lt;/code&gt; when you need more control over the probe method or when &lt;code&gt;tracepath&lt;/code&gt; does not provide enough information.&lt;/p&gt;
&lt;h2 id="practical-examples"&gt;Practical Examples &lt;a class="headline-link" href="#practical-examples" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="diagnose-slow-connections"&gt;Diagnose Slow Connections &lt;a class="headline-link" href="#diagnose-slow-connections" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If a website is loading slowly, trace the route to identify where the delay occurs:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;traceroute -n example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Look for hops with significantly higher latency than the previous ones. The hop before the latency spike is often the source of the problem.&lt;/p&gt;
&lt;h3 id="check-if-a-host-is-reachable"&gt;Check if a Host is Reachable &lt;a class="headline-link" href="#check-if-a-host-is-reachable" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If &lt;a href="https://linuxize.com/post/linux-ping-command/"&gt;&lt;code&gt;ping&lt;/code&gt;&lt;/a&gt;
shows packet loss, use &lt;code&gt;traceroute&lt;/code&gt; to find where packets are being dropped:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;traceroute google.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Hops showing &lt;code&gt;* * *&lt;/code&gt; followed by successful hops indicate a router that does not respond to probes but forwards traffic. If all remaining hops show &lt;code&gt;* * *&lt;/code&gt;, the issue is at or after the last responding hop.&lt;/p&gt;
&lt;h3 id="trace-through-a-firewall"&gt;Trace Through a Firewall &lt;a class="headline-link" href="#trace-through-a-firewall" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If standard UDP probes are blocked, try ICMP or TCP:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo traceroute -I google.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo traceroute -T -p &lt;span class="m"&gt;80&lt;/span&gt; google.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="compare-routes-to-different-servers"&gt;Compare Routes to Different Servers &lt;a class="headline-link" href="#compare-routes-to-different-servers" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To understand routing differences, trace routes to multiple servers:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;traceroute -n server1.example.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;traceroute -n server2.example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This helps identify whether traffic to different destinations takes different paths through your network.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Basic trace&lt;/td&gt;
&lt;td&gt;&lt;code&gt;traceroute example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skip DNS resolution&lt;/td&gt;
&lt;td&gt;&lt;code&gt;traceroute -n example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Limit to N hops&lt;/td&gt;
&lt;td&gt;&lt;code&gt;traceroute -m 15 example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;One probe per hop&lt;/td&gt;
&lt;td&gt;&lt;code&gt;traceroute -q 1 example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use ICMP&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo traceroute -I example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use TCP&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo traceroute -T example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use TCP on port 443&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo traceroute -T -p 443 example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Specify interface&lt;/td&gt;
&lt;td&gt;&lt;code&gt;traceroute -i eth0 example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Set timeout&lt;/td&gt;
&lt;td&gt;&lt;code&gt;traceroute -w 3 example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trace with tracepath&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tracepath example.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;All hops show &lt;code&gt;* * *&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The destination or your network may be blocking traceroute probes. Try using ICMP (&lt;code&gt;-I&lt;/code&gt;) or TCP (&lt;code&gt;-T&lt;/code&gt;) instead of the default UDP. If the issue persists, a firewall between you and the destination is likely blocking all probe types.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Only the first hop responds&lt;/strong&gt;&lt;br&gt;
Your local router responds, but nothing beyond it does. This often indicates a firewall or routing issue at your ISP. Contact your network administrator or ISP for assistance.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Trace never completes&lt;/strong&gt;&lt;br&gt;
The destination may not be reachable, or the maximum hop count is too low. Increase the maximum hops with &lt;code&gt;-m 60&lt;/code&gt; and check if the trace progresses further.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;High latency at a specific hop&lt;/strong&gt;&lt;br&gt;
A single hop with high latency does not always indicate a problem. Routers often deprioritize ICMP responses. If the final destination has acceptable latency, the intermediate high latency may not affect actual traffic.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Latency increases then decreases&lt;/strong&gt;&lt;br&gt;
This can occur due to asymmetric routing, where the return path differs from the outbound path. The times displayed include the round trip, so a longer return path can inflate the displayed latency.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Permission denied&lt;/strong&gt;&lt;br&gt;
Options like &lt;code&gt;-I&lt;/code&gt; (ICMP) and &lt;code&gt;-T&lt;/code&gt; (TCP) may require root privileges. Run the command with &lt;code&gt;sudo&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between traceroute and ping?&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://linuxize.com/post/linux-ping-command/"&gt;&lt;code&gt;ping&lt;/code&gt;&lt;/a&gt;
tests whether a destination is reachable and measures round-trip latency. &lt;code&gt;traceroute&lt;/code&gt; shows the path packets take and the latency at each hop along the route. Use &lt;code&gt;ping&lt;/code&gt; for basic connectivity checks and &lt;code&gt;traceroute&lt;/code&gt; for diagnosing where problems occur.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why do some hops show asterisks?&lt;/strong&gt;&lt;br&gt;
Asterisks (&lt;code&gt;* * *&lt;/code&gt;) mean no response was received. The router may be configured to ignore traceroute probes, a firewall may be blocking them, or the packets may have been lost. This does not necessarily mean the router is down.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the default protocol used by traceroute?&lt;/strong&gt;&lt;br&gt;
On Linux, &lt;code&gt;traceroute&lt;/code&gt; uses UDP by default. On Windows, &lt;code&gt;tracert&lt;/code&gt; uses ICMP. You can switch Linux &lt;code&gt;traceroute&lt;/code&gt; to ICMP with &lt;code&gt;-I&lt;/code&gt; or TCP with &lt;code&gt;-T&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I trace the route on Windows?&lt;/strong&gt;&lt;br&gt;
Windows uses the &lt;code&gt;tracert&lt;/code&gt; command instead of &lt;code&gt;traceroute&lt;/code&gt;. The syntax is similar: &lt;code&gt;tracert example.com&lt;/code&gt;. It uses ICMP by default.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What does TTL mean in traceroute?&lt;/strong&gt;&lt;br&gt;
TTL (Time to Live) is a field in the IP packet header that limits the packet&amp;rsquo;s lifespan. Each router decrements the TTL by 1. When it reaches 0, the router discards the packet and sends an ICMP &amp;ldquo;Time Exceeded&amp;rdquo; message. Traceroute uses this mechanism to discover each hop.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How can I trace the route to a specific port?&lt;/strong&gt;&lt;br&gt;
Use the &lt;code&gt;-p&lt;/code&gt; option with TCP (&lt;code&gt;-T&lt;/code&gt;) or UDP to specify the destination port:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo traceroute -T -p &lt;span class="m"&gt;443&lt;/span&gt; example.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Is there an alternative to traceroute for continuous diagnostics?&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://linux.die.net/man/8/mtr" target="_blank" rel="noopener noreferrer"&gt;&lt;code&gt;mtr&lt;/code&gt;&lt;/a&gt;
combines &lt;code&gt;ping&lt;/code&gt; and &lt;code&gt;traceroute&lt;/code&gt; in a single, continuously updating view and is useful for ongoing packet loss and latency checks.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If UDP probes are blocked on your network, fall back to &lt;code&gt;sudo traceroute -I&lt;/code&gt; (ICMP) or &lt;code&gt;sudo traceroute -T -p 443&lt;/code&gt; (TCP on HTTPS). The TCP form is most likely to pass through stateful firewalls.&lt;/p&gt;
&lt;p&gt;For more options, refer to the &lt;a href="https://linux.die.net/man/8/traceroute" target="_blank" rel="noopener noreferrer"&gt;traceroute man page&lt;/a&gt;
by running &lt;code&gt;man traceroute&lt;/code&gt; in your terminal.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/traceroute-command-in-linux/featured_hu_98a5e1101391566b.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>Linux Users and Permissions</title><link>https://linuxize.com/series/linux-users-and-permissions/</link><pubDate>Tue, 03 Feb 2026 12:00:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/series/linux-users-and-permissions/</guid><category>linux commands</category><category>security</category><description>Learn how to manage Linux users, groups, and file permissions. This series covers useradd, chmod, chown, sudo, and other essential commands for controlling access on Linux systems.</description><content:encoded>&lt;p&gt;Linux access control starts with users, groups, and permissions. This series covers the essential commands and files that control who can log in, what they can do, and which files they can access.&lt;/p&gt;
&lt;p&gt;Each article includes clear examples you can run on any Linux system. The series is organized into five modules:&lt;/p&gt;
&lt;h2 id="what-you-will-learn"&gt;What You Will Learn &lt;a class="headline-link" href="#what-you-will-learn" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Getting Started&lt;/strong&gt; - Listing users, creating accounts, and managing passwords&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Groups&lt;/strong&gt; - Creating groups, assigning users to them, and removing groups&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Privileges&lt;/strong&gt; - su, sudo, and safe privilege escalation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Permissions &amp;amp; Ownership&lt;/strong&gt; - chmod, chown, and permission basics&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;System Files &amp;amp; Defaults&lt;/strong&gt; - /etc/passwd and umask behavior&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites &lt;a class="headline-link" href="#prerequisites" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Basic familiarity with the Linux command line&lt;/li&gt;
&lt;li&gt;Access to a Linux system (or WSL on Windows)&lt;/li&gt;
&lt;/ul&gt;</content:encoded><media:content url="https://linuxize.com/series/linux-users-and-permissions/featured_hu_20a1d576d48abb6d.webp" medium="image" type="image/webp" width="1200" height="636"/></item><item><title>SSH Essentials</title><link>https://linuxize.com/series/ssh-essentials/</link><pubDate>Fri, 30 Jan 2026 18:00:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/series/ssh-essentials/</guid><category>ssh</category><category>linux commands</category><category>security</category><description>Learn how to use SSH to securely connect to remote servers, transfer files, set up key-based authentication, and create encrypted tunnels.</description><content:encoded>&lt;p&gt;SSH (Secure Shell) is a cryptographic network protocol used for secure communication between a client and a remote server. It is the standard way to log into remote Linux machines, transfer files, and create encrypted tunnels.&lt;/p&gt;
&lt;p&gt;This series covers everything you need to work with SSH, from basic connections to advanced techniques like tunneling and chroot jails.&lt;/p&gt;
&lt;p&gt;You can also use the &lt;a href="https://linuxize.com/cheatsheet/ssh/"&gt;SSH cheatsheet&lt;/a&gt;
as a quick reference while reading the series.&lt;/p&gt;
&lt;h2 id="what-youll-learn"&gt;What You&amp;rsquo;ll Learn &lt;a class="headline-link" href="#what-youll-learn" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Getting Started&lt;/strong&gt; — The SSH command, enabling SSH on different systems, configuring the client, and changing the default port&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Key-Based Authentication&lt;/strong&gt; — Generating SSH keys on Linux and Windows, setting up keys on various distributions, and configuring passwordless login&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tunneling &amp;amp; Port Forwarding&lt;/strong&gt; — Local and remote port forwarding, dynamic tunneling, and SOCKS proxies for private browsing&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;File Transfer&lt;/strong&gt; — Copying files with SCP and SFTP, changing the SFTP port, setting up chroot jails, mounting remote directories with SSHFS, and using Rsync over SSH&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites &lt;a class="headline-link" href="#prerequisites" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Access to a Linux, macOS, or Windows terminal&lt;/li&gt;
&lt;li&gt;A remote server or virtual machine to connect to&lt;/li&gt;
&lt;li&gt;Basic familiarity with the Linux command line&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each article includes step-by-step instructions and practical examples. By the end of this series, you will be able to securely manage remote servers, automate authentication with SSH keys, and transfer files over encrypted connections.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/series/ssh-essentials/featured_hu_24356a4e40528646.webp" medium="image" type="image/webp" width="1200" height="636"/></item><item><title>Bash Scripting Fundamentals</title><link>https://linuxize.com/series/bash-scripting-fundamentals/</link><pubDate>Wed, 14 Jan 2026 12:31:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/series/bash-scripting-fundamentals/</guid><category>bash</category><category>linux commands</category><category>scripting</category><description>Learn Bash scripting from the ground up. This series covers everything from basic syntax to advanced techniques for writing powerful shell scripts.</description><content:encoded>&lt;p&gt;Bash is the default shell on most Linux distributions and macOS. Learning to write Bash scripts is an essential skill for anyone working with Linux systems, whether you’re a system administrator, developer, or DevOps engineer.&lt;/p&gt;
&lt;p&gt;This series will guide you from the basics of Bash scripting to more advanced skills. You&amp;rsquo;ll learn how to automate tasks, process text, handle user input, and write maintainable scripts.&lt;/p&gt;
&lt;p&gt;You can also use the &lt;a href="https://linuxize.com/cheatsheet/bash/"&gt;Bash cheatsheet&lt;/a&gt;
as a quick reference while reading the series.&lt;/p&gt;
&lt;h2 id="what-youll-learn"&gt;What You&amp;rsquo;ll Learn &lt;a class="headline-link" href="#what-youll-learn" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Getting Started&lt;/strong&gt; - Shebang, running scripts, comments, and shell configuration&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Variables &amp;amp; Data&lt;/strong&gt; - Working with strings, numbers, arrays, and environment variables&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Input/Output&lt;/strong&gt; - Reading input, writing files, and handling redirections&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Control Flow&lt;/strong&gt; - Conditionals, comparisons, and pattern matching&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Loops&lt;/strong&gt; - For, while, until loops and controlling loop execution&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Functions &amp;amp; Advanced&lt;/strong&gt; - Reusable code, exit codes, background processes, and productivity tips&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites &lt;a class="headline-link" href="#prerequisites" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Basic familiarity with the Linux command line&lt;/li&gt;
&lt;li&gt;Access to a Linux or macOS terminal (or WSL on Windows)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each article includes practical examples you can run on your own system. By the end of this series, you&amp;rsquo;ll be able to write scripts that automate your daily tasks and solve real-world problems.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/series/bash-scripting-fundamentals/featured_hu_714831af26f2cfae.webp" medium="image" type="image/webp" width="1200" height="636"/></item><item><title>How to Use the Export Command in Linux</title><link>https://linuxize.com/post/export-command-in-linux/</link><pubDate>Fri, 09 Jan 2026 16:10:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/export-command-in-linux/</guid><category>bash</category><category>linux commands</category><description>The export command in Bash marks variables to be inherited by child processes. This guide explains what export does, how to use it, and when to make variables persistent.</description><content:encoded>&lt;p&gt;The &lt;code&gt;export&lt;/code&gt; command is an essential part of the Bash shell in Linux. It allows you to share variables or functions you create so that they can be used by other programs or new shells started from your current terminal.&lt;/p&gt;
&lt;p&gt;By default, variables exist only in the shell where they are created. When you use export, the variable becomes an environment variable, meaning it is passed to child processes.&lt;/p&gt;
&lt;p&gt;In this article, we will show you how to use the &lt;code&gt;export&lt;/code&gt; command to create, list, and manage environment variables and functions.&lt;/p&gt;
&lt;h2 id="what-is-an-environment-variable"&gt;What Is an Environment Variable? &lt;a class="headline-link" href="#what-is-an-environment-variable" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Environment variables are system-wide variables that are inherited by all spawned child processes and shells.&lt;/p&gt;
&lt;p&gt;Environment variables allow you to customize how the system works and the behavior of the applications on the system. For example, environment variables can store information about the default text editor or browser, the paths to executable files, or the system locale and keyboard layout settings.&lt;/p&gt;
&lt;p&gt;Common examples include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;PATH&lt;/code&gt; – Defines where the shell looks for executable files.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HOME&lt;/code&gt; – Your home directory.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;USER&lt;/code&gt; – Your username.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LANG&lt;/code&gt; - The current locales settings.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SHELL&lt;/code&gt; - The path of the current user’s shell, such as bash or zsh.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="syntax-overview"&gt;Syntax Overview &lt;a class="headline-link" href="#syntax-overview" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The syntax of the export command is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;export [-f] [-n] [name[=value] …]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Or to list exported variables:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;export -p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;name&lt;/code&gt; - the shell variable or function to export.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-p&lt;/code&gt; - lists all exported variables in the current shell.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-n&lt;/code&gt; - removes the export property from the specified variable(s) (they remain defined in the current shell but won’t be inherited by child processes).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-f&lt;/code&gt; - treats the specified name(s) as functions instead of variables.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To see why &lt;code&gt;export&lt;/code&gt; matters, compare a regular shell variable with an exported one:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;linuxize&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bash -c &lt;span class="s1"&gt;&amp;#39;echo &amp;#34;$NAME&amp;#34;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;linuxize&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bash -c &lt;span class="s1"&gt;&amp;#39;echo &amp;#34;$NAME&amp;#34;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The first command does not pass &lt;code&gt;NAME&lt;/code&gt; to the child shell. After &lt;code&gt;export&lt;/code&gt;, the child shell can read it.&lt;/p&gt;
&lt;h2 id="list-all-exported-variables"&gt;List All Exported Variables &lt;a class="headline-link" href="#list-all-exported-variables" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To see all exported variables in your current shell, type:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; -p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Example output:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;declare -x PATH=&amp;#34;/usr/local/bin:/usr/bin:/bin&amp;#34;
declare -x HOME=&amp;#34;/home/user&amp;#34;
declare -x LANG=&amp;#34;en_US.UTF-8&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These are variables that any child process will inherit.&lt;/p&gt;
&lt;p&gt;You can also use &lt;code&gt;printenv&lt;/code&gt; or &lt;code&gt;env&lt;/code&gt; to see all currently active environment variables.&lt;/p&gt;
&lt;h2 id="creating-and-exporting-environment-variables"&gt;Creating and Exporting Environment Variables &lt;a class="headline-link" href="#creating-and-exporting-environment-variables" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To create a new &lt;a href="https://linuxize.com/post/how-to-set-and-list-environment-variables-in-linux/"&gt;environment variable&lt;/a&gt;
, use the following form:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;VARIABLE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;VALUE&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Variable names are case-sensitive. By convention, environment variables should have UPPER CASE names.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;COUNT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2024&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Check its value:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$COUNT&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;2024&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Variables defined without &lt;code&gt;export&lt;/code&gt; are local to the current shell and won’t be inherited by child processes.&lt;/p&gt;
&lt;p&gt;You can also first define a variable and export it separately:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;COUNT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;2024&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; COUNT&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="exporting-functions"&gt;Exporting Functions &lt;a class="headline-link" href="#exporting-functions" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Functions can be exported to child shells using the &lt;code&gt;-f&lt;/code&gt; option. Example:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;greet&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Hello World!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; -f greet&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="note callout callout-info"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" &gt;
&lt;path d="M 16 3 C 8.832031 3 3 8.832031 3 16 C 3 23.167969 8.832031 29 16 29 C 23.167969 29 29 23.167969 29 16 C 29 8.832031 23.167969 3 16 3 Z M 16 5 C 22.085938 5 27 9.914063 27 16 C 27 22.085938 22.085938 27 16 27 C 9.914063 27 5 22.085938 5 16 C 5 9.914063 9.914063 5 16 5 Z M 15 10 L 15 12 L 17 12 L 17 10 Z M 15 14 L 15 22 L 17 22 L 17 14 Z "&gt;&lt;/path&gt;
&lt;/svg&gt;&lt;span class="callout-title"&gt;Info&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;Without &lt;code&gt;-f&lt;/code&gt;, export assumes you’re exporting a variable, not a function.&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This works in Bash. Function export is not portable across all shells.&lt;/p&gt;
&lt;p&gt;Then, start a new child shell by typing &lt;code&gt;bash&lt;/code&gt;, and enter the function name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;greet&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Hello World!&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you haven’t exported the function, it will not be available in the child shell, and there will be no output.&lt;/p&gt;
&lt;h2 id="remove-export-property"&gt;Remove Export Property &lt;a class="headline-link" href="#remove-export-property" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To stop exporting a variable while retaining it in the current shell:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; -n VARIABLE&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To remove a variable completely from both current and child processes:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;unset&lt;/span&gt; VARIABLE&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="make-environment-variables-permanent"&gt;Make Environment Variables Permanent &lt;a class="headline-link" href="#make-environment-variables-permanent" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Exported variables are not permanent and last only for the current session.&lt;/p&gt;
&lt;p&gt;To make environment variables persistent across sessions, add &lt;code&gt;export VARIABLE=value&lt;/code&gt; to your shell configuration file. Common places include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/etc/profile&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/.bashrc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/.bash_profile&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/etc/environment&lt;/code&gt; (typically uses plain &lt;code&gt;VARIABLE=value&lt;/code&gt;, not &lt;code&gt;export VARIABLE=value&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;JAVA_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/path/to/java/home&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;:&lt;span class="nv"&gt;$JAVA_HOME&lt;/span&gt;/bin&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;export&lt;/code&gt; command is important for managing environment variables and functions in Linux.&lt;/p&gt;
&lt;p&gt;Important aspects to remember:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Child processes inherit exported variables/functions.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;export -f&lt;/code&gt; for functions.&lt;/li&gt;
&lt;li&gt;Remove exports with &lt;code&gt;export -n&lt;/code&gt; or completely delete with &lt;code&gt;unset&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Persistent exports require adding them to the shell configuration files.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mastering &lt;code&gt;export&lt;/code&gt; will make your shell scripts and session management much more powerful.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/export-command-in-linux/featured_hu_7adaac1fcc59aff1.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>ifconfig Command in Linux: Configure Network Interfaces</title><link>https://linuxize.com/post/ifconfig-command/</link><pubDate>Mon, 28 Jun 2021 20:31:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/ifconfig-command/</guid><category>linux commands</category><description>Configure and view network interfaces in Linux using ifconfig. Covers IP assignment, enabling and disabling interfaces, MTU, MAC address changes, and modern ip command equivalents.</description><content:encoded>&lt;p&gt;&lt;code&gt;ifconfig&lt;/code&gt; (interface configuration) is a network management tool used to configure and view the status of network interfaces in Linux. With &lt;code&gt;ifconfig&lt;/code&gt;, you can assign IP addresses, enable or disable interfaces, change MTU values, modify MAC addresses, and more.&lt;/p&gt;
&lt;div class="note callout callout-warning"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"&gt;
&lt;path d="M10 20C4.477 20 0 15.523 0 10S4.477 0 10 0s10 4.477 10 10-4.477 10-10 10zm0-2c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm-.5-5h1c.276 0 .5.224.5.5v1c0 .276-.224.5-.5.5h-1c-.276 0-.5-.224-.5-.5v-1c0-.276.224-.5.5-.5zm0-8h1c.276 0 .5.224.5.5V8l-.5 3-1 .5L9 8V5.5c0-.276.224-.5.5-.5z"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;span class="callout-title"&gt;Warning&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;&lt;code&gt;ifconfig&lt;/code&gt; is deprecated and replaced by the &lt;a href="https://linuxize.com/post/linux-ip-command/" target="_blank" rel="noopener noreferrer"&gt;&lt;code&gt;ip&lt;/code&gt;&lt;/a&gt;
command. It may not be installed on modern Linux distributions. Where possible, use &lt;code&gt;ip&lt;/code&gt; for new scripts and workflows.&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This guide explains how to use the &lt;code&gt;ifconfig&lt;/code&gt; command with practical examples.&lt;/p&gt;
&lt;h2 id="how-to-install-ifconfig"&gt;How to Install &lt;code&gt;ifconfig&lt;/code&gt; &lt;a class="headline-link" href="#how-to-install-ifconfig" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;ifconfig&lt;/code&gt; is part of the &lt;code&gt;net-tools&lt;/code&gt; package, which is not installed by default on many modern distributions.&lt;/p&gt;
&lt;p&gt;If you get an error saying &lt;code&gt;ifconfig: command not found&lt;/code&gt;, install the package using the instructions below.&lt;/p&gt;
&lt;h3 id="install-ifconfig-on-ubuntu-debian-and-derivatives"&gt;Install &lt;code&gt;ifconfig&lt;/code&gt; on Ubuntu, Debian, and Derivatives &lt;a class="headline-link" href="#install-ifconfig-on-ubuntu-debian-and-derivatives" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install net-tools&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="install-ifconfig-on-fedora-rhel-and-derivatives"&gt;Install &lt;code&gt;ifconfig&lt;/code&gt; on Fedora, RHEL, and Derivatives &lt;a class="headline-link" href="#install-ifconfig-on-fedora-rhel-and-derivatives" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install net-tools&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="ifconfig-command-syntax"&gt;&lt;code&gt;ifconfig&lt;/code&gt; Command Syntax &lt;a class="headline-link" href="#ifconfig-command-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The general syntax for &lt;code&gt;ifconfig&lt;/code&gt; is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ifconfig [INTERFACE] [OPTIONS] [ADDRESS]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;INTERFACE&lt;/code&gt; - the name of the network interface (for example, &lt;code&gt;eth0&lt;/code&gt;, &lt;code&gt;ens3&lt;/code&gt;, or &lt;code&gt;lo&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ADDRESS&lt;/code&gt; - the IP address to assign to the interface&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="note callout callout-info"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" &gt;
&lt;path d="M 16 3 C 8.832031 3 3 8.832031 3 16 C 3 23.167969 8.832031 29 16 29 C 23.167969 29 29 23.167969 29 16 C 29 8.832031 23.167969 3 16 3 Z M 16 5 C 22.085938 5 27 9.914063 27 16 C 27 22.085938 22.085938 27 16 27 C 9.914063 27 5 22.085938 5 16 C 5 9.914063 9.914063 5 16 5 Z M 15 10 L 15 12 L 17 12 L 17 10 Z M 15 14 L 15 22 L 17 22 L 17 14 Z "&gt;&lt;/path&gt;
&lt;/svg&gt;&lt;span class="callout-title"&gt;Info&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;Modern Linux distributions use predictable interface names such as &lt;code&gt;ens3&lt;/code&gt; or &lt;code&gt;enp0s3&lt;/code&gt; instead of the traditional &lt;code&gt;eth0&lt;/code&gt;. Run &lt;code&gt;ifconfig -a&lt;/code&gt; to see the actual interface names on your system.&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The configurations set with &lt;code&gt;ifconfig&lt;/code&gt; are not persistent. After a system restart, all changes are lost. To make changes permanent, edit the distribution-specific network configuration files or use a network manager.&lt;/p&gt;
&lt;p&gt;Only root or users with &lt;a href="https://linuxize.com/post/sudo-command-in-linux/"&gt;sudo&lt;/a&gt;
privileges can modify network interfaces.&lt;/p&gt;
&lt;h2 id="display-network-interface-information"&gt;Display Network Interface Information &lt;a class="headline-link" href="#display-network-interface-information" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Run &lt;code&gt;ifconfig&lt;/code&gt; without options to display all active network interfaces:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ifconfig&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To display all interfaces, including inactive ones, add the &lt;code&gt;-a&lt;/code&gt; flag:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ifconfig -a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;eth0: flags=4163&amp;lt;UP,BROADCAST,RUNNING,MULTICAST&amp;gt; mtu 1500
inet 172.20.10.3 netmask 255.255.255.240 broadcast 172.20.10.15
inet6 2401:4900:1d65:40a1:4ebb:58ff:fe9c:f555 prefixlen 64 scopeid 0x0&amp;lt;global&amp;gt;
inet6 fe80::4ebb:58ff:fe9c:f555 prefixlen 64 scopeid 0x20&amp;lt;link&amp;gt;
ether 4c:bb:58:9c:f5:55 txqueuelen 1000 (Ethernet)
RX packets 84110 bytes 70667629 (70.6 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 59727 bytes 20886290 (20.8 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73&amp;lt;UP,LOOPBACK,RUNNING&amp;gt; mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10&amp;lt;host&amp;gt;
loop txqueuelen 1000 (Local Loopback)
RX packets 4198 bytes 498729 (498.7 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4198 bytes 498729 (498.7 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To display information for a specific interface, pass its name as an argument:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ifconfig eth0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The equivalent &lt;code&gt;ip&lt;/code&gt; command is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ip addr show eth0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="assign-an-ip-address-and-netmask-to-a-network-interface"&gt;Assign an IP Address and Netmask to a Network Interface &lt;a class="headline-link" href="#assign-an-ip-address-and-netmask-to-a-network-interface" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To assign an IP address and netmask to an interface, use the following syntax:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ifconfig INTERFACE IP_ADDRESS netmask SUBNET_MASK&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For example, to assign the IP address &lt;code&gt;192.168.0.101&lt;/code&gt; with netmask &lt;code&gt;255.255.0.0&lt;/code&gt; to &lt;code&gt;eth0&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ifconfig eth0 192.168.0.101 netmask 255.255.0.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can also assign a secondary IP address using interface aliasing:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ifconfig eth0:0 192.168.0.102 netmask 255.255.0.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The equivalent &lt;code&gt;ip&lt;/code&gt; command for assigning an address is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ip addr add 192.168.0.101/16 dev eth0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="enable-and-disable-a-network-interface"&gt;Enable and Disable a Network Interface &lt;a class="headline-link" href="#enable-and-disable-a-network-interface" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To disable an active network interface, pass the &lt;code&gt;down&lt;/code&gt; flag after the interface name:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ifconfig eth0 down&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To enable an inactive interface, use the &lt;code&gt;up&lt;/code&gt; flag:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ifconfig eth0 up&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you are connected over SSH through the same interface, bringing it down will disconnect your session. Use caution on remote systems and make sure you have out-of-band access before applying interface state changes.&lt;/p&gt;
&lt;p&gt;The equivalent &lt;code&gt;ip&lt;/code&gt; commands are:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ip link &lt;span class="nb"&gt;set&lt;/span&gt; eth0 down
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ip link &lt;span class="nb"&gt;set&lt;/span&gt; eth0 up&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="enable-and-disable-promiscuous-mode"&gt;Enable and Disable Promiscuous Mode &lt;a class="headline-link" href="#enable-and-disable-promiscuous-mode" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Promiscuous mode allows a network interface to capture and view all packets on the network segment, not just those addressed to it. It is commonly used for network analysis and packet capture with tools like &lt;a href="https://linuxize.com/post/tcpdump-command-in-linux/"&gt;&lt;code&gt;tcpdump&lt;/code&gt;&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;To enable promiscuous mode on an interface:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ifconfig eth0 promisc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To disable promiscuous mode:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ifconfig eth0 -promisc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The equivalent &lt;code&gt;ip&lt;/code&gt; commands are:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ip link &lt;span class="nb"&gt;set&lt;/span&gt; eth0 promisc on
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ip link &lt;span class="nb"&gt;set&lt;/span&gt; eth0 promisc off&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="change-the-mtu-of-a-network-interface"&gt;Change the MTU of a Network Interface &lt;a class="headline-link" href="#change-the-mtu-of-a-network-interface" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The MTU (Maximum Transmission Unit) defines the maximum size of packets transmitted on an interface. Lowering the MTU can help on networks with fragmentation issues; raising it (jumbo frames) can improve throughput on supported networks.&lt;/p&gt;
&lt;p&gt;To change the MTU value, use the following syntax:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ifconfig INTERFACE mtu MTU_VALUE&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For example, to set the MTU of &lt;code&gt;eth0&lt;/code&gt; to &lt;code&gt;9000&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ifconfig eth0 mtu &lt;span class="m"&gt;9000&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The equivalent &lt;code&gt;ip&lt;/code&gt; command is:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ip link &lt;span class="nb"&gt;set&lt;/span&gt; eth0 mtu &lt;span class="m"&gt;9000&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="change-the-mac-address-of-a-network-interface"&gt;Change the MAC Address of a Network Interface &lt;a class="headline-link" href="#change-the-mac-address-of-a-network-interface" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The MAC (Media Access Control) address is the hardware address that uniquely identifies a network interface on a local network.&lt;/p&gt;
&lt;p&gt;To change the MAC address, first bring the interface down, then set the new address with the &lt;code&gt;hw ether&lt;/code&gt; flag:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ifconfig eth0 down
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ifconfig eth0 hw ether 00:00:2d:3a:2a:28
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ifconfig eth0 up&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The interface must be down before changing its MAC address. The equivalent &lt;code&gt;ip&lt;/code&gt; commands are:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ip link &lt;span class="nb"&gt;set&lt;/span&gt; eth0 down
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ip link &lt;span class="nb"&gt;set&lt;/span&gt; eth0 address 00:00:2d:3a:2a:28
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ip link &lt;span class="nb"&gt;set&lt;/span&gt; eth0 up&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;ifconfig: command not found&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
The &lt;code&gt;net-tools&lt;/code&gt; package is not installed. Install it with &lt;code&gt;sudo apt install net-tools&lt;/code&gt; on Ubuntu, Debian, and Derivatives, or &lt;code&gt;sudo dnf install net-tools&lt;/code&gt; on Fedora, RHEL, and Derivatives.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes are lost after a reboot&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;ifconfig&lt;/code&gt; changes are applied only to the running system and do not survive a restart. To make changes permanent, use your distribution&amp;rsquo;s network manager (NetworkManager, systemd-networkd, or Netplan) or edit the appropriate configuration files.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The interface name is not &lt;code&gt;eth0&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
Modern Linux systems use predictable interface names such as &lt;code&gt;ens3&lt;/code&gt;, &lt;code&gt;enp0s3&lt;/code&gt;, or &lt;code&gt;wlp2s0&lt;/code&gt;. Run &lt;code&gt;ifconfig -a&lt;/code&gt; or &lt;code&gt;ip link show&lt;/code&gt; to list the actual interface names on your system.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cannot change the MAC address while the interface is up&lt;/strong&gt;&lt;br&gt;
The interface must be brought down before changing its MAC address. Run &lt;code&gt;ifconfig eth0 down&lt;/code&gt; first, change the address, then bring it back up with &lt;code&gt;ifconfig eth0 up&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;ifconfig&lt;/code&gt; command&lt;/th&gt;
&lt;th&gt;&lt;code&gt;ip&lt;/code&gt; equivalent&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ifconfig&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ip addr show&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show active interfaces&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ifconfig -a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ip addr show&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show all interfaces including inactive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ifconfig eth0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ip addr show eth0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show a specific interface&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ifconfig eth0 IP netmask MASK&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ip addr add IP/PREFIX dev eth0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Assign an IP address&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ifconfig eth0 down&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ip link set eth0 down&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Disable an interface&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ifconfig eth0 up&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ip link set eth0 up&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Enable an interface&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ifconfig eth0 promisc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ip link set eth0 promisc on&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Enable promiscuous mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ifconfig eth0 -promisc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ip link set eth0 promisc off&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Disable promiscuous mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ifconfig eth0 mtu VALUE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ip link set eth0 mtu VALUE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Change MTU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ifconfig eth0 hw ether MAC&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ip link set eth0 address MAC&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Change MAC address&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Should I use &lt;code&gt;ifconfig&lt;/code&gt; or &lt;code&gt;ip&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;ip&lt;/code&gt; for new scripts and day-to-day work. &lt;code&gt;ifconfig&lt;/code&gt; is no longer maintained and is absent from many modern distributions. The &lt;code&gt;ip&lt;/code&gt; command provides all of the same functionality and more. See the Quick Reference table above for the &lt;code&gt;ip&lt;/code&gt; equivalents of common &lt;code&gt;ifconfig&lt;/code&gt; commands.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why do my network changes disappear after a reboot?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;ifconfig&lt;/code&gt; configures the live kernel network state only. The changes are not written to any configuration file. To persist changes, use your distribution&amp;rsquo;s network configuration system: Netplan on Ubuntu, NetworkManager on Fedora, or &lt;code&gt;/etc/network/interfaces&lt;/code&gt; on Debian.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I find my IP address on Linux?&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;ifconfig&lt;/code&gt; to display all active interfaces and their assigned addresses. The &lt;code&gt;inet&lt;/code&gt; field shows the IPv4 address and &lt;code&gt;inet6&lt;/code&gt; shows the IPv6 address. The modern alternative is &lt;code&gt;ip addr show&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is promiscuous mode and is it safe to enable?&lt;/strong&gt;&lt;br&gt;
Promiscuous mode allows an interface to receive all packets on the network, not just those addressed to it. It is safe to enable in controlled environments for diagnostic purposes (for example, with &lt;code&gt;tcpdump&lt;/code&gt;). On shared networks, it can capture other hosts&amp;rsquo; traffic, so it should only be used with appropriate authorization.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;ifconfig&lt;/code&gt; to view and configure network interfaces, assign IP addresses, toggle interface state, and modify MAC addresses and MTU values. For new systems and scripts, prefer the &lt;a href="https://linuxize.com/post/linux-ip-command/"&gt;&lt;code&gt;ip&lt;/code&gt; command&lt;/a&gt;
, which replaces &lt;code&gt;ifconfig&lt;/code&gt; and is available on most modern Linux distributions. For more details, see the &lt;a href="https://man7.org/linux/man-pages/man8/ifconfig.8.html" target="_blank" rel="noopener noreferrer"&gt;ifconfig man page&lt;/a&gt;
.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/ifconfig-command/featured_hu_b869374e33bcba46.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>Grep Exclude: Patterns, Files, and Directories</title><link>https://linuxize.com/post/grep-exclude/</link><pubDate>Tue, 18 May 2021 05:31:00 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/grep-exclude/</guid><category>grep</category><category>linux commands</category><description>Use grep to exclude patterns, files, and directories from search results. Examples for --invert-match, --exclude, --exclude-dir, and --include.</description><content:encoded>&lt;p&gt;&lt;a href="https://linuxize.com/post/how-to-use-grep-command-to-search-files-in-linux/"&gt;Grep&lt;/a&gt;
is a command-line tool for searching files for lines that match a pattern. By default, it prints every matching line to standard output.&lt;/p&gt;
&lt;p&gt;In many situations, you need the opposite, to exclude or ignore certain words, patterns, files, or directories from the search results. This guide explains how to use grep exclusion options with practical examples.&lt;/p&gt;
&lt;h2 id="grep-exclude-syntax"&gt;Grep Exclude Syntax &lt;a class="headline-link" href="#grep-exclude-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use the following syntax when excluding matches, files, or directories:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep [OPTIONS] PATTERN [FILE...]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The most common options for exclusion are &lt;code&gt;-v&lt;/code&gt;, &lt;code&gt;--exclude&lt;/code&gt;, &lt;code&gt;--include&lt;/code&gt;, and &lt;code&gt;--exclude-dir&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="exclude-words-and-patterns"&gt;Exclude Words and Patterns &lt;a class="headline-link" href="#exclude-words-and-patterns" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To display only the lines that do not match a search pattern, use the &lt;code&gt;-v&lt;/code&gt; (or &lt;code&gt;--invert-match&lt;/code&gt;) option.&lt;/p&gt;
&lt;p&gt;For example, to print the lines in &lt;code&gt;/etc/passwd&lt;/code&gt; that do not contain the string &lt;code&gt;nologin&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep -wv nologin /etc/passwd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;root:x:0:0:root:/root:/bin/bash
git:x:994:994:git daemon user:/:/usr/bin/git-shell
linuxize:x:1000:1000:linuxize:/home/linuxize:/bin/bash&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;-w&lt;/code&gt; option tells grep to match only whole words, so &lt;code&gt;nologin&lt;/code&gt; does not match inside longer strings like &lt;code&gt;nologinuser&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="exclude-multiple-patterns"&gt;Exclude Multiple Patterns &lt;a class="headline-link" href="#exclude-multiple-patterns" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To exclude more than one pattern, use the &lt;code&gt;-e&lt;/code&gt; option for each pattern:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep -wv -e nologin -e bash /etc/passwd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can use &lt;code&gt;-e&lt;/code&gt; as many times as needed.&lt;/p&gt;
&lt;p&gt;Another option is to join the patterns with the OR operator (&lt;code&gt;|&lt;/code&gt;). By default, grep interprets patterns as basic regular expressions, where &lt;code&gt;|&lt;/code&gt; must be escaped:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep -wv &lt;span class="s1"&gt;&amp;#39;nologin\|bash&amp;#39;&lt;/span&gt; /etc/passwd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;With extended regular expressions (&lt;code&gt;-E&lt;/code&gt;), the &lt;code&gt;|&lt;/code&gt; operator does not need escaping:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep -Ewv &lt;span class="s1"&gt;&amp;#39;nologin|bash&amp;#39;&lt;/span&gt; /etc/passwd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Both commands produce the same result: lines that contain neither &lt;code&gt;nologin&lt;/code&gt; nor &lt;code&gt;bash&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="exclude-lines-matching-a-position"&gt;Exclude Lines Matching a Position &lt;a class="headline-link" href="#exclude-lines-matching-a-position" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You can use &lt;a href="https://linuxize.com/post/regular-expressions-in-grep/"&gt;regular expressions&lt;/a&gt;
to exclude lines where a pattern appears at a specific position. In the following example, lines where &lt;code&gt;games&lt;/code&gt; appears at the beginning are excluded:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep -v &lt;span class="s2"&gt;&amp;#34;^games&amp;#34;&lt;/span&gt; file.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="exclude-from-piped-output"&gt;Exclude from Piped Output &lt;a class="headline-link" href="#exclude-from-piped-output" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A command&amp;rsquo;s output can be filtered through grep using a pipe. For example, to list all running processes except those owned by &lt;code&gt;root&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ps -ef &lt;span class="p"&gt;|&lt;/span&gt; grep -wv root&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Only the lines that do not contain the whole word &lt;code&gt;root&lt;/code&gt; are printed.&lt;/p&gt;
&lt;h2 id="exclude-files"&gt;Exclude Files &lt;a class="headline-link" href="#exclude-files" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When performing a recursive search with &lt;code&gt;-r&lt;/code&gt; or &lt;code&gt;-R&lt;/code&gt;, you can limit which files grep examines using &lt;code&gt;--exclude&lt;/code&gt; and &lt;code&gt;--include&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="exclude"&gt;&amp;ndash;exclude &lt;a class="headline-link" href="#exclude" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;--exclude&lt;/code&gt; option skips files whose names match a glob pattern. In the following example, grep searches for &lt;code&gt;linuxize&lt;/code&gt; in all files in the current directory but skips &lt;code&gt;.png&lt;/code&gt; and &lt;code&gt;.jpg&lt;/code&gt; files:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep -rl --exclude&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;*.png&amp;#34;&lt;/span&gt; --exclude&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;*.jpg&amp;#34;&lt;/span&gt; linuxize .&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can use &lt;code&gt;--exclude&lt;/code&gt; multiple times to skip different file types.&lt;/p&gt;
&lt;h3 id="include"&gt;&amp;ndash;include &lt;a class="headline-link" href="#include" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;--include&lt;/code&gt; option is the opposite of &lt;code&gt;--exclude&lt;/code&gt;: grep searches only the files whose names match the specified pattern. For example, to search only &lt;code&gt;.conf&lt;/code&gt; files:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep -rl --include&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;*.conf&amp;#34;&lt;/span&gt; linuxize /etc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is useful when you want to narrow the search to a specific file type rather than listing everything to exclude.&lt;/p&gt;
&lt;h3 id="combining-include-and-exclude"&gt;Combining &amp;ndash;include and &amp;ndash;exclude &lt;a class="headline-link" href="#combining-include-and-exclude" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You can use both options together. The following command searches only &lt;code&gt;.log&lt;/code&gt; files but skips any file named &lt;code&gt;debug.log&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep -rl --include&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;*.log&amp;#34;&lt;/span&gt; --exclude&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;debug.log&amp;#34;&lt;/span&gt; error /var/log&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="exclude-directories"&gt;Exclude Directories &lt;a class="headline-link" href="#exclude-directories" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When searching recursively, use &lt;code&gt;--exclude-dir&lt;/code&gt; to skip specific directories or folders. The path is relative to the search directory.&lt;/p&gt;
&lt;p&gt;The following example searches for &lt;code&gt;linuxize&lt;/code&gt; in all files under &lt;code&gt;/etc&lt;/code&gt; but skips the &lt;code&gt;/etc/pki&lt;/code&gt; directory:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep -R --exclude-dir&lt;span class="o"&gt;=&lt;/span&gt;pki linuxize /etc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To exclude multiple directories, use &lt;code&gt;--exclude-dir&lt;/code&gt; for each one:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep -r --exclude-dir&lt;span class="o"&gt;=&lt;/span&gt;proc --exclude-dir&lt;span class="o"&gt;=&lt;/span&gt;boot --exclude-dir&lt;span class="o"&gt;=&lt;/span&gt;sys gnu /&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The difference between &lt;code&gt;-r&lt;/code&gt; and &lt;code&gt;-R&lt;/code&gt; is that &lt;code&gt;-R&lt;/code&gt; follows symbolic links while &lt;code&gt;-r&lt;/code&gt; does not.&lt;/p&gt;
&lt;h3 id="combining-file-and-directory-exclusions"&gt;Combining File and Directory Exclusions &lt;a class="headline-link" href="#combining-file-and-directory-exclusions" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You can combine &lt;code&gt;--exclude&lt;/code&gt;, &lt;code&gt;--include&lt;/code&gt;, and &lt;code&gt;--exclude-dir&lt;/code&gt; in a single command. For example, to search &lt;code&gt;.conf&lt;/code&gt; files under &lt;code&gt;/etc&lt;/code&gt; while skipping the &lt;code&gt;pki&lt;/code&gt; and &lt;code&gt;ssl&lt;/code&gt; directories:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grep -rl --include&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;*.conf&amp;#34;&lt;/span&gt; --exclude-dir&lt;span class="o"&gt;=&lt;/span&gt;pki --exclude-dir&lt;span class="o"&gt;=&lt;/span&gt;ssl error /etc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you mostly need recursive project searches with file-type filters and ignore-file support, &lt;a href="https://linuxize.com/post/ripgrep-in-linux/"&gt;&lt;code&gt;ripgrep&lt;/code&gt;&lt;/a&gt;
can be simpler than combining several &lt;code&gt;grep&lt;/code&gt; exclude options.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-v&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Invert match, show lines that do not match&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-e pattern&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specify a pattern (use multiple times to exclude several)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--exclude=&amp;quot;GLOB&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Skip files matching the glob pattern&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--include=&amp;quot;GLOB&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Search only files matching the glob pattern&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--exclude-dir=DIR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Skip directories matching the name&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-r&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Recursive search (does not follow symlinks)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-R&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Recursive search (follows symlinks)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;-v&lt;/code&gt; and &lt;code&gt;--exclude&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
The &lt;code&gt;-v&lt;/code&gt; option inverts line matching, so it shows lines that do not contain the pattern. The &lt;code&gt;--exclude&lt;/code&gt; option skips entire files based on their filename. They operate at different levels.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I make grep ignore a file or directory?&lt;/strong&gt;&lt;br&gt;
To ignore files by name during a recursive search, use &lt;code&gt;--exclude=&amp;quot;GLOB&amp;quot;&lt;/code&gt;. To ignore directories, use &lt;code&gt;--exclude-dir=DIR&lt;/code&gt;. Both options accept glob patterns and can be specified multiple times to skip several files or directories in one command.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I exclude multiple directories?&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;--exclude-dir&lt;/code&gt; once for each directory you want to skip: &lt;code&gt;grep -r --exclude-dir=dir1 --exclude-dir=dir2 pattern .&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I use regular expressions with &lt;code&gt;--exclude&lt;/code&gt; or &lt;code&gt;--exclude-dir&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
No. These options accept only glob patterns (like &lt;code&gt;*.log&lt;/code&gt; or &lt;code&gt;test_*&lt;/code&gt;), not regular expressions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;-r&lt;/code&gt; and &lt;code&gt;-R&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
Both search directories recursively. The difference is that &lt;code&gt;-R&lt;/code&gt; follows symbolic links while &lt;code&gt;-r&lt;/code&gt; does not. Use &lt;code&gt;-r&lt;/code&gt; to avoid searching the same files twice through symlinks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I exclude case-insensitively?&lt;/strong&gt;&lt;br&gt;
Add the &lt;code&gt;-i&lt;/code&gt; option to make the pattern match case-insensitive: &lt;code&gt;grep -vi pattern file.txt&lt;/code&gt;. The &lt;code&gt;--exclude&lt;/code&gt; and &lt;code&gt;--exclude-dir&lt;/code&gt; options always use case-sensitive glob matching.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Grep provides several options for excluding content from search results. Use &lt;code&gt;-v&lt;/code&gt; to invert line matching, &lt;code&gt;--exclude&lt;/code&gt; and &lt;code&gt;--include&lt;/code&gt; to filter files by name, and &lt;code&gt;--exclude-dir&lt;/code&gt; to skip directories during recursive searches.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/grep-exclude/featured_hu_6c5a6255c7faf396.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>Linux File Permissions Explained</title><link>https://linuxize.com/post/understanding-linux-file-permissions/</link><pubDate>Fri, 30 Apr 2021 05:01:47 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/understanding-linux-file-permissions/</guid><category>linux commands</category><description>Linux file permissions control who can read, write, and execute files and directories. This guide explains permission classes, symbolic and numeric chmod modes, and special bits such as setuid, setgid, and the sticky bit.</description><content:encoded>&lt;p&gt;In Linux, file permissions, attributes, and ownership control the access level that the system processes and users have to files. This ensures that only authorized users and processes can access specific files and directories.&lt;/p&gt;
&lt;h2 id="linux-file-permissions"&gt;Linux File Permissions &lt;a class="headline-link" href="#linux-file-permissions" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The basic Linux permissions model works by associating each system file with an owner and a group and assigning permission access rights for three different classes of users:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The file owner.&lt;/li&gt;
&lt;li&gt;The group members.&lt;/li&gt;
&lt;li&gt;Others (everybody else).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;File ownership can be changed using the &lt;a href="https://linuxize.com/post/linux-chown-command/"&gt;&lt;code&gt;chown&lt;/code&gt;&lt;/a&gt;
and &lt;a href="https://linuxize.com/post/chgrp-command-in-linux/"&gt;&lt;code&gt;chgrp&lt;/code&gt;&lt;/a&gt;
commands.&lt;/p&gt;
&lt;p&gt;Three file permissions types apply to each class of users:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The read permission.&lt;/li&gt;
&lt;li&gt;The write permission.&lt;/li&gt;
&lt;li&gt;The execute permission.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This concept allows you to control which users can read the file, write to the file, or execute the file.&lt;/p&gt;
&lt;p&gt;To view the file permissions, use the &lt;a href="https://linuxize.com/post/how-to-list-files-in-linux-using-the-ls-command/"&gt;&lt;code&gt;ls&lt;/code&gt;&lt;/a&gt;
command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls -l file_name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;-rw-r--r-- 12 linuxize users 12.0K Apr 28 10:10 file_name
|[-][-][-]- [------] [---]
| | | | | | |
| | | | | | +-----------&amp;gt; 7. Group
| | | | | +-------------------&amp;gt; 6. Owner
| | | | +--------------------------&amp;gt; 5. Alternate Access Method
| | | +----------------------------&amp;gt; 4. Others Permissions
| | +-------------------------------&amp;gt; 3. Group Permissions
| +----------------------------------&amp;gt; 2. Owner Permissions
+------------------------------------&amp;gt; 1. File Type&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first character indicates the file type. It can be a regular file (&lt;code&gt;-&lt;/code&gt;), directory (&lt;code&gt;d&lt;/code&gt;), a &lt;a href="https://linuxize.com/post/how-to-create-symbolic-links-in-linux-using-the-ln-command/"&gt;symbolic link&lt;/a&gt;
(&lt;code&gt;l&lt;/code&gt;), or other special types of files. The following nine characters represent the file permissions, three triplets of three characters each. The first triplet shows the owner permissions, the second one group permissions, and the last triplet shows everybody else permissions.&lt;/p&gt;
&lt;p&gt;In the example above, &lt;code&gt;rw-r--r--&lt;/code&gt; means that the file owner has read and write permissions (&lt;code&gt;rw-&lt;/code&gt;), the group and others have only read permissions (&lt;code&gt;r--&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;File permissions have a different meaning depending on the file type.&lt;/p&gt;
&lt;p&gt;Each of the three permission triplets can be constructed of the following characters and have different effects, depending on whether they are set to a file or to a directory:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Effect of Permissions on Files&lt;/strong&gt;&lt;/p&gt;
&lt;div class="mt-0 border-t border-b border-gray-300 dark:border-slate-800 overflow-hidden relative"&gt;
&lt;div class="overflow-y-auto scrollbar-w-2 scrollbar-track-gray-lighter scrollbar-thumb-rounded scrollbar-thumb-gray scrolling-touch"&gt;
&lt;table class="w-full text-left table-collapse"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Permission&lt;/th&gt;
&lt;th&gt;Character&lt;/th&gt;
&lt;th&gt;Meaning on File&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Read&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The file is not readable. You cannot view the file contents.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;r&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The file is readable.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Write&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The file cannot be changed or modified.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;w&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The file can be changed or modified.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Execute&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The file cannot be executed.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;x&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The file can be executed.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;If found in the &lt;code&gt;user&lt;/code&gt; triplet, it sets the &lt;code&gt;setuid&lt;/code&gt; bit. If found in the &lt;code&gt;group&lt;/code&gt; triplet, it sets the &lt;code&gt;setgid&lt;/code&gt; bit. It also means that &lt;code&gt;x&lt;/code&gt; flag is set. &lt;br&gt; When the &lt;code&gt;setuid&lt;/code&gt; or &lt;code&gt;setgid&lt;/code&gt; flags are set on an executable file, the file is executed with the file&amp;rsquo;s owner and/or group privileges.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;S&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Same as &lt;code&gt;s&lt;/code&gt;, but the &lt;code&gt;x&lt;/code&gt; flag is not set. This flag is rarely used on files.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;t&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;If found in the &lt;code&gt;others&lt;/code&gt; triplet, it sets the &lt;code&gt;sticky&lt;/code&gt; bit. &lt;br&gt;It also means that &lt;code&gt;x&lt;/code&gt; flag is set. This flag is useless on files.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;T&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Same as, &lt;code&gt;t&lt;/code&gt; but the &lt;code&gt;x&lt;/code&gt; flag is not set. This flag is useless on files.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Effect of Permissions on Directories (Folders)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Directories are special types of files that can contain other files and directories.&lt;/p&gt;
&lt;div class="mt-0 border-t border-b border-gray-300 dark:border-slate-800 overflow-hidden relative"&gt;
&lt;div class="overflow-y-auto scrollbar-w-2 scrollbar-track-gray-lighter scrollbar-thumb-rounded scrollbar-thumb-gray scrolling-touch"&gt;
&lt;table class="w-full text-left table-collapse"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Permission&lt;/th&gt;
&lt;th&gt;Character&lt;/th&gt;
&lt;th&gt;Meaning on Directory&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Read&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The directory&amp;rsquo;s contents cannot be shown.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;r&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The directory&amp;rsquo;s contents can be shown. &lt;br&gt;(e.g., You can list files inside the directory with &lt;a href="https://linuxize.com/post/how-to-list-files-in-linux-using-the-ls-command/" target="_blank" rel="noopener noreferrer"&gt;&lt;code&gt;ls&lt;/code&gt;&lt;/a&gt;
.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Write&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The directory&amp;rsquo;s contents cannot be altered.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;w&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The directory&amp;rsquo;s contents can be altered. &lt;br&gt;(e.g., You can &lt;a href="https://linuxize.com/post/create-a-file-in-linux/" target="_blank" rel="noopener noreferrer"&gt;create new files&lt;/a&gt;
, &lt;a href="https://linuxize.com/post/how-to-remove-files-and-directories-using-linux-command-line/" target="_blank" rel="noopener noreferrer"&gt;delete files&lt;/a&gt;
..etc.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Execute&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The directory cannot be changed to.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;x&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The directory can be navigated using &lt;a href="https://linuxize.com/post/linux-cd-command/" target="_blank" rel="noopener noreferrer"&gt;&lt;code&gt;cd&lt;/code&gt;&lt;/a&gt;
.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;If found in the &lt;code&gt;user&lt;/code&gt; triplet, it sets the &lt;code&gt;setuid&lt;/code&gt; bit. If found in the &lt;code&gt;group&lt;/code&gt; triplet it sets the &lt;code&gt;setgid&lt;/code&gt; bit. It also means that &lt;code&gt;x&lt;/code&gt; flag is set. When the &lt;code&gt;setgid&lt;/code&gt; flag is set on a directory, the new files created within it inherits the directory group ID (GID) instead of the primary group ID of the user who created the file. &lt;br&gt; &lt;code&gt;setuid&lt;/code&gt; has no effect on directories.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;S&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Same as &lt;code&gt;s&lt;/code&gt;, but the &lt;code&gt;x&lt;/code&gt; flag is not set. This flag is useless on directories.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;t&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;If found in the &lt;code&gt;others&lt;/code&gt; triplet, it sets the &lt;code&gt;sticky&lt;/code&gt; bit. &lt;br&gt;It also means that &lt;code&gt;x&lt;/code&gt; flag is set. When the sticky bit is set on a directory, only the file&amp;rsquo;s owner, the directory&amp;rsquo;s owner, or the administrative user can delete or rename the files within the directory.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;T&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Same as &lt;code&gt;t&lt;/code&gt;, but the &lt;code&gt;x&lt;/code&gt; flag is not set. This flag is useless on directories.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="changing-file-permissions"&gt;Changing File Permissions &lt;a class="headline-link" href="#changing-file-permissions" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;File permissions can be changed using the &lt;code&gt;chmod&lt;/code&gt; command. Only root, the file owner, or a user with sudo privileges can change the permissions of a file. Be extra careful when using &lt;code&gt;chmod&lt;/code&gt;, especially when changing permissions recursively. The command can accept one or more files and/or directories separated by spaces as arguments.&lt;/p&gt;
&lt;p&gt;Permissions can be specified using a symbolic mode, numeric mode, or a reference file.&lt;/p&gt;
&lt;h3 id="symbolic-text-method"&gt;Symbolic (Text) Method &lt;a class="headline-link" href="#symbolic-text-method" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The syntax of the &lt;code&gt;chmod&lt;/code&gt; command when using the symbolic mode has the following format:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="o"&gt;[&lt;/span&gt;OPTIONS&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;ugoa…&lt;span class="o"&gt;][&lt;/span&gt;-+&lt;span class="o"&gt;=]&lt;/span&gt;perms…&lt;span class="o"&gt;[&lt;/span&gt;,…&lt;span class="o"&gt;]&lt;/span&gt; FILE...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The first set of flags (&lt;code&gt;[ugoa…]&lt;/code&gt;), called user flags, defines the user classes whose permissions will be changed.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;u&lt;/code&gt; - The file owner.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;g&lt;/code&gt; - The users who are members of the group.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;o&lt;/code&gt; - All other users.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;a&lt;/code&gt; - All users, identical to &lt;code&gt;ugo&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When the users&amp;rsquo; flag is omitted, it defaults to &lt;code&gt;a&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The second set of flags (&lt;code&gt;[-+=]&lt;/code&gt;), the operation flags, defines whether the permissions are to be removed, added, or set:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-&lt;/code&gt; - Removes the specified permissions.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;+&lt;/code&gt; - Adds specified permissions.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;=&lt;/code&gt; - Changes the current permissions to the specified permissions. If no permissions are given after the &lt;code&gt;=&lt;/code&gt; symbol, all permissions from the specified user class are removed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The permissions (&lt;code&gt;perms...&lt;/code&gt;) are explicitly set using either zero or one or more of the following letters: &lt;code&gt;r&lt;/code&gt;, &lt;code&gt;w&lt;/code&gt;, &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;X&lt;/code&gt;, &lt;code&gt;s&lt;/code&gt;, and &lt;code&gt;t&lt;/code&gt;. Use a single letter from the set &lt;code&gt;u&lt;/code&gt;, &lt;code&gt;g&lt;/code&gt;, and &lt;code&gt;o&lt;/code&gt; when copying permissions from one to another users&amp;rsquo; class.&lt;/p&gt;
&lt;p&gt;When setting permissions for more than one user class (&lt;code&gt;[,…]&lt;/code&gt;), use commas (without spaces) to separate the symbolic modes.&lt;/p&gt;
&lt;p&gt;Here are some examples of how to use the &lt;code&gt;chmod&lt;/code&gt; command in symbolic mode:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Give the members of the group permission to execute the file, but not to read and write to it:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="nv"&gt;g&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;x filename&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Remove the write permission for all users:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod a-w filename&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Recursively remove the execute permission for other users:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod -R o-x dirname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Remove the read, write, and execute permission for all users except the file’s owner:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod og-rwx filename&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The same thing can also be accomplished by using the following form:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="nv"&gt;og&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; filename&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Give read, write and execute permission to the file’s owner, read permissions to the file&amp;rsquo;s group, and no permissions to all other users:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="nv"&gt;u&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;rwx,g&lt;span class="o"&gt;=&lt;/span&gt;r,o&lt;span class="o"&gt;=&lt;/span&gt; filename&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="numeric-method"&gt;Numeric Method &lt;a class="headline-link" href="#numeric-method" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The syntax of the &lt;code&gt;chmod&lt;/code&gt; command when using the numeric mode has the following format:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="o"&gt;[&lt;/span&gt;OPTIONS&lt;span class="o"&gt;]&lt;/span&gt; NUMBER FILE...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When using the numeric mode, you can set the permissions for all three user classes (owner, group, and all others) at the same time.&lt;/p&gt;
&lt;p&gt;The permission number can be a 3-digit or 4-digit number. When a 3-digit number is used, the first digit represents the permissions of the file&amp;rsquo;s owner, the second one the file&amp;rsquo;s group, and the last one all other users.&lt;/p&gt;
&lt;p&gt;Each write, read, and execute permissions have the following number value:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;r&lt;/code&gt; (read) = 4&lt;/li&gt;
&lt;li&gt;&lt;code&gt;w&lt;/code&gt; (write) = 2&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x&lt;/code&gt; (execute) = 1&lt;/li&gt;
&lt;li&gt;no permissions = 0&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The permissions number of a specific user class is represented by the sum of the values of the permissions for that group.&lt;/p&gt;
&lt;p&gt;To find out the file&amp;rsquo;s permissions in numeric mode, simply calculate the totals for all users&amp;rsquo; classes. For example, to give read, write and execute permission to the file’s owner, read and execute permissions to the file&amp;rsquo;s group and only read permissions to all other users, you would do the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Owner: rwx=4+2+1=7&lt;/li&gt;
&lt;li&gt;Group: r-x=4+0+1=5&lt;/li&gt;
&lt;li&gt;Others: r&amp;ndash;=4+0+0=4&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Using the method above, we get the number &lt;code&gt;754&lt;/code&gt;, which represents the desired permissions.&lt;/p&gt;
&lt;p&gt;To set the &lt;code&gt;setuid&lt;/code&gt;, &lt;code&gt;setgid&lt;/code&gt;, and &lt;code&gt;sticky bit&lt;/code&gt; flags, use a 4-digit number.&lt;/p&gt;
&lt;p&gt;When a 4-digit number is used, the first digit has the following meaning:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;setuid=4&lt;/li&gt;
&lt;li&gt;setgid=2&lt;/li&gt;
&lt;li&gt;sticky=1&lt;/li&gt;
&lt;li&gt;no changes = 0&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The next three digits have the same meaning as when using 3 digits number.&lt;/p&gt;
&lt;p&gt;If the first digit is 0 it can be omitted, and the mode can be represented with 3 digits. The numeric mode &lt;code&gt;0755&lt;/code&gt; is the same as &lt;code&gt;755&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To calculate the numeric mode, you can also use another method (binary method), but it is a little more complicated. Knowing how to calculate the numeric mode using 4, 2, and 1 is sufficient for most users.&lt;/p&gt;
&lt;p&gt;You can check the file&amp;rsquo;s permissions in the numeric notation using the &lt;a href="https://linuxize.com/post/stat-command-in-linux/"&gt;&lt;code&gt;stat&lt;/code&gt;&lt;/a&gt;
command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;stat -c &lt;span class="s2"&gt;&amp;#34;%a&amp;#34;&lt;/span&gt; file_name&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Here are some examples of how to use the &lt;code&gt;chmod&lt;/code&gt; command in numeric mode:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Give the file&amp;rsquo;s owner read and write permissions and only read permissions to group members and all other users:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;644&lt;/span&gt; file&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Give the file&amp;rsquo;s owner read, write and execute permissions, read and execute permissions to group members and no permissions to all other users:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;750&lt;/span&gt; file&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Give read, write, and execute permissions, and a sticky bit to a given directory:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod &lt;span class="m"&gt;1777&lt;/span&gt; dirname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Recursively set read, write, and execute permissions to the file owner and no permissions for all other users on a given directory:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod -R &lt;span class="m"&gt;700&lt;/span&gt; dirname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/chmod/"&gt;chmod cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Common permission values:&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Symbolic&lt;/th&gt;
&lt;th&gt;Who can do what&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;777&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rwxrwxrwx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Everyone can read, write, and execute&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;755&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rwxr-xr-x&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Owner full access; group and others read and execute&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;750&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rwxr-x---&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Owner full access; group read and execute; others none&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;700&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rwx------&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Owner full access; group and others none&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;664&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rw-rw-r--&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Owner and group read/write; others read only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;644&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rw-r--r--&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Owner read/write; group and others read only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;600&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rw-------&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Owner read/write; group and others none&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;400&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;r--------&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Owner read only; group and others none&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Symbolic chmod examples:&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Effect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;chmod u+x file&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Add execute for owner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;chmod g-w file&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Remove write for group&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;chmod o= file&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Remove all permissions for others&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;chmod a+r file&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Add read for everyone&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;chmod u=rwx,g=rx,o= file&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Set exact permissions for all classes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;chmod -R 755 dir&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Recursively set permissions on a directory&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;chmod&lt;/code&gt; and &lt;code&gt;chown&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://linuxize.com/post/chmod-command-in-linux/"&gt;&lt;code&gt;chmod&lt;/code&gt;&lt;/a&gt;
changes the permission bits (read, write, execute) on a file. &lt;a href="https://linuxize.com/post/linux-chown-command/"&gt;&lt;code&gt;chown&lt;/code&gt;&lt;/a&gt;
changes the file&amp;rsquo;s owner and group. Both affect who can access the file, but they control different aspects.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What does &lt;code&gt;chmod 777&lt;/code&gt; mean and is it safe?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;777&lt;/code&gt; gives read, write, and execute permission to the owner, group, and all other users. It is rarely appropriate and should be avoided on files that contain sensitive data or are executable by services, as it allows anyone on the system to modify or run them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why does a directory need execute permission?&lt;/strong&gt;&lt;br&gt;
On a directory, execute permission allows you to enter it and access items inside it by name. Without execute permission, you can list the directory contents only in limited cases, but you cannot traverse it with commands such as &lt;code&gt;cd&lt;/code&gt; or open files within it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is the sticky bit and when should I use it?&lt;/strong&gt;&lt;br&gt;
The sticky bit on a directory (mode &lt;code&gt;1xxx&lt;/code&gt;, shown as &lt;code&gt;t&lt;/code&gt; in &lt;code&gt;ls -l&lt;/code&gt;) restricts deletion so that only the file&amp;rsquo;s owner, the directory&amp;rsquo;s owner, or root can delete files inside it. It is used on shared directories like &lt;code&gt;/tmp&lt;/code&gt; to prevent users from deleting each other&amp;rsquo;s files.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is setuid and why is it dangerous?&lt;/strong&gt;&lt;br&gt;
When set on an executable file, &lt;code&gt;setuid&lt;/code&gt; causes the file to run with the owner&amp;rsquo;s privileges rather than the caller&amp;rsquo;s. For example, &lt;code&gt;/usr/bin/passwd&lt;/code&gt; is setuid root so ordinary users can change their own password. Misusing setuid on custom scripts is a common privilege escalation risk.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I view permissions in numeric mode?&lt;/strong&gt;&lt;br&gt;
Use the &lt;a href="https://linuxize.com/post/stat-command-in-linux/"&gt;&lt;code&gt;stat&lt;/code&gt;&lt;/a&gt;
command: &lt;code&gt;stat -c &amp;quot;%a %n&amp;quot; file&lt;/code&gt;. It prints the octal permission value alongside the filename.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In Linux, access to files is controlled through permission bits assigned to three classes — owner, group, and others. Use &lt;code&gt;chmod&lt;/code&gt; with symbolic or numeric mode to change permissions, and use &lt;code&gt;ls -l&lt;/code&gt; or &lt;code&gt;stat&lt;/code&gt; to inspect them. For a focused command reference, see the &lt;a href="https://linuxize.com/post/chmod-command-in-linux/"&gt;&lt;code&gt;chmod&lt;/code&gt; command guide&lt;/a&gt;
.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/understanding-linux-file-permissions/featured_hu_e68ef3b6acdb73f3.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>Listing Linux Services with systemctl</title><link>https://linuxize.com/post/systemctl-list/</link><pubDate>Wed, 23 Dec 2020 20:11:17 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/systemctl-list/</guid><category>linux commands</category><description>Use the systemctl command to list running, failed, and enabled Linux services. Includes filtering by state, checking status, and listing unit files.</description><content:encoded>&lt;p&gt;In Linux, a service is a program that runs in the &lt;a href="https://linuxize.com/post/how-to-run-linux-commands-in-background/"&gt;background&lt;/a&gt;
. Services can be started on-demand or at boot time.&lt;/p&gt;
&lt;p&gt;If you are using Linux as your primary operating system or development platform, you will deal with different services such as a web server, SSH, or &lt;a href="https://linuxize.com/post/scheduling-cron-jobs-with-crontab/"&gt;cron&lt;/a&gt;
. Knowing how to list running services or check the service status is important when debugging system issues.&lt;/p&gt;
&lt;p&gt;Most recent Linux distributions use systemd as the default init system and service manager. Systemd is a suite of tools for managing Linux systems. It is used to boot up the machine, manage services, automount filesystems, log events, set up the hostname, and other system tasks.&lt;/p&gt;
&lt;p&gt;This article explains how to use &lt;code&gt;systemctl&lt;/code&gt; to list services, filter by state, and check service status.&lt;/p&gt;
&lt;h2 id="listing-services"&gt;Listing Services &lt;a class="headline-link" href="#listing-services" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Systemd uses the concept of units, which can be services, sockets, mount points, devices, etc. Units are defined using text files in &lt;code&gt;ini&lt;/code&gt; format. These files include information about the unit, its settings, and commands to execute. The filename extension defines the unit file type. For example, system service unit files have a &lt;code&gt;.service&lt;/code&gt; extension. To write one from scratch, see &lt;a href="https://linuxize.com/post/how-to-create-a-systemd-service/"&gt;How to Create a systemd Service File in Linux&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://linuxize.com/post/systemctl-command-in-linux/"&gt;&lt;code&gt;systemctl&lt;/code&gt;&lt;/a&gt;
is a command-line utility used for controlling systemd and managing services. It is part of the systemd ecosystem and is available by default on most modern Linux distributions.&lt;/p&gt;
&lt;p&gt;To get a list of all loaded service units, type:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl list-units --type service&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;UNIT LOAD ACTIVE SUB DESCRIPTION
cron.service loaded active running Regular background program processing daemon
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Each line of output contains the following columns from left to right:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;UNIT&lt;/code&gt; — The name of the service unit.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LOAD&lt;/code&gt; — Whether the unit file has been loaded into memory.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ACTIVE&lt;/code&gt; — The high-level activation state, which can be active, reloading, inactive, failed, activating, or deactivating. It is a generalization of the &lt;code&gt;SUB&lt;/code&gt; column.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SUB&lt;/code&gt; — The low-level activation state. The value of this field depends on the unit type. For example, a service unit can be in one of the following states: dead, exited, failed, inactive, or running.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DESCRIPTION&lt;/code&gt; — A short description of the unit.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By default, the command lists only the loaded active units. To see loaded but inactive units too, pass the &lt;code&gt;--all&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl list-units --type service --all&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="filtering-by-state"&gt;Filtering by State &lt;a class="headline-link" href="#filtering-by-state" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can use the &lt;code&gt;--state&lt;/code&gt; flag to filter services by their current state. This is useful when you want to see only running services or only those that have failed.&lt;/p&gt;
&lt;p&gt;To list only running services:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl list-units --type service --state&lt;span class="o"&gt;=&lt;/span&gt;running&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To list only failed services:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl list-units --type service --state&lt;span class="o"&gt;=&lt;/span&gt;failed&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;There is also a shortcut for listing all failed units across the system:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl --failed&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To list exited services (services that ran once and completed):&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl list-units --type service --state&lt;span class="o"&gt;=&lt;/span&gt;exited&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="listing-installed-unit-files"&gt;Listing Installed Unit Files &lt;a class="headline-link" href="#listing-installed-unit-files" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;list-unit-files&lt;/code&gt; command shows all installed unit files on disk, not just the currently loaded ones. This is useful for checking which services are enabled to start at boot:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl list-unit-files --type service&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;UNIT FILE STATE PRESET
cron.service enabled enabled
nginx.service enabled enabled
ssh.service enabled enabled
apparmor.service enabled enabled
apt-daily.service static -
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;STATE&lt;/code&gt; column shows the enable status of each service:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;enabled&lt;/code&gt; — The service starts automatically at boot.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;disabled&lt;/code&gt; — The service does not start at boot.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;static&lt;/code&gt; — The service cannot be enabled directly. It is started only as a dependency of another unit.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;masked&lt;/code&gt; — The service is completely blocked from starting.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To list only the services that are enabled at boot, you can filter by state:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl list-unit-files --type service --state&lt;span class="o"&gt;=&lt;/span&gt;enabled&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="displaying-service-status"&gt;Displaying Service Status &lt;a class="headline-link" href="#displaying-service-status" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To check the status of a service, use the &lt;code&gt;systemctl status&lt;/code&gt; command. For example, to determine the current status of the nginx service you would run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl status nginx.service&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="note callout callout-tip"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50"&gt;
&lt;path d="M25 6c-1.645 0-3 1.355-3 3v1.406c-1.945.457-3.645 1.36-4.953 2.676C15.094 15.055 14 17.848 14 21.062v7.801c0 1.836-1.004 4.164-2.04 5.89l-1.792 2.692a1.01 1.01 0 0 0-.05 1.028c.175.324.515.527.882.527h9c0 2.746 2.254 5 5 5s5-2.254 5-5h9c.367 0 .707-.203.883-.527a1.01 1.01 0 0 0-.051-1.028l-1.785-2.68-.004-.003C36.996 33.016 36 30.836 36 29v-7.8c0-5.368-3.195-9.524-8-10.759V9c0-1.645-1.355-3-3-3zm0 2c.555 0 1 .445 1 1v1.113c-.223-.02-.441-.043-.668-.05A1.064 1.064 0 0 0 25 10c-.11 0-.215.02-.316.059-.235.004-.457.027-.684.043V9c0-.555.445-1 1-1zM3.48 9.477C1.25 13.102 0 17.418 0 22s1.25 8.898 3.48 12.523l1.708-1.046C3.151 30.168 2 26.219 2 22s1.152-8.168 3.188-11.477zm43.04 0l-1.708 1.046C46.849 13.832 48 17.781 48 22s-1.152 8.168-3.188 11.477l1.708 1.046C48.75 30.898 50 26.582 50 22s-1.25-8.898-3.48-12.523zM25 12c5.512 0 9 3.668 9 9.2V29c0 2.512 1.203 4.918 2.328 6.797.012.012.02.027.027.039L37.13 37H12.87l.774-1.164c.007-.012.015-.027.027-.04C14.809 33.903 16 31.376 16 28.864v-7.8c0-2.766.914-5.004 2.469-6.57C20.019 12.925 22.239 12 25 12zm-17.184.14C5.996 15.083 5 18.356 5 22c0 3.672 1.129 7.047 2.809 9.848l1.714-1.032C8.008 28.286 7 25.262 7 22c0-3.29.871-6.148 2.516-8.809zm34.368 0l-1.7 1.051C42.13 15.851 43 18.711 43 22c0 3.262-1.008 6.285-2.527 8.816l1.718 1.032C43.871 29.047 45 25.672 45 22c0-3.645-.996-6.918-2.816-9.86zM22 39h6a3 3 0 0 1-6 0z"/&gt;
&lt;/svg&gt;
&lt;span class="callout-title"&gt;Tip&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;You can omit the &amp;ldquo;.service&amp;rdquo; suffix. &lt;code&gt;systemctl status nginx&lt;/code&gt; is the same as &lt;code&gt;systemctl status nginx.service&lt;/code&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2026-03-03 19:13:50 UTC; 4 days ago
Docs: man:nginx(8)
Main PID: 3061064 (nginx)
Tasks: 2 (limit: 470)
Memory: 6.0M
CGroup: /system.slice/nginx.service
├─3061064 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
└─3061065 nginx: worker process&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The command will print the following information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Loaded&lt;/code&gt; — Whether the service unit has been loaded and the full path to the unit file. It also shows whether the unit is enabled to start at boot.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Active&lt;/code&gt; — Whether the service is active and running. If your terminal supports colors and the service is active, the dot (&lt;code&gt;●&lt;/code&gt;) and &amp;ldquo;active (running)&amp;rdquo; part will be printed in green. The line also shows how long the service has been running.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Docs&lt;/code&gt; — The service documentation.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Main PID&lt;/code&gt; — The process ID of the main service process.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Tasks&lt;/code&gt; — The number of tasks accounted for the unit and the tasks limit.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Memory&lt;/code&gt; — Information about used memory.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CGroup&lt;/code&gt; — Information about related Control Groups.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="quick-status-checks"&gt;Quick Status Checks &lt;a class="headline-link" href="#quick-status-checks" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you only want to check whether a service is running without the full status output, use the &lt;code&gt;systemctl is-active&lt;/code&gt; command. For example, to verify that the nginx service is running, you would run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl is-active nginx.service&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;active&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To check whether a service is enabled to start at boot, use &lt;code&gt;systemctl is-enabled&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl is-enabled nginx.service&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;enabled&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Both commands return an exit status of 0 for true and non-zero for false, which makes them useful inside shell scripts:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="sh"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;sh&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; systemctl is-active --quiet nginx&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Nginx is running&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;--quiet&lt;/code&gt; flag suppresses the text output so only the exit status is used.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;systemctl list-units --type service&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List loaded active services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;systemctl list-units --type service --all&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List all loaded services including inactive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;systemctl list-units --type service --state=running&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List only running services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;systemctl --failed&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List all failed units&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;systemctl list-unit-files --type service&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List all installed service unit files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;systemctl list-unit-files --state=enabled&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List services enabled at boot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;systemctl status service_name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show detailed service status&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;systemctl is-active service_name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Check if a service is running&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;systemctl is-enabled service_name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Check if a service starts at boot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;systemctl list-units --no-pager&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List units without pager (useful for scripts)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;For a printable quick reference, see the &lt;a href="https://linuxize.com/cheatsheet/systemctl/"&gt;systemctl cheatsheet&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Unit service_name.service could not be found&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
Check the exact unit name with &lt;code&gt;systemctl list-unit-files --type service | grep name&lt;/code&gt;. Some services use different unit names than package names.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;systemctl&lt;/code&gt; output is paged and hard to use in scripts&lt;/strong&gt;&lt;br&gt;
Add &lt;code&gt;--no-pager&lt;/code&gt; to listing and status commands so output is printed directly to stdout.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Service shows &lt;code&gt;failed&lt;/code&gt; but &lt;code&gt;status&lt;/code&gt; output is too short&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;systemctl status service_name&lt;/code&gt; for recent errors, then run &lt;code&gt;journalctl -u service_name&lt;/code&gt; for full logs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You can list services but cannot manage them&lt;/strong&gt;&lt;br&gt;
Listing usually works without root privileges. Starting, stopping, enabling, and disabling services requires &lt;code&gt;sudo&lt;/code&gt; or equivalent administrative permissions.&lt;/p&gt;
&lt;h2 id="faq"&gt;FAQ &lt;a class="headline-link" href="#faq" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;list-units&lt;/code&gt; and &lt;code&gt;list-unit-files&lt;/code&gt;?&lt;/strong&gt;
&lt;code&gt;list-units&lt;/code&gt; shows units that are currently loaded in memory. &lt;code&gt;list-unit-files&lt;/code&gt; shows all installed unit files on disk, regardless of whether they are loaded. Use &lt;code&gt;list-unit-files&lt;/code&gt; when you want to see which services are enabled or disabled at boot.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Do I need &lt;code&gt;sudo&lt;/code&gt; to list services?&lt;/strong&gt;
No. Most &lt;code&gt;systemctl&lt;/code&gt; listing and status commands work without &lt;code&gt;sudo&lt;/code&gt;. You only need elevated privileges to start, stop, enable, or disable services.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What does a &amp;ldquo;static&amp;rdquo; unit file state mean?&lt;/strong&gt;
A static service cannot be enabled or disabled directly with &lt;code&gt;systemctl enable&lt;/code&gt;. It is designed to be started only as a dependency of another unit or by manual invocation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do I find out why a service failed?&lt;/strong&gt;
Run &lt;code&gt;systemctl status service_name&lt;/code&gt; to see the last few log lines. For the full log output, use the &lt;a href="https://linuxize.com/post/journalctl-command-in-linux/"&gt;&lt;code&gt;journalctl -u service_name&lt;/code&gt;&lt;/a&gt;
command.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We have shown you how to use the &lt;code&gt;systemctl&lt;/code&gt; command to list Linux services, filter them by state, and check their status. To view detailed logs for a service, use the &lt;a href="https://linuxize.com/post/journalctl-command-in-linux/"&gt;&lt;code&gt;journalctl&lt;/code&gt;&lt;/a&gt;
command.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/systemctl-list/featured_hu_ee2645988c97a412.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>nmap Command in Linux with Practical Examples</title><link>https://linuxize.com/post/nmap-command/</link><pubDate>Wed, 16 Dec 2020 20:31:47 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/nmap-command/</guid><category>linux commands</category><description>Use the nmap command in Linux to discover hosts, scan ports, detect services, and understand common scan options such as -sn, -Pn, and -sV.</description><content:encoded>&lt;p&gt;When you need to see which hosts are online, which ports are open, or which service is listening on a remote system, &lt;code&gt;nmap&lt;/code&gt; is usually the first tool to reach for. It is widely used for network inventory, service discovery, troubleshooting, and security reviews.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;nmap&lt;/code&gt; command can also detect service versions, guess the remote operating system, and run scripts for deeper checks. This guide explains the most useful &lt;code&gt;nmap&lt;/code&gt; options in Linux through practical examples.&lt;/p&gt;
&lt;div class="note callout callout-warning"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"&gt;
&lt;path d="M10 20C4.477 20 0 15.523 0 10S4.477 0 10 0s10 4.477 10 10-4.477 10-10 10zm0-2c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm-.5-5h1c.276 0 .5.224.5.5v1c0 .276-.224.5-.5.5h-1c-.276 0-.5-.224-.5-.5v-1c0-.276.224-.5.5-.5zm0-8h1c.276 0 .5.224.5.5V8l-.5 3-1 .5L9 8V5.5c0-.276.224-.5.5-.5z"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;span class="callout-title"&gt;Warning&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;Scan only systems and networks you own or have permission to test. Unauthorized scanning can trigger alerts and may violate local law or policy.&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="nmap-command-syntax"&gt;nmap Command Syntax &lt;a class="headline-link" href="#nmap-command-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use the following syntax when running &lt;code&gt;nmap&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmap [OPTIONS] TARGET...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;OPTIONS&lt;/code&gt; - Scan type, host discovery, output, and detection flags such as &lt;code&gt;-sn&lt;/code&gt;, &lt;code&gt;-Pn&lt;/code&gt;, &lt;code&gt;-sV&lt;/code&gt;, or &lt;code&gt;-p&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TARGET&lt;/code&gt; - One or more IP addresses, hostnames, CIDR ranges, or target lists.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="installing-nmap"&gt;Installing Nmap &lt;a class="headline-link" href="#installing-nmap" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Nmap is available on all major operating systems, including Linux, BSD, macOS, and Windows.&lt;/p&gt;
&lt;p&gt;If you prefer a GUI, Nmap also ships with &lt;a href="https://nmap.org/zenmap/" target="_blank" rel="noopener noreferrer"&gt;Zenmap&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;Official packages and installers are available from the Nmap &lt;a href="https://nmap.org/download.html" target="_blank" rel="noopener noreferrer"&gt;download page&lt;/a&gt;
.&lt;/p&gt;
&lt;h3 id="ubuntu-debian-and-derivatives"&gt;Ubuntu, Debian, and Derivatives &lt;a class="headline-link" href="#ubuntu-debian-and-derivatives" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Nmap is available from the default Ubuntu and Debian repositories. To install it, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install nmap&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="fedora-rhel-and-derivatives"&gt;Fedora, RHEL, and Derivatives &lt;a class="headline-link" href="#fedora-rhel-and-derivatives" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;On Fedora and other Red Hat derivatives, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install nmap&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="macos"&gt;macOS &lt;a class="headline-link" href="#macos" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;macOS users can install Nmap by downloading the &amp;ldquo;.dmg&amp;rdquo; installation package from the Nmap site or via Homebrew:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;brew install nmap&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="windows"&gt;Windows &lt;a class="headline-link" href="#windows" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The easiest way to install Nmap on Windows is to download and run the installer from the official site.&lt;/p&gt;
&lt;p&gt;You can run it from Command Prompt, PowerShell, or Zenmap. For more details, check the &lt;a href="https://nmap.org/book/inst-windows.html#inst-win-exec" target="_blank" rel="noopener noreferrer"&gt;post-install usage instructions&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="run-a-basic-nmap-scan"&gt;Run a Basic nmap Scan &lt;a class="headline-link" href="#run-a-basic-nmap-scan" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Nmap is typically used to audit network security, network mapping, identify open ports, and search for online devices. For quick single-port checks or simple TCP/UDP tests, &lt;a href="https://linuxize.com/post/netcat-nc-command-with-examples/"&gt;&lt;code&gt;netcat&lt;/code&gt;&lt;/a&gt;
is a lightweight alternative.&lt;/p&gt;
&lt;p&gt;The simplest scan targets a single host without any extra options:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmap scanme.nmap.org&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;When you run &lt;code&gt;nmap&lt;/code&gt; as a regular user without raw packet privileges, it falls back to a TCP connect scan (&lt;code&gt;-sT&lt;/code&gt;). That means Nmap asks the operating system to complete the TCP connection instead of crafting raw SYN packets itself.&lt;/p&gt;
&lt;p&gt;The output includes the responsive host, latency, and the ports Nmap found open or filtered:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;Starting Nmap 7.91 ( https://nmap.org ) at 2020-12-16 20:19 CET
Nmap scan report for cast.lan (192.168.10.121)
Host is up (0.048s latency).
Not shown: 981 closed ports
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
25/tcp open smtp
53/tcp open domain
80/tcp open http
110/tcp open pop3
143/tcp open imap
443/tcp open https
587/tcp open submission
993/tcp open imaps
995/tcp open pop3s
1025/tcp open NFS-or-IIS
1080/tcp open socks
8080/tcp open http-proxy
8081/tcp open blackice-icecap
Nmap done: 1 IP address (1 host up) scanned in 1.78 seconds&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In this example, Nmap reports several open TCP ports such as &lt;code&gt;22/tcp&lt;/code&gt; for SSH and &lt;code&gt;443/tcp&lt;/code&gt; for HTTPS. &amp;ldquo;Not shown&amp;rdquo; tells you how many scanned ports were closed and therefore omitted from the main list.&lt;/p&gt;
&lt;h2 id="when-to-use-sudo-nmap"&gt;When to Use &lt;code&gt;sudo nmap&lt;/code&gt; &lt;a class="headline-link" href="#when-to-use-sudo-nmap" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The most common follow-up question is when to run &lt;code&gt;sudo nmap&lt;/code&gt;. On Linux, privileged scans allow Nmap to use raw packets, which enables SYN scanning (&lt;code&gt;-sS&lt;/code&gt;) and some advanced detection features.&lt;/p&gt;
&lt;p&gt;Run this command to use the default privileged TCP SYN scan:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmap 192.168.10.121&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;With &lt;code&gt;sudo&lt;/code&gt;, Nmap usually switches to SYN scan (&lt;code&gt;-sS&lt;/code&gt;). This is generally faster and lighter than a full TCP connect scan, which is why queries such as &lt;code&gt;sudo nmap&lt;/code&gt; are so common.&lt;/p&gt;
&lt;p&gt;If you want to be explicit, specify the scan type directly:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmap -sS 192.168.10.121&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Use &lt;code&gt;-v&lt;/code&gt; or &lt;code&gt;-vv&lt;/code&gt; for more detailed progress information:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmap -vv 192.168.10.121&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To perform a UDP scan, run &lt;code&gt;nmap&lt;/code&gt; as root and add &lt;code&gt;-sU&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmap -sU 192.168.10.121&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;UDP scans are slower because UDP does not confirm closed ports the same way TCP does. For that reason, it is often better to target only the ports you care about.&lt;/p&gt;
&lt;p&gt;Nmap also supports IPv6 targets. To scan an IPv6 host, use &lt;code&gt;-6&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmap -6 fd12:3456:789a:1::1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="specify-target-hosts"&gt;Specify Target Hosts &lt;a class="headline-link" href="#specify-target-hosts" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Nmap treats every non-option argument as a target host.&lt;/p&gt;
&lt;div class="note callout callout-tip"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50"&gt;
&lt;path d="M25 6c-1.645 0-3 1.355-3 3v1.406c-1.945.457-3.645 1.36-4.953 2.676C15.094 15.055 14 17.848 14 21.062v7.801c0 1.836-1.004 4.164-2.04 5.89l-1.792 2.692a1.01 1.01 0 0 0-.05 1.028c.175.324.515.527.882.527h9c0 2.746 2.254 5 5 5s5-2.254 5-5h9c.367 0 .707-.203.883-.527a1.01 1.01 0 0 0-.051-1.028l-1.785-2.68-.004-.003C36.996 33.016 36 30.836 36 29v-7.8c0-5.368-3.195-9.524-8-10.759V9c0-1.645-1.355-3-3-3zm0 2c.555 0 1 .445 1 1v1.113c-.223-.02-.441-.043-.668-.05A1.064 1.064 0 0 0 25 10c-.11 0-.215.02-.316.059-.235.004-.457.027-.684.043V9c0-.555.445-1 1-1zM3.48 9.477C1.25 13.102 0 17.418 0 22s1.25 8.898 3.48 12.523l1.708-1.046C3.151 30.168 2 26.219 2 22s1.152-8.168 3.188-11.477zm43.04 0l-1.708 1.046C46.849 13.832 48 17.781 48 22s-1.152 8.168-3.188 11.477l1.708 1.046C48.75 30.898 50 26.582 50 22s-1.25-8.898-3.48-12.523zM25 12c5.512 0 9 3.668 9 9.2V29c0 2.512 1.203 4.918 2.328 6.797.012.012.02.027.027.039L37.13 37H12.87l.774-1.164c.007-.012.015-.027.027-.04C14.809 33.903 16 31.376 16 28.864v-7.8c0-2.766.914-5.004 2.469-6.57C20.019 12.925 22.239 12 25 12zm-17.184.14C5.996 15.083 5 18.356 5 22c0 3.672 1.129 7.047 2.809 9.848l1.714-1.032C8.008 28.286 7 25.262 7 22c0-3.29.871-6.148 2.516-8.809zm34.368 0l-1.7 1.051C42.13 15.851 43 18.711 43 22c0 3.262-1.008 6.285-2.527 8.816l1.718 1.032C43.871 29.047 45 25.672 45 22c0-3.645-.996-6.918-2.816-9.86zM22 39h6a3 3 0 0 1-6 0z"/&gt;
&lt;/svg&gt;
&lt;span class="callout-title"&gt;Tip&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;Arguments that begin with &lt;code&gt;-&lt;/code&gt; or &lt;code&gt;--&lt;/code&gt; are treated as options.&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The simplest form is to pass one or more IP addresses or hostnames:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmap 192.168.10.121 host.to.scan&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Use CIDR notation to scan a network range:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmap 192.168.10.0/24&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can also use octet ranges. This example scans &lt;code&gt;192.168.10.1&lt;/code&gt;, &lt;code&gt;192.168.11.1&lt;/code&gt;, and &lt;code&gt;192.168.12.1&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmap 192.168.10-12.1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Commas let you define multiple values in the same octet:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmap 192.168.10,11,12.1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can combine these forms in one command:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmap 10.8-10.10,11,12.0/28 192.168.1-2.100,101&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you want to confirm the target list before scanning, use &lt;code&gt;-sL&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmap -sL 10.8-10.10,11,12.0/28 192.168.1-2.100,101&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This lists the targets without performing a scan, which is useful when you are working with a large or complex range.&lt;/p&gt;
&lt;p&gt;To exclude one or more hosts from a range, use &lt;code&gt;--exclude&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmap 10.8-10.10,11,12.0/28 --exclude 10.10.12.12&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="scan-specific-ports"&gt;Scan Specific Ports &lt;a class="headline-link" href="#scan-specific-ports" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, Nmap performs a quick scan for the 1000 most popular ports. These ports are not the first 1000 consecutive ports, but the 1000 most commonly used ports ranging from 1 to 65389.&lt;/p&gt;
&lt;p&gt;To scan for all ports from 1 through 65535, use the &lt;code&gt;-p-&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmap -p- 192.168.10.121&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Each port can be in one of the following states:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;open&lt;/code&gt; - A service on the target accepted the connection or probe.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;closed&lt;/code&gt; - The host responded, but nothing is listening on that port.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;filtered&lt;/code&gt; - A firewall, packet filter, or network rule prevented Nmap from confirming the port state.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ports and port ranges are specified with &lt;code&gt;-p&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To scan only port &lt;code&gt;443&lt;/code&gt;, run:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmap -p &lt;span class="m"&gt;443&lt;/span&gt; 192.168.10.121&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To scan multiple ports, separate them with commas:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmap -p 80,443 192.168.10.121&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Use a dash for ranges. This example scans UDP ports &lt;code&gt;1&lt;/code&gt; through &lt;code&gt;1024&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmap -sU -p 1-1024 192.168.10.121&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can combine ranges and individual ports:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmap -p 1-1024,8080,9000 192.168.10.121&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can also use service names. For example, this scans the SSH port:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmap -p ssh 192.168.10.121&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="discover-live-hosts-with--sn"&gt;Discover Live Hosts with &lt;code&gt;-sn&lt;/code&gt; &lt;a class="headline-link" href="#discover-live-hosts-with--sn" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To perform host discovery without a port scan, use &lt;code&gt;-sn&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmap -sn 192.168.10.0/24&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This tells Nmap to find which hosts are up and skip the port scan stage. It is useful when you want a fast inventory of live systems on a subnet before deciding what to scan next.&lt;/p&gt;
&lt;h2 id="skip-host-discovery-with--pn"&gt;Skip Host Discovery with &lt;code&gt;-Pn&lt;/code&gt; &lt;a class="headline-link" href="#skip-host-discovery-with--pn" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, Nmap performs host discovery first and scans only hosts it believes are online. That behavior is efficient, but it can miss hosts when firewalls drop discovery probes.&lt;/p&gt;
&lt;p&gt;Use &lt;code&gt;-Pn&lt;/code&gt; to skip host discovery and treat every target as online:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmap -Pn 192.168.10.121&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is especially useful when a host blocks ping or other discovery probes but still has open ports you want to test. The tradeoff is speed: &lt;code&gt;-Pn&lt;/code&gt; can make large scans much slower because Nmap attempts the requested scan against every target you specify.&lt;/p&gt;
&lt;p&gt;If you see guidance online for &lt;code&gt;-P0&lt;/code&gt; or &lt;code&gt;-PN&lt;/code&gt;, that refers to older Nmap syntax. The current option is &lt;code&gt;-Pn&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="disable-dns-name-resolution"&gt;Disable DNS Name Resolution &lt;a class="headline-link" href="#disable-dns-name-resolution" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Nmap&amp;rsquo;s default behavior is to perform reverse-DNS resolution for each discovered host, which increases the scan time.&lt;/p&gt;
&lt;p&gt;When scanning large ranges, disabling DNS lookups can make the scan noticeably faster. Use &lt;code&gt;-n&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmap -n 192.168.10.0/16&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="detect-services-versions-and-os-details"&gt;Detect Services, Versions, and OS Details &lt;a class="headline-link" href="#detect-services-versions-and-os-details" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To identify the service and version behind an open port, use &lt;code&gt;-sV&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmap -sV scanme.nmap.org&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This helps when the port number alone is not enough, especially if a service is running on a non-standard port.&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;...
PORT STATE SERVICE VERSION
19/tcp filtered chargen
22/tcp open ssh OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.13 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.7 ((Ubuntu))
135/tcp filtered msrpc
139/tcp filtered netbios-ssn
445/tcp filtered microsoft-ds
9929/tcp open nping-echo Nping echo
31337/tcp open tcpwrapped
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To attempt operating system detection, use &lt;code&gt;-O&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmap -O scanme.nmap.org&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If Nmap can fingerprint the remote system, the output looks similar to this:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;...
Device type: general purpose
Running: Linux 5.X
OS CPE: cpe:/o:linux:linux_kernel:5
OS details: Linux 5.0 - 5.4
Network Distance: 18 hops
OS detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 26.47 seconds&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you want OS detection, version detection, default scripts, and &lt;a href="https://linuxize.com/post/traceroute-command-in-linux/"&gt;traceroute&lt;/a&gt;
in one command, use &lt;code&gt;-A&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmap -A 192.168.10.121&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Aggressive scan mode is useful during focused testing, but it is heavier and slower than a basic scan. It is usually better to start small and add options as needed.&lt;/p&gt;
&lt;h2 id="save-nmap-output"&gt;Save nmap Output &lt;a class="headline-link" href="#save-nmap-output" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By default, Nmap prints the information to standard output (stdout).&lt;/p&gt;
&lt;p&gt;If you scan a large network or need to keep the results, save the output to a file.&lt;/p&gt;
&lt;p&gt;To save the normal human-readable output, use &lt;code&gt;-oN&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmap -sU -p 1-1024 192.168.10.121 -oN output.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;To save XML output for later parsing or import into other tools, use &lt;code&gt;-oX&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmap -sU -p 1-1024 192.168.10.121 -oX output.xml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you want normal, XML, and grepable output files in one run, use &lt;code&gt;-oA&lt;/code&gt; with a base filename:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmap -sV 192.168.10.121 -oA scan-results&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This creates files such as &lt;code&gt;scan-results.nmap&lt;/code&gt; and &lt;code&gt;scan-results.xml&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Nmap still supports grepable output with &lt;code&gt;-oG&lt;/code&gt;, which can be processed with tools such as &lt;a href="https://linuxize.com/post/how-to-use-grep-command-to-search-files-in-linux/"&gt;&lt;code&gt;grep&lt;/code&gt;&lt;/a&gt;
, &lt;a href="https://linuxize.com/post/awk-command/"&gt;&lt;code&gt;awk&lt;/code&gt;&lt;/a&gt;
, and &lt;a href="https://linuxize.com/post/linux-cut-command/"&gt;&lt;code&gt;cut&lt;/code&gt;&lt;/a&gt;
. However, the Nmap documentation treats grepable output as deprecated, so XML is the better choice for new automation.&lt;/p&gt;
&lt;h2 id="use-the-nmap-scripting-engine"&gt;Use the Nmap Scripting Engine &lt;a class="headline-link" href="#use-the-nmap-scripting-engine" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One of the most powerful features of Nmap is its scripting engine. Nmap ships with &lt;a href="https://github.com/nmap/nmap/tree/master/scripts" target="_blank" rel="noopener noreferrer"&gt;hundreds of scripts&lt;/a&gt;
, and you can also write your own scripts in the Lua language.&lt;/p&gt;
&lt;p&gt;You can use scripts to gather extra information, test specific services, and automate common checks.&lt;/p&gt;
&lt;p&gt;For example, this script checks a web target against a malware host list:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmap -sV --script http-malware-host scanme.nmap.org&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Because NSE scripts range from simple information gathering to intrusive checks, review the script before running it against production systems.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Basic scan&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nmap target&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SYN scan as root&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo nmap -sS target&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scan specific ports&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nmap -p 22,80,443 target&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scan all ports&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nmap -p- target&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Host discovery only&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo nmap -sn 192.168.10.0/24&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skip host discovery&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo nmap -Pn target&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Detect service versions&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo nmap -sV target&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OS detection&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo nmap -O target&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Save normal output&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nmap target -oN output.txt&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Save all major formats&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nmap target -oA scan-results&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Host appears down, but you know it is online&lt;/strong&gt;&lt;br&gt;
Try &lt;code&gt;-Pn&lt;/code&gt; to skip host discovery. Some firewalls drop the probes Nmap uses to decide whether a host is up.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UDP scan is taking too long&lt;/strong&gt;&lt;br&gt;
Limit the ports with &lt;code&gt;-p&lt;/code&gt; instead of scanning large UDP ranges. UDP scans are slower and often return less clear feedback than TCP scans.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DNS lookups are slowing the scan&lt;/strong&gt;&lt;br&gt;
Add &lt;code&gt;-n&lt;/code&gt; to skip reverse DNS resolution, especially when scanning large networks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You are not seeing SYN scan behavior&lt;/strong&gt;&lt;br&gt;
Run the command with &lt;code&gt;sudo&lt;/code&gt; or specify &lt;code&gt;-sS&lt;/code&gt;. Without raw packet privileges, Nmap falls back to TCP connect scan.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;nmap&lt;/code&gt; command is one of the most useful Linux tools for host discovery, port scanning, and service detection. If you want a lighter tool for quick socket tests, see &lt;a href="https://linuxize.com/post/netcat-nc-command-with-examples/"&gt;&lt;code&gt;netcat&lt;/code&gt;&lt;/a&gt;
next.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/nmap-command/featured_hu_10e80ee9e63bb80f.webp" medium="image" type="image/webp" width="1200" height="675"/></item><item><title>Chattr Command in Linux (File Attributes)</title><link>https://linuxize.com/post/chattr-command-in-linux/</link><pubDate>Wed, 09 Dec 2020 20:11:34 +0100</pubDate><author>hello@linuxize.com (Linuxize)</author><guid>https://linuxize.com/post/chattr-command-in-linux/</guid><category>linux commands</category><description>How to use chattr and lsattr to set and view file attributes in Linux, including immutable files, append-only logs, and recursive protection.</description><content:encoded>&lt;p&gt;Many Linux filesystems support special file attributes that control how the kernel and system tools handle a file. You can mark a file as immutable so it cannot be changed or removed by mistake, or set a log file to append-only so new entries can be added without allowing old ones to be overwritten. These attributes work separately from standard &lt;a href="https://linuxize.com/post/chmod-command-in-linux/"&gt;permission bits&lt;/a&gt;
, and support depends on the filesystem.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;chattr&lt;/code&gt; command sets or removes supported attributes, and its companion &lt;code&gt;lsattr&lt;/code&gt; displays them. This guide explains the most useful flags with practical examples.&lt;/p&gt;
&lt;h2 id="chattr-syntax"&gt;&lt;code&gt;chattr&lt;/code&gt; Syntax &lt;a class="headline-link" href="#chattr-syntax" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;chattr&lt;/code&gt; command takes the following general form:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="txt"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;txt&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chattr [OPTIONS] [OPERATOR][ATTRIBUTES] FILE...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;[OPERATOR]&lt;/code&gt; is one of three symbols:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;+&lt;/code&gt; - Add the specified attributes to the existing ones.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-&lt;/code&gt; - Remove the specified attributes from the existing ones.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;=&lt;/code&gt; - Set the specified attributes as the only attributes, replacing all others.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The operator is followed by one or more &lt;code&gt;[ATTRIBUTES]&lt;/code&gt; flags. The most useful flags are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;i&lt;/code&gt; - &lt;strong&gt;Immutable&lt;/strong&gt;. The file cannot be modified, deleted, renamed, or linked to. Only root or a process with the required capability can set or clear this flag.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;a&lt;/code&gt; - &lt;strong&gt;Append only&lt;/strong&gt;. The file can only be opened in append mode for writing. Existing content cannot be overwritten or truncated. Only root or a process with the required capability can set or clear this flag.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;A&lt;/code&gt; - &lt;strong&gt;No atime updates&lt;/strong&gt;. The kernel will not update the access time (atime) when the file is read.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;d&lt;/code&gt; - &lt;strong&gt;No dump&lt;/strong&gt;. The file is skipped by the &lt;code&gt;dump&lt;/code&gt; backup program.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;e&lt;/code&gt; - &lt;strong&gt;Extents&lt;/strong&gt;. The file uses extents for mapping blocks on disk. This flag may appear in &lt;code&gt;lsattr&lt;/code&gt; output, but it cannot be removed with &lt;code&gt;chattr&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;s&lt;/code&gt; - &lt;strong&gt;Secure deletion&lt;/strong&gt;. This flag is documented by &lt;code&gt;chattr&lt;/code&gt;, but current ext2, ext3, and ext4 kernels do not honor it.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;S&lt;/code&gt; - &lt;strong&gt;Synchronous updates&lt;/strong&gt;. Changes to the file are written to disk immediately.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;j&lt;/code&gt; - &lt;strong&gt;Data journaling&lt;/strong&gt;. File data is written to the ext3 or ext4 journal before being written to the file itself.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;u&lt;/code&gt; - &lt;strong&gt;Undeletable&lt;/strong&gt;. This flag is documented by &lt;code&gt;chattr&lt;/code&gt;, but current ext2, ext3, and ext4 kernels do not honor it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the full list, run &lt;code&gt;man chattr&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The most commonly used option is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-R&lt;/code&gt; - Apply attribute changes recursively to directories and their contents.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By default, file attributes are not preserved when copying a file with commands like &lt;a href="https://linuxize.com/post/cp-command-in-linux/"&gt;&lt;code&gt;cp&lt;/code&gt;&lt;/a&gt;
or &lt;a href="https://linuxize.com/post/how-to-use-rsync-for-local-and-remote-data-transfer-and-synchronization/"&gt;&lt;code&gt;rsync&lt;/code&gt;&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id="viewing-attributes-with-lsattr"&gt;Viewing Attributes with &lt;code&gt;lsattr&lt;/code&gt; &lt;a class="headline-link" href="#viewing-attributes-with-lsattr" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before changing attributes, you need to see what is already set. The &lt;code&gt;lsattr&lt;/code&gt; command shows the current attribute flags for one or more files:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lsattr todo.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;--------------e----- todo.txt&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Each position in the output corresponds to an attribute flag. In this case only the &lt;code&gt;e&lt;/code&gt; (extents) flag is set, which is the default on ext4 filesystems.&lt;/p&gt;
&lt;p&gt;If you prefer descriptive names instead of single-letter flags, use &lt;code&gt;-l&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lsattr -l todo.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You can also pass a directory to &lt;code&gt;lsattr&lt;/code&gt; to see the attributes of every file inside it. This is helpful when auditing a configuration directory like &lt;code&gt;/etc/&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lsattr /etc/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;By default this skips hidden files. Add &lt;code&gt;-a&lt;/code&gt; to include dot files in the listing:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lsattr -a /etc/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you want to see the attributes of the directory itself rather than its contents, use &lt;code&gt;-d&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lsattr -d /etc/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;For a full recursive listing of a directory tree, use &lt;code&gt;-R&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lsattr -R /etc/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="making-a-file-immutable"&gt;Making a File Immutable &lt;a class="headline-link" href="#making-a-file-immutable" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One of the most common uses of &lt;code&gt;chattr&lt;/code&gt; is making a file immutable so it cannot be modified, deleted, or renamed.&lt;/p&gt;
&lt;p&gt;Create a test file and set the immutable flag with &lt;code&gt;+i&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;touch ~/demo.txt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chattr +i ~/demo.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;We use &lt;a href="https://linuxize.com/post/sudo-command-in-linux/"&gt;sudo&lt;/a&gt;
because changing the immutable flag requires elevated privileges.&lt;/p&gt;
&lt;p&gt;Verify the change:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lsattr ~/demo.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;----i---------e----- /home/user/demo.txt&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;i&lt;/code&gt; flag now appears in the output. If you try to remove the file, the operation will fail:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm ~/demo.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;rm: cannot remove &amp;#39;/home/user/demo.txt&amp;#39;: Operation not permitted&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To remove the immutable flag when you need to edit or delete the file again:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chattr -i ~/demo.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;After clearing the flag, you can modify or remove the file normally.&lt;/p&gt;
&lt;h2 id="setting-append-only-mode"&gt;Setting Append-Only Mode &lt;a class="headline-link" href="#setting-append-only-mode" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;a&lt;/code&gt; (append-only) attribute is useful for log files. It allows new data to be appended but prevents existing content from being overwritten or truncated.&lt;/p&gt;
&lt;p&gt;Create a test file and enable append-only mode:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;touch /tmp/app.log
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chattr +a /tmp/app.log&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;After setting this flag, you can still append to the file:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;new entry&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee -a /tmp/app.log&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;But attempting to overwrite it will fail:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;overwrite&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sudo tee /tmp/app.log&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;tee: /tmp/app.log: Operation not permitted&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This restriction applies to new write attempts. As the &lt;code&gt;chattr&lt;/code&gt; manual notes, existing open file descriptors are not affected retroactively.&lt;/p&gt;
&lt;p&gt;To remove the append-only flag:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chattr -a /tmp/app.log&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="combining-multiple-attributes"&gt;Combining Multiple Attributes &lt;a class="headline-link" href="#combining-multiple-attributes" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can set or remove multiple attributes in a single command. For example, to make a file immutable and disable atime updates:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chattr +iA todo.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Verify:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lsattr todo.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="output"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"&gt;&lt;/path&gt;
&lt;polyline points="14 2 14 8 20 8"&gt;&lt;/polyline&gt;
&lt;/svg&gt;&lt;span class="px-2 py-0.5 rounded text-xs font-medium bg-gray-200 text-gray-700 dark:bg-slate-600 dark:text-slate-300"&gt;output&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-output" data-lang="output"&gt;----i------A--e----- todo.txt&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To remove both at once:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chattr -iA todo.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id="using-the--operator"&gt;Using the &lt;code&gt;=&lt;/code&gt; Operator &lt;a class="headline-link" href="#using-the--operator" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;=&lt;/code&gt; operator replaces the current user-settable attributes with exactly the ones you specify. For example, to leave a file with only the &lt;code&gt;A&lt;/code&gt; flag set:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo &lt;span class="nv"&gt;chattr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;A todo.txt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This clears other changeable flags such as &lt;code&gt;i&lt;/code&gt; or &lt;code&gt;a&lt;/code&gt; and keeps &lt;code&gt;A&lt;/code&gt;. Filesystem-managed flags such as &lt;code&gt;e&lt;/code&gt; may still appear in &lt;code&gt;lsattr&lt;/code&gt; output.&lt;/p&gt;
&lt;h2 id="applying-attributes-recursively"&gt;Applying Attributes Recursively &lt;a class="headline-link" href="#applying-attributes-recursively" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;-R&lt;/code&gt; flag applies attribute changes to a directory and everything inside it. Start with a test directory before you use it on system paths:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir -p ~/demo-config/subdir
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;touch ~/demo-config/app.conf ~/demo-config/subdir/site.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chattr -R +i ~/demo-config/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Every file and subdirectory under &lt;code&gt;~/demo-config/&lt;/code&gt; is now immutable. To reverse it:&lt;/p&gt;
&lt;div class="code-block relative my-4 rounded-lg overflow-hidden border border-gray-200 dark:border-slate-700" data-lang="bash" data-prompt="$"&gt;
&lt;div class="code-header flex items-center justify-between px-4 py-2 bg-gray-50 dark:bg-slate-800/80 border-b border-gray-200 dark:border-slate-700"&gt;
&lt;div class="flex items-center gap-2"&gt;&lt;svg class="w-4 h-4 text-gray-500 dark:text-slate-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;
&lt;polyline points="4 17 10 11 4 5"&gt;&lt;/polyline&gt;
&lt;line x1="12" y1="19" x2="20" y2="19"&gt;&lt;/line&gt;
&lt;/svg&gt;
&lt;span class="text-sm text-gray-600 dark:text-slate-400 font-medium"&gt;Terminal&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chattr -R -i ~/demo-config/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class="note callout callout-warning"&gt;
&lt;div class="callout-header"&gt;&lt;svg role="img" aria-hidden="true" class="callout-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"&gt;
&lt;path d="M10 20C4.477 20 0 15.523 0 10S4.477 0 10 0s10 4.477 10 10-4.477 10-10 10zm0-2c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm-.5-5h1c.276 0 .5.224.5.5v1c0 .276-.224.5-.5.5h-1c-.276 0-.5-.224-.5-.5v-1c0-.276.224-.5.5-.5zm0-8h1c.276 0 .5.224.5.5V8l-.5 3-1 .5L9 8V5.5c0-.276.224-.5.5-.5z"&gt;&lt;/path&gt;
&lt;/svg&gt;
&lt;span class="callout-title"&gt;Warning&lt;/span&gt;&lt;/div&gt;
&lt;div class="callout-body"&gt;Be careful with recursive immutable flags. If you apply them to a system directory such as &lt;code&gt;/etc/nginx/&lt;/code&gt;, package managers and configuration tools will fail to update files there. Remove the flag before running updates.&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference &lt;a class="headline-link" href="#quick-reference" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;View attributes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lsattr file&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;View attributes recursively&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lsattr -R /path/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Make file immutable&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo chattr +i file&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remove immutable flag&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo chattr -i file&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Set append-only&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo chattr +a file&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remove append-only&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo chattr -a file&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Disable atime updates&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo chattr +A file&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skip dump backups&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo chattr +d file&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apply recursively&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo chattr -R +i /dir/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Set exact attributes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo chattr =A file&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="troubleshooting"&gt;Troubleshooting &lt;a class="headline-link" href="#troubleshooting" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;Operation not permitted&amp;rdquo; when setting attributes&lt;/strong&gt;&lt;br&gt;
Only root can set the &lt;code&gt;i&lt;/code&gt; and &lt;code&gt;a&lt;/code&gt; flags. Run the command with &lt;code&gt;sudo&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;Operation not permitted&amp;rdquo; even with sudo&lt;/strong&gt;&lt;br&gt;
Some filesystems and mount setups do not support these file attribute flags. Verify the filesystem type with &lt;code&gt;df -T /path/to/file&lt;/code&gt; and confirm it supports &lt;code&gt;chattr&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cannot delete or modify a file unexpectedly&lt;/strong&gt;&lt;br&gt;
Someone may have set the immutable flag. Check with &lt;code&gt;lsattr file&lt;/code&gt; and look for the &lt;code&gt;i&lt;/code&gt; flag. Remove it with &lt;code&gt;sudo chattr -i file&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Package updates fail with &amp;ldquo;Operation not permitted&amp;rdquo;&lt;/strong&gt;&lt;br&gt;
If you applied &lt;code&gt;chattr +i&lt;/code&gt; recursively to a system directory like &lt;code&gt;/etc/&lt;/code&gt;, package managers will not be able to update configuration files. Remove the flag with &lt;code&gt;sudo chattr -R -i /etc/directory/&lt;/code&gt; before running updates.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="headline-link" href="#conclusion" aria-hidden="true"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;chattr&lt;/code&gt; and &lt;code&gt;lsattr&lt;/code&gt; commands give you filesystem-level control over how files can be modified, deleted, or backed up. For related file permission management, see the &lt;a href="https://linuxize.com/post/chmod-command-in-linux/"&gt;&lt;code&gt;chmod&lt;/code&gt;&lt;/a&gt;
and &lt;a href="https://linuxize.com/post/linux-chown-command/"&gt;&lt;code&gt;chown&lt;/code&gt;&lt;/a&gt;
guides.&lt;/p&gt;</content:encoded><media:content url="https://linuxize.com/post/chattr-command-in-linux/featured_hu_65dd83e83db54a3c.webp" medium="image" type="image/webp" width="1200" height="675"/></item></channel></rss>