Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
Terminal, Shell, Console and Prompt: Telling Them Apart and the Right Setup for Each OS
The terminal emulator draws the window, the shell interprets the line you type, and the PTY in between carries keys and signals; they are separate programs, so you install and update them separately. We show with a real experiment which settings file bash, zsh and PowerShell read and when, and give a decision table for PowerShell 7.6 + Windows Terminal + WSL 2 on Windows and zsh on macOS, plus where the repo should live.
Being Fast from the Keyboard: Line Editing Shortcuts, History Search, Tab Completion and CLI Completions
Working with Ctrl-A/E/W/K/Y, Alt-. and Ctrl-R instead of the arrow keys brings most of your speed in the terminal; bash, zsh and PSReadLine share the same shortcut family. We show with a real experiment in three shells how history stores secrets, and cover the right history settings, .NET 10's dotnet completions script, ng completion and the fixes for two completion traps we hit in zsh.
Configuring zsh: .zshrc, Aliases, Functions, Plugins, the Prompt and Startup Time
A good .zshrc is written in a fixed order: history, completion, aliases and functions, plugins, and the prompt last; slowness usually comes not from a framework but from external commands that run on every start. With real measurements we cover when to pick an alias, a function or a script, installing zsh-autosuggestions and zsh-syntax-highlighting by hand, a Starship prompt showing the git branch and the .NET version, and a completion cache that took startup from 206 ms to 21 ms.
A Developer Terminal with PowerShell 7: the Object Pipeline, $PROFILE, PSReadLine and Equivalents for Bash Users
In PowerShell, .NET objects flow through the pipe instead of text, so the Bookstore API's JSON can be filtered and grouped directly with Invoke-RestMethod (prices arrive as doubles; convert to decimal for money). With real output we cover $PROFILE and modules, what the execution policy really protects, winget, a bash equivalents table, curl.exe, what 7.6 LTS brought and 7.4's support ending on 10 November 2026, plus encoding and CRLF pitfalls.
Modern CLI Tools: a Daily Workflow with fzf, ripgrep, fd, bat, eza, zoxide and jq
Because ripgrep and fd respect .gitignore, they find fewer but correct results than grep in the Bookstore repo, about 90 times faster; fzf is a picker you can put in front of any list. We cover installing the tools with brew, winget and apt (Ubuntu's fdfind/batcat names and old fzf), Ctrl-R/Ctrl-T integration, branch and test pickers, processing API, dotnet package list and npm ls output with jq, and why scripts shouldn't depend on these tools.
Terminal Multiplexing with tmux: Panes, Sessions and Surviving a Dropped SSH Connection
In tmux, shells run inside a background tmux server and your terminal is just a client; that's why a job outside tmux dies when SSH drops while a job inside tmux keeps going (shown with a real experiment). We cover sessions, windows and panes, prefix shortcuts, a development script that opens dotnet watch and ng serve with one command, copy mode, a minimal .tmux.conf that accounts for default changes between tmux 3.4 and 3.8, and the nested tmux and TERM pitfalls.