Create partitions and filesystems in Linux

I haven’t played around much with commands to create partitions and filesystems in Linux. This is the reason I decided to put together this practical tutorial for myself and to share with the world. But, first I decided to take a little trip to Staten Island on the Ferry.

Create Partitions and Filesystems in Linux

To manage MBR and GPT Partition. Tools to use are:

  • fdisk → For MBR (older, BIOS-based systems, up to 2TB disks).
  • gdisk or parted → For GPT (modern, UEFI-based, larger disks).

fdisk example command:

sudo fdisk /dev/sdb        # open disk /dev/sdb
# inside fdisk:
  n   # create new partition
  p   # primary
  1   # partition number
      # accept default start
  +2G # size = 2GB
  w   # write changes

Example with GPT (parted):

sudo parted /dev/sdc
(parted) mklabel gpt               # create GPT partition table
(parted) mkpart primary ext4 1MiB 2GiB
(parted) mkpart primary linux-swap 2GiB 4GiB
(parted) print
(parted) quit

Create Filesystems with mkfs

Once the partition is created (e.g., /dev/sdb1), you can format it:

EXT filesystems (common in Linux). You can use either below:

sudo mkfs.ext2 /dev/sdb1
sudo mkfs.ext3 /dev/sdb2
sudo mkfs.ext4 /dev/sdb3

XFS (great for large files, modern distros):

sudo mkfs.xfs /dev/sdb4

VFAT (for USB sticks, cross-platform with Windows):

sudo mkfs.vfat -F 32 /dev/sdb5

exFAT (newer removable media, Windows/macOS support):

sudo mkfs.exfat /dev/sdb6

Handling Swap Partitions

Swap partitions extend RAM usage to disk:

sudo mkswap /dev/sdb7       # format as swap
sudo swapon /dev/sdb7       # enable swap
sudo swapoff /dev/sdb7      # disable swap

To make swap permanent → add to /etc/fstab:

/dev/sdb7 none swap sw 0 0

Basic Knowledge of Btrfs

Btrfs = “B-tree filesystem”, modern FS with advanced features:

  • Supports multi-device volumes (like RAID).
  • Compression built-in (zlib, zstd, lzo).
  • Subvolumes = lightweight partitions inside a filesystem.

Create Btrfs filesystem:

sudo mkfs.btrfs /dev/sdb1

Multi-device (RAID-like):

sudo mkfs.btrfs -m raid1 -d raid1 /dev/sdb1 /dev/sdb2

Mount with compression:

sudo mount -o compress=zstd /dev/sdb1 /mnt/btrfs

Create subvolumes:

sudo btrfs subvolume create /mnt/btrfs/data
sudo btrfs subvolume create /mnt/btrfs/logs

List subvolumes:

sudo btrfs subvolume list /mnt/btrfs

Real-life sysadmin workflow:

  1. Plug in new disk → lsblk or fdisk -l to detect.
  2. Partition with fdisk or parted.
  3. Format with mkfs.* or mkswap.
  4. Mount it (mount /dev/sdb1 /mnt/data).
  5. Add permanent entry in /etc/fstab.

How to find the filesystem type for a partition?

As a sysadmin you often need to check what filesystem type a partition is using.
There are several commands you can use in Linux:

lsblk -f (fastest, most common):

lsblk -f

Example output:

NAME   FSTYPE LABEL UUID                                 MOUNTPOINT
sda
├─sda1 ext4         1a2b3c4d-5678-90ef-ghij-klmnopqrst   /
├─sda2 swap         1234abcd-5678-90ef-ghij-klmnopqrst   [SWAP]
└─sda3 xfs          2233abcd-4455-6677-8899-aabbccddeeff /data

blkid (shows filesystem info directly):

sudo blkid /dev/sda1

Example output:

/dev/sda1: UUID="1a2b3c4d-5678" TYPE="ext4" PARTLABEL="primary"

file -s (reads filesystem signature):

sudo file -s /dev/sda1

Example output:

/dev/sda1: Linux rev 1.0 ext4 filesystem data, UUID=1a2b3c4d...

df -Th (check mounted partitions):

df -Th

Example output:

Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/sda1      ext4   50G   20G   27G  43% /
/dev/sda3      xfs   100G   10G   90G  10% /data

