Linux Commands Every Dev Should Know

beginner linux terminal commands shell

We don’t need to be Linux experts, but we do need to be comfortable on a server. Whether we’re SSH’d into a production box, debugging a Docker container, or setting up a VPS — these commands come up constantly.

File Navigation

pwd                   # where am I? prints current directory
ls                    # list files in current directory
ls -la                # show all files (hidden too), with permissions and sizes
ls -lh                # human-readable file sizes (KB, MB, GB)

cd /var/log           # go to an absolute path
cd ..                 # go up one directory
cd ~                  # go to home directory
cd -                  # go back to the previous directory

Reading Files

cat app.log           # dump entire file to terminal (fine for small files)
less app.log          # scroll through file (q to quit, / to search)
head -n 20 app.log    # first 20 lines
tail -n 50 app.log    # last 50 lines
tail -f app.log       # follow the file in real-time (great for watching logs)

tail -f is something we’ll use all the time in production. It keeps printing new lines as they’re added to the file.

File Manipulation

cp file.txt backup.txt        # copy a file
cp -r src/ src_backup/        # copy a directory recursively
mv old.txt new.txt            # rename or move a file
mkdir -p logs/2024/march      # create nested directories in one go
touch notes.txt               # create an empty file (or update timestamp)
rm file.txt                   # delete a file
rm -rf node_modules/          # delete directory and everything inside — BE CAREFUL

The -rf flag means “recursive” and “force” — it won’t ask for confirmation. One wrong rm -rf on a production server and we’re having a very bad day. Always double-check the path.

File Permissions

Every file has three permission groups: owner, group, and others. Each group can have read (r), write (w), and execute (x) permissions.

Permission String: -rwxr-xr--
type
-
file
owner
rwx
7 (4+2+1)
group
r-x
5 (4+0+1)
others
r--
4 (4+0+0)
r=4   w=2   x=1   →   add them up for octal notation
chmod 755 deploy.sh       # owner: rwx, group: r-x, others: r-x
chmod 644 config.json     # owner: rw-, group: r--, others: r--
chmod +x script.sh        # add execute permission for everyone

chown manish file.txt         # change file owner
chown manish:devs file.txt    # change owner and group

Common permission sets: 755 for scripts we want to run, 644 for config files, 600 for private keys (SSH keys, secrets).

Process Management

ps aux                    # list all running processes
ps aux | grep node        # find a specific process

top                       # real-time process viewer (q to quit)
htop                      # better version of top (install: apt install htop)

kill 1234                 # gracefully stop process with PID 1234
kill -9 1234              # force kill (last resort, no cleanup)

lsof -i :3000            # what's using port 3000?

When a port is “already in use,” lsof -i :PORT tells us exactly which process is hogging it. Then we can kill it.

Text Search and Piping

grep "error" app.log              # find lines containing "error"
grep -r "TODO" src/               # search recursively in a directory
grep -i "warning" app.log         # case-insensitive search
grep -n "error" app.log           # show line numbers

find . -name "*.log"              # find all .log files in current directory
find /var -name "*.conf" -type f  # find config files under /var

# Piping — send output of one command to another
ps aux | grep node | grep -v grep    # find node processes
cat app.log | sort | uniq -c | sort -rn  # count unique log lines

The | (pipe) is one of the most powerful tools in Linux. It chains commands together — the output of one becomes the input of the next.

Environment Variables

echo $PATH                        # print the PATH variable
echo $HOME                        # print home directory
export API_KEY="abc123"           # set a variable for current session
env                               # print all environment variables

# Make it permanent — add to shell config
echo 'export API_KEY="abc123"' >> ~/.bashrc
source ~/.bashrc                  # reload the config without restarting terminal

Networking

curl https://api.example.com/users    # make an HTTP request
curl -s https://example.com | head    # silent mode, show first few lines
wget https://example.com/file.zip     # download a file

ss -tlnp                              # list all listening TCP ports
# (older systems use: netstat -tlnp)

ping google.com                       # test if a host is reachable
nslookup example.com                  # look up DNS records

In simple language, we don’t need to memorize every flag — we need ls, cd, cat, grep, ps, kill, chmod, and curl to be comfortable on any server, and man <command> to look up everything else.