Looking at /etc/fstab (persistent mounts):

cat /etc/fstab

You might see something like:

UUID=1a2b3c4d-5678-90ef / ext4 defaults 0 1
UUID=2233abcd-4455-6677 /data xfs defaults 0 2

Consider supporting my work by purchasing one of my T-Shirt and/or coffee mugs designs. You can go to my shop here. You can contact me if you have any questions. Thank you!

Vim Cheatsheet for Real Sysadmin Work

I tend to forget about various Linux commands especially when working in vim. This is why I decide to create this Vim Cheatsheet and share it with the world. Remember, Vim = Vi Improved (vi + extra features like syntax highlighting, undo/redo, plugins, scripting).

In order to get inspiration I first had to brew a great cup of Latin America specialty coffee using my moka pot at home. Let’s get started!

Modes in Vim

  • Normal mode → navigation & commands (default)
  • Insert mode → editing text (i, a, o)
  • Visual mode → select text (v, V)
  • Command mode → type commands (:)

Basic File Operations

:w        " Save file
:q        " Quit
:q!       " Quit without saving
:wq       " Save and quit
:x        " Save and quit (same as :wq)
:saveas newfile.txt   " Save file with new name

Navigation

h   " Left
l   " Right
j   " Down
k   " Up
Ctrl + d   " Half-page down
Ctrl + u   " Half-page up
gg         " Go to beginning of file
G          " Go to end of file
:n         " Jump to line n (example: :42)

Insert & Edit

i   " Insert before cursor
a   " Append after cursor
o   " Open new line below
O   " Open new line above
r   " Replace single character
R   " Replace until Esc
u   " Undo last change
Ctrl + r   " Redo

Delete, Copy, Paste

x       " Delete character
dd      " Delete line
5dd     " Delete 5 lines
yy      " Yank (copy) line
5yy     " Yank 5 lines
p       " Paste below
P       " Paste above

Search & Replace

/word        " Search forward
?word        " Search backward
n            " Next match
N            " Previous match
:%s/foo/bar/g       " Replace all 'foo' with 'bar'
:10,20s/foo/bar/g   " Replace between lines 10 and 20

Visual Mode

v     " Select characters
V     " Select whole lines
Ctrl + v   " Block selection (columns)
y     " Yank (copy) selection
d     " Delete selection
p     " Paste after cursor

Multiple Files & Buffers

:e file.txt      " Open file
:bn              " Next buffer
:bp              " Previous buffer
:ls              " List buffers
:b 2             " Switch to buffer 2

Splits & Tabs

:split file.txt " Horizontal split
:vsplit file.txt " Vertical split
Ctrl + w + w " Switch between splits
:tabnew file.txt " Open in new tab
:tabn " Next tab
:tabp " Previous tab

Main Differences Between vi and vim

vi → the original, very minimal editor (1976).
vim → “Vi IMproved” with extra features.

Featurevivim
Syntax highlighting❌ No✅ Yes
Undo/Redo❌ Limited✅ Multiple levels
Plugins❌ No✅ Yes
Split windows❌ No✅ Yes
Visual selection❌ No✅ Yes
Command-line completion❌ No✅ Yes
Available today✅ Minimal, always present✅ Default on modern Linux

I hope this Vim Cheatsheet helps somebody out there. If you like to support me consider ordering one of my T-Shirts and/or coffee mug designs from my shop here.

Regular Expressions (regex) in Linux

Regular Expressions (regex) are one of the most powerful tools for Linux sysadmins when searching logs, parsing configs, or cleaning up files. I found some practical real-life examples you’ll may use on your day-to-day SysAdmin routine.

First, I needed to brew a great cup of Catimor coffee variety for more inspiration. Below are some brief examples. grep is one of my favorite commands and T-Shirt!

Create Simple Regular Expressions

Regex are patterns used to match text. For example to find all lines in /var/log/auth.log containing the word failed you can run this command:

grep "Failed" /var/log/auth.log

Match “error” or “ERROR” (case-insensitive):

grep -i "error" /var/log/syslog

Match numbers in a text:

grep "[0-9]" users.txt

Basic vs Extended Regular Expressions in Linux

BRE (Basic Regex): default in grep

ERE (Extended Regex): use with egrep or grep -E

Example (basic regex) – \| needed for OR:

grep "error\|warning" /var/log/syslog

Example (extended regex):

grep -E "error|warning" /var/log/syslog

Special Characters, Character Classes, Quantifiers, Anchors

Special characters:

  • . → matches any character
  • * → zero or more
  • + → one or more (ERE only)
  • ? → zero or one (ERE only)

For example, matches “fail” followed by anything, then “root”):

grep -E "fail.*root" /var/log/auth.log

Character classes:

  • [0-9] → digits
  • [A-Za-z] → letters
  • [^abc] → not a, b, or c

Find lines starting with a digit:

grep "^[0-9]" file.txt

Find 3-digit numbers:

grep -E "[0-9]{3}" file.txt

Quantifiers:

  • {n} → exactly n times
  • {n,} → at least n times
  • {n,m} → between n and m times

Find lines ending with .com

grep "\.com$" domains.txt

Anchors:

  • ^ → start of line
  • $ → end of line

Regex Tools for Searching Filesystem/File Content

Find files with regex in names:

find /etc -regex ".*\.conf"

Search recursively in files:

grep -R "PermitRootLogin" /etc/ssh/

Regex for Delete, Change, Substitute (with sed)

Delete lines containing “DEBUG”:

sed -i '/DEBUG/d' /var/log/app.log

Replace “http” with “https”:

sed -i 's/http:/https:/g' index.html

Change only at line start (^ anchor):

sed -i 's/^root/ROOT/' /etc/passwd

More Linux Real-Life Sysadmin Examples

Find failed SSH logins:

    grep "Failed password" /var/log/auth.log

    Extract IPs from logs:

      grep -oE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" /var/log/auth.log

      Remove commented lines in config:

        sed -i '/^#/d' /etc/ssh/sshd_config

        Check which users have UID ≥ 1000 (normal users):

          awk -F: '$3 >= 1000 {print $1,$3}' /etc/passwd

          Regular Expressions (regex) Summary:

          • BRE vs ERE: basic needs escapes (\|), extended is simpler.
          • Special chars: . * + ? for flexible matching.
          • Classes: [0-9], [A-Za-z], [^x].
          • Anchors: ^ start, $ end.
          • Tools: grep, egrep, find -regex, sed, awk.

          Contact me if you have any questions. Also, consider shopping for one my T-Shirt and coffee mugs designs. Thanks!

          The Windows Search Engine is Currently Disabled

          One of my clients reached out to me with an error message “The Windows Search Engine is Currently Disabled” when they were trying to search in Outlook. I found this strange, but then found out another IT support tech was working on the users machine last week. They were working on resolving some disk space issues with a large Windows .edb file.

          After brewing a great cup of Catuai coffee from Latin America I decided to take on this one. To solve this one, you have to launch the services.msc console. You can start it in Windows > Windows logo > type services.msc > make sure you run it was Administrator.

          Locate the Windows Search service. You can double click or right click and go to Properties. Then go to the General tab and make the changes below:

          The service should be set to Automatic and then Start it. The services status should be Running.

          The Windows Search Engine is Currently Disabled. Is one of many issues I have experienced with Windows services in general.

          If you like my work and want to support me consider shopping one of my T-Shirts and/or coffee mugs designs. My shop is here. I create my own designs. Thanks!

          Process priorities in Linux in Brief

          Process priorities in Linux are critical for system administration and performance tuning. Linux controls process execution priority with the nice value (for user-space) and scheduling priority at the kernel level. These are some of the Linux commands I hardly touch to be honest. Hopefully this short tutorial on process priorities in Linux can help somebody out there.

          I was very happy to put this tutorial together after taking a walk in the Greenacre Park in New York City

          Default Linux Priority of a Job

          Every process has a nice value between -20 (highest priority) and 19 (lowest priority). The default nice value for processes started by normal users is 0.

          For example:

          ps -o pid,comm,nice -p $$

          This shows the PID, command, and nice value of your current shell ($$ is your shell PID).
          Output would be:

            PID COMMAND   NI
          12345 bash       0

          Run a Program with Higher or Lower Priority

          You can set the nice value at start with the nice command. Run a command with lower priority (nice value = 10):

          nice -n 10 gzip somefile.iso

          This makes gzip less demanding on CPU, letting other tasks run faster.

          • Run a command with higher priority (nice value = -5):
            Requires root privileges.
          • This speeds up tar compression by giving it more CPU time.

          Change the Priority of a Running Process

          Use renice to adjust the nice value of an already running process. Find the PID:

          ps -eo pid,comm,nice | grep nginx

          Change the nice value:

          sudo renice -n -10 -p 1321

          -n -10 → set nice value to -10 (higher priority).
          -p 1321 → apply to PID 1321.

          Check again:

          ps -o pid,comm,nice -p 1321

          Real-Life Admin Examples

          Example 1: Lower priority backup job.

          Run backup in background without slowing the server:

          nice -n 15 rsync -av /data /backup &
          

          Example 2: Speed up a critical web service.

          If a database (mysqld) is slow during high load:

          sudo renice -n -5 -p $(pidof mysqld)
          

          Example 3: Batch processing

          Give CPU-intensive video encoding lowest priority:

          nice -n 19 ffmpeg -i coolmovie.mp4 -c:v libx265 movie-hevc.mp4

          Summary

          • Default nice = 0
          • Higher nice = lower priority (19 is lowest).
          • Lower nice (negative) = higher priority (-20 is max).
          • nice → start process with a priority.
          • renice → change priority of a running process.

          Support my work by shopping a T-Shirt or coffee mug from my shop. Thanks!

          Managing Processes in Linux Commands

          I think managing processes in Linux is essential for Linux admins because process control equals server control. I decided to put together real-world commands and examples for future reference. First, I had to read some Specialty Coffee news to keep up to date about what’s going on in the coffee world.

          Run Jobs in the Foreground and Background

          By default, commands run in the foreground (blocking your terminal). For example, if you:

          ping yakahu.com

          You can’t type anything else until you stop it (Ctrl+C).

          Run in background ( & ):

          ping google.com > ping.log &

          Keeps running in the background. Output saved to ping.log

          List background jobs: (cool command)

          jobs

          Bring job to foreground:

          fg %1

          Send job to background:

          bg %1

          Signal a Program to Continue Running After Logout

          Normally, background jobs stop when you log out. Use nohup or disown.

          nohup ping google.com > ping.log 2>&1 &

          nohup = “no hangup,” keeps process alive after logout.

          2>&1 meaning:

          This one confuses people, but it’s simple.

          • 2 = standard error (stderr)
          • 1 = standard output (stdout)

          2>&1 means:

          “Send error messages to the same place as normal output.”

          So both outputs land in the same file: ping.log.

          OR if you already started a job, detach it:

          disown %1

          Real-life example: Run a backup overnight and disconnect from SSH.

          Monitor Active Processes

          ps (snapshot of processes):

          ps aux | less
          • a = all users
          • u = user-oriented format
          • x = processes without a terminal

          How to find a specific process? For example if you want to find all sshd running processes:

          ps aux | grep sshd

          top (live monitoring):

          top or htop(you may need to install it)
          • Press M → sort by memory
          • Press P → sort by CPU

          Exit with q.

          Sort processes by memory usage:

          ps aux --sort=-%mem | head -n 10
          

          Sort by CPU usage:

          ps aux --sort=-%cpu | head -n 10

          Send Signals to Processes

          Every process has a PID (process ID). Use kill to send signals. List signals:

          kill -l

          You should get a list similar to this:

          1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL
          5) SIGTRAP 6) SIGABRT 7) SIGEMT 8) SIGFPE
          9) SIGKILL 10) SIGBUS 11) SIGSEGV 12) SIGSYS
          13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGURG
          17) SIGSTOP 18) SIGTSTP 19) SIGCONT 20) SIGCHLD
          21) SIGTTIN 22) SIGTTOU 23) SIGIO 24) SIGXCPU
          25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH
          29) SIGINFO 30) SIGUSR1 31) SIGUSR2

          Most common signals:

          • SIGTERM (15) – ask process to exit gracefully
          • SIGKILL (9) – force kill immediately
          • SIGHUP (1) – reload configuration

          Gracefully stop Apache

          sudo kill -15 $(pidof apache2)

          Force kill a stuck process:

          sudo kill -9 1425

          (where 1234 is the PID from ps or top)

          Reload a service config without restarting:

          kill -HUP $(pidof syslogd)

          Linux Process Real-Life Scenarios

          Run a backup in the background overnight:

          nohup rsync -av /home /backup & disown

          Find and kill a runaway process eating 100% CPU:

          ps aux --sort=-%cpu | head -n 5
          kill -9 <PID>

          Monitor a webserver process in real time:

          top -p $(pidof nginx)

          If the above gives you an error, try this one instead:

          top -p $(pidof nginx | awk '{print $1}')

          Gracefully stop a database server:

          kill -15 $(pidof mysqld)

          How do i kill the Linux process i started with nohup?

          Processes started with nohup don’t automatically tie back to your shell’s job list, so jobs and fg/bg won’t see them.
          You’ll need to find the PID (process ID) and kill it manually. So, If you started:

          nohup ping google.com > ping.log 2>&1 &

          You can check with:

          ps aux | grep ping

          Example output:

          paco   3351  0.0  0.1  12345  678 ?   S   11:35   0:00 ping yakahu.com

          In this case 3351 is the PID.

          Or you can grab the Linux process more directly using:

          pidof ping

          Kill the Linux process

          Now that you know the process ID you can run:

          kill -15 3351

          -15 = SIGTERM (ask politely to stop).

          If it refuses. Run this one to force it!

          kill -9 3351

          -9 = SIGKILL (force kill).

          Verify the process is NOT running anymore: (Very important!):

          ps aux | grep ping

          or you can run:

          pidof ping

          If you want nohup to leave a PID file automatically (useful for cleanup), you can do:

          nohup ping yakahu.com > ping.log 2>&1 & echo $! > ping.pid

          Later you can kill it with:

          kill -15 $(cat ping.pid)

          Managing processes in Linux is crucial for daily work as a SysAdmin. If you like my brief tutorial consider supporting me by shopping one of my T-shirt and coffee mugs designs.

          Streams, Pipes, and Redirects in Linux

          Using Streams, Pipes, and Redirects in Linux is one of the usual daily tools for sysadmins. I used to be confused about these streams below, but now I’m starting to get more confident about it. I brewed a great Catimor coffee variety before putting together this simple tutorial.

          In Linux, every process has three default streams:

          • stdin (0) → standard input (keyboard, file, etc.)
          • stdout (1) → standard output (screen by default)
          • stderr (2) → standard error (screen by default)

          Redirect stdout ( > )

          Send output to a file (overwrite):

          ls > file_list.txt

          Now the output of ls is saved in file_list.txt.

          Append instead of overwrite:

          ls >> file_list.txt

          Redirect stderr ( 2> )

          Capture only errors:

          ls /fakepath 2> errors.txt

          Success output to the screen.
          Errors go to file errors.txt

          Redirect stdout and stderr together

          ls /etc /fakepath &> output.txt

          Redirect stdin ( < )

          Read from a file instead of typing: (Counts lines from file_list.txt.)

          wc -l < file_list.txt

          Pipe Output Between Commands ( | )

          Pipes connect stdout of one command to stdin of another. Some examples:

          Find number of running SSH processes:

          ps aux | grep ssh | wc -l

          View disk usage sorted by size:

          du -sh /var/* | sort -h

          Use Output of One Command as Arguments (Command Substitution)

          echo "Today is $(date)"

          Make a backup with today’s date:

          tar -czf backup-$(date +%F).tar.gz /etc

          Send Output to Both Screen and File ( tee )

          Save command output and still see it:

          ls -l /etc | tee etc_list.txt

          Append to file:

          ls -l /var | tee -a etc_list.txt

          Real-Life Scenarios for Sysadmins

          Debugging logs: (Watch logs live, filter “error”, save to file.)

          tail -f /var/log/syslog | grep error | tee errors.log

          Counting failed SSH login attempts:

          grep "Failed password" /var/log/auth.log | wc -l

          Find biggest files in /var and log them:

          du -ah /var | sort -rh | head -n 20 | tee top20files.txt

          Redirect errors only, while keeping output on screen:

          find / -name passwd 2> errors.log

          As usual, you can contact me if you have any questions. Also, support my work by shopping one of my T-Shirts or coffee mugs designs. Thanks!

          dd Command Tutorial for Sysadmins

          I think I only used the dd command less than ten times in my Linux sysadmin life. So, I decided to put together a simple dd Command Tutorial for Sysadmins. But, first I had to brew my favorite Caturra coffee variety and check out their Specialty Coffee news section.

          What is dd?

          dd is a low-level copying tool in Linux/UNIX. Unlike cp, it works at the raw byte level, meaning it can copy anything: files, partitions, disks, even memory.
          This makes it invaluable for backups, recovery, cloning, and troubleshooting.

          Basic Syntax

          dd if=<input> of=<output> [options]

          if= → input file/device (source)
          of= → output file/device (destination)
          bs= → block size (how much data to read/write at once)
          count= → how many blocks to copy
          status=progress → show progress bar (modern feature)

          Real-Life Use Cases for Sysadmins

          Backup the first 512 bytes (bootloader + partition table):

          sudo dd if=/dev/sda of=mbr_backup.img bs=512 count=1

          Restore it if corrupted:

          sudo dd if=mbr_backup.img of=/dev/sda bs=512 count=1

          Clone a Full Disk

          sudo dd if=/dev/sda of=/dev/sdb bs=4M status=progress

          Makes /dev/sdb a bootable copy of /dev/sda.

          Useful for migrations or duplicating lab servers.

          Create a Disk Image

          sudo dd if=/dev/sda of=disk_backup.img bs=4M status=progress

          Creates an image file (disk_backup.img) you can compress or transfer.

          Write an ISO to USB

          sudo dd if=ubuntu.iso of=/dev/sdb bs=4M status=progress oflag=sync

          Common method for creating bootable USB drives.

          Wipe a Disk Securely

          Overwrite a disk with zeros:

          sudo dd if=/dev/zero of=/dev/sdb bs=1M status=progress

          Overwrite with random data:

          sudo dd if=/dev/urandom of=/dev/sdb bs=1M status=progress

          Careful: This destroys all data on the target disk.

          Performance Testing (Disk Speed)

          Write test:

          dd if=/dev/zero of=testfile bs=1G count=1 oflag=dsync

          Read test:

          dd if=testfile of=/dev/null bs=1G count=1

          Partial File Copy (Skip & Limit)

          Copy the first 100MB of a file:

          dd if=bigfile.iso of=sample.iso bs=1M count=100

          Skip first 50MB and copy the next 100MB:

          dd if=bigfile.iso of=part.iso bs=1M skip=50 count=100

          Create Swap File

          sudo dd if=/dev/zero of=/swapfile bs=1M count=2048
          sudo chmod 600 /swapfile
          sudo mkswap /swapfile
          sudo swapon /swapfile

          Makes a 2GB swap file.

          Safety Tips

          Always double-check if= and of= before pressing Enter.

          Use lsblk or fdisk -l to confirm disk names.

          Practice with small files before using real disks.

          Quick Reference Cheatsheet

          • Backup MBR: dd if=/dev/sda of=mbr.img bs=512 count=1
          • Clone disk: dd if=/dev/sda of=/dev/sdb bs=4M status=progress
          • ISO → USB: dd if=linux.iso of=/dev/sdb bs=4M status=progress
          • Wipe disk: dd if=/dev/zero of=/dev/sdb bs=1M status=progress
          • Create swap: dd if=/dev/zero of=/swapfile bs=1M count=2048

          Contact me if you have any questions. If you like my work consider supporting me by shopping one of my coffee mugs and T-Shirt designs using my Shop here.

          Managing Users in macOS via Terminal

          macOS is UNIX-based, so you can use standard BSD commands like dscl (Directory Service Command Line) for managing users in macos and groups as well. The reason I found this useful is that you can remote using SSH to any mac and make this changes. You don’t need to rely on the GUI. Especially if you’re connecting from a different OS such as Windows or Linux.

          Some of these commands require sudo because they modify system accounts. Before I tested these I had to brew a nice Sidra coffee variety at home using my Moka pot.

          Check existing users

          dscl . list /Users

          Means the local directory (your Mac).
          This lists all user accounts (system + human).

          Add a new user

          Create a local user paco with a home directory.

          sudo sysadminctl -addUser paco -fullName "Paco Raban" -password "Secret123"

          Creates the user paco.
          fullName sets the display name.
          password sets the login password.
          Automatically creates /Users/paco.

          Another way with dscl (more manual way):

          sudo dscl . -create /Users/john
          sudo dscl . -create /Users/john UserShell /bin/bash
          sudo dscl . -create /Users/john RealName "John Doe"
          sudo dscl . -create /Users/john UniqueID 501
          sudo dscl . -create /Users/john PrimaryGroupID 20
          sudo dscl . -create /Users/john NFSHomeDirectory /Users/john
          sudo dscl . -passwd /Users/john Secret123
          sudo createhomedir -c -u john

          Note: UniqueID must be unique (start from 501 upward for normal users).

          Remove a user

          sudo sysadminctl -deleteUser paco

          This deletes the user and their home directory.

          Add a user to the admin group

          sudo dseditgroup -o edit -a paco -t user admin

          –a paco → add user paco.
          admin group → macOS admin privileges.

          Remove a user from a group

          sudo dseditgroup -o edit -d paco -t user admin

          List members of a group

          dscl . -read /Groups/admin GroupMembership

          If the Mac is joined to Active Directory (AD)

          • The local user commands stay the same, but:
            • You don’t create AD users with dscl; those come from the AD server.
            • Group membership changes must be done on the AD domain controller, unless you are adding an AD user to a local Mac group.
          • Example: Add an AD user to local admin group:
          sudo dseditgroup -o edit -a "ADDOMAIN\\paco" -t user admin

          You must use the AD short name and escape the backslash (\\).

          Managing Users in macOS using the Terminal

          This task is easier than what I expected. So useful to know some Terminal commands. Let me know what you think.

          Always contact me if you have any questions. Grab one of my designs in my shop if you like to support me. Thanks!

          10 practical Linux Text-filter examples

          Hola! I put together a mini Linux text-filter examples using a data.csv file. I have copy/paste it below for your reference.
          I’m going to use commands like cut, grep, awk, sort, uniq, head, tail, and wc.
          I’ll explain each example and you can run them on your Linux command line. But first, I needed to grab a good beer and get inspired.

          data.csv sample file: (you can copy/paste it into your terminal)

          Name,Age,Department,Salary
          Alice,30,HR,45000
          Bob,25,IT,50000
          Charlie,35,Finance,55000
          Diana,28,Marketing,47000
          Ethan,40,IT,60000
          Fiona,32,Finance,53000
          George,29,HR,46000
          Hannah,31,Marketing,48000

          Show only the names from the CSV

          cut -d',' -f1 data.csv

          -d',' → delimiter is a comma.
          -f1 → first field only.

          Show only employees in the IT department

          grep ",IT," data.csv

          Searches for lines containing ,IT, to avoid partial matches.

          Show employees earning more than 50,000

          awk -F',' '$4 > 50000' data.csv

          -F',' → set field separator to comma.
          $4 > 50000 → filter where Salary (field 4) is greater than 50,000.

          Sort employees by Salary (highest first)

          sort -t',' -k4 -nr data.csv

          -t',' → delimiter comma.
          -k4 → sort by 4th column (Salary).
          -n → numeric sort.
          -r → reverse order.

          Count how many employees are in each department

          cut -d',' -f3 data.csv | sort | uniq -c

          First cuts the Department column.
          Sorts it.
          uniq -c → shows counts.

          Show only the first 3 employees in the file

          head -n 3 data.csv

          Show the last 2 employees in the file

          tail -n 2 data.csv

          Find all employees with names starting with “A”

          grep "^A" data.csv

          ^A → regex meaning “starts with A”.

          Add $1000 to each employee’s salary (display only)

          awk -F',' '{if(NR==1){print $0} else {$4=$4+1000; OFS=","; print}}' data.csv

          Leaves the header row intact (NR==1).
          Adds 1000 to field 4 for all other rows.

          Count total employees in the file (excluding header)

          tail -n +2 data.csv | wc -l

          tail -n +2 → skip header.
          wc -l → line count.

          I hope these Linux text-filter examples are useful for you. If you like to support me please consider buying one of my T-Shirt or coffee mugs designs in my shop. Thanks!