Skip to content
QA Knowledge Hub

Linux commands for testers

Updated 2026-11-13 · 10 min read

Thirty questions with practical answers, common mistakes and scenarios for testers preparing for interviews.

The following setup was run first. It creates fake logs and a local HTTP listener used by the port examples. Use only a disposable environment; it creates files and starts a background process. The setup produced no stdout. The ShopLite server ran separately on the Docker Desktop host at port 3001.

mkdir -p /tmp/qa-linux/logs
cd /tmp/qa-linux
printf '00:00 INFO start\n00:01 ERROR [payment] timeout\n00:02 WARN retry\n00:03 ERROR [payment] declined\n' > logs/app.log
printf '' > .fixture
cat > smoke.sh <<'SCRIPT'
#!/bin/sh
set -eu
cd /tmp/qa-linux
grep -q 'ERROR' logs/app.log
printf 'fixture check passed\n'
SCRIPT
python3 -m http.server 8123 --bind 127.0.0.1 >/tmp/fixture-http.log 2>&1 &

Files and navigation

1. How do you find the current directory?

A relative path is interpreted from the current directory. Check this before collecting a report or changing a file; a CI step may start somewhere different from your interactive shell.

pwd

Observed stdout:

/tmp/qa-linux

2. How do you navigate to a log directory?

Changing directory affects that shell. A later CI step may use a fresh shell, so specify its working directory explicitly instead of assuming the change persists.

cd logs
pwd

Observed stdout:

/tmp/qa-linux/logs

3. How do you list hidden and ordinary files?

The hidden marker file is included. Hidden files are not automatically secret, but do not open configuration indiscriminately when collecting evidence.

ls -a

Observed stdout:

.
..
.fixture
logs
smoke.sh

4. How do you inspect the start of a log?

The first lines can reveal startup configuration or the initial failure. A truncated excerpt is evidence about those lines, not the entire run.

head -n 2 logs/app.log

Observed stdout:

00:00 INFO start
00:01 ERROR [payment] timeout

5. How do you inspect the last few lines?

Use a bounded excerpt when attaching logs to a defect. Retain timestamps and enough context to identify the failing request.

tail -n 2 logs/app.log

Observed stdout:

00:02 WARN retry
00:03 ERROR [payment] declined

6. How do you follow a growing log?

Following keeps the command running as data arrives. This demonstration deliberately stops after two seconds; exit 124 comes from timeout, not a failed application. Rotation may require a different follow strategy.

timeout 2 tail -n 1 -f logs/app.log

Observed stdout:

00:03 ERROR [payment] declined

Searching and extracting evidence

7. How do you find error lines with line numbers?

Line numbers make the excerpt easier to locate in the original file. The search is case-sensitive here; do not assume it finds every spelling of an error.

grep -n 'ERROR' logs/app.log

Observed stdout:

2:00:01 ERROR [payment] timeout
4:00:03 ERROR [payment] declined

8. How do you search without case sensitivity?

This finds WARN as well as other case variants. Grep normally returns 0 for a match, 1 for no matches and a different status for errors, which matters in CI.

grep -in 'warn' logs/app.log

Observed stdout:

3:00:02 WARN retry

9. How do you search for a literal string?

Fixed-string matching avoids interpreting brackets as a regular expression. This is useful for a literal component label or request marker copied from a log.

grep -Fn '[payment]' logs/app.log

Observed stdout:

2:00:01 ERROR [payment] timeout
4:00:03 ERROR [payment] declined

10. How do you find log files recursively?

Quote the filename pattern so the shell does not expand it before find receives it. This filters paths; it does not search inside file contents.

find . -type f -name '*.log' | sort

Observed stdout:

./logs/app.log

11. How do you search within a known directory tree?

Recursive grep combines discovery and content search. Limit the root to the relevant logs so the result is useful and avoids unrelated sensitive files.

grep -rn 'ERROR' logs

Observed stdout:

logs/app.log:2:00:01 ERROR [payment] timeout
logs/app.log:4:00:03 ERROR [payment] declined

12. How do you print a selected line range?

The n option suppresses default printing and p prints the selected range. The original file is unchanged; prefer read-only extraction when gathering evidence.

sed -n '2,3p' logs/app.log

Observed stdout:

00:01 ERROR [payment] timeout
00:02 WARN retry

13. How do you replace text without editing the input?

This writes transformed output to stdout only. Do not relabel original evidence and then attach it as if it were the raw log.

sed 's/ERROR/FAIL/g' logs/app.log

Observed stdout:

00:00 INFO start
00:01 FAIL [payment] timeout
00:02 WARN retry
00:03 FAIL [payment] declined

14. How does awk extract fields?

Awk splits these lines on whitespace by default. That works for this fixture; it is not a reliable JSON parser or a full CSV parser.

awk '{print $2, $3}' logs/app.log

Observed stdout:

INFO start
ERROR [payment]
WARN retry
ERROR [payment]

15. How do you count error records?

Matching the severity field avoids counting the word ERROR embedded in a message. The result counts matching lines, not necessarily unique failed transactions.

awk '$2 == "ERROR" {n++} END {print n+0}' logs/app.log

Observed stdout:

2

16. How do you sort and count repeated values?

Uniq groups adjacent equal lines, so sorting comes first here. The totals describe severity records in this tiny file and do not measure defect severity or user impact.

awk '{print $2}' logs/app.log | sort | uniq -c

Observed stdout:

      2 ERROR
      1 INFO
      1 WARN

Files, permissions and processes

17. How do you copy a file and verify its contents?

Cmp produced no output and succeeded for identical files. The final message was printed after that check; in a script, ensure the message depends on the comparison succeeding.

cp logs/app.log copied.log
cmp logs/app.log copied.log && printf 'copy identical\n'

Observed stdout:

copy identical

18. How do you rename a captured report?

Renaming within this fixture moves the path rather than duplicating the contents. Check destination names before using a move operation on evidence that must be retained.

mv copied.log archived.log
test -f archived.log && printf 'archive exists\n'

Observed stdout:

archive exists

19. How do you make a script executable?

Mode 700 grants the owner read, write and execute access and grants none to group or others. The stat format shown is GNU syntax, verified in the Linux container; macOS stat uses different options.

chmod 700 smoke.sh
stat -c '%a %n' smoke.sh

Observed stdout:

700 smoke.sh

20. How do you run a small shell smoke check?

The script checks for an expected error record and prints a result. It is deliberately a fixture check, not proof that ShopLite is healthy or that a release can ship.

./smoke.sh

Observed stdout:

fixture check passed

21. How do you inspect a specific process?

The container’s initial process is shown without listing unrelated host processes. A live process is not proof that the service is responsive.

ps -p 1 -o pid,comm

Observed stdout:

    PID COMMAND
      1 sleep

22. How do you identify a listening TCP port?

The options select listening TCP sockets with numeric addresses. This fixture listener is inside the Linux container; the host’s port 3001 is in a different network namespace.

ss -ltn sport = :8123

Observed stdout:

State  Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0      5          127.0.0.1:8123      0.0.0.0:*

23. How do you map a listening port to a process?

Lsof adds process information, subject to permissions. Avoid killing a process simply because it uses a port; establish ownership and what else depends on it first.

lsof -nP -iTCP:8123 -sTCP:LISTEN

Observed stdout:

COMMAND PID USER FD   TYPE  DEVICE SIZE/OFF NODE NAME
python3  27 root 3u  IPv4 1355777      0t0  TCP 127.0.0.1:8123 (LISTEN)

Networking and shell scenarios

24. How do you make an HTTP check with curl?

This requests the local ShopLite instance through Docker Desktop’s host alias and prints the response status. It does not check the response body; a 200 response can still contain a business defect.

curl -sS -o /dev/null -w '%{http_code}\n' http://host.docker.internal:3001/api/products

Observed stdout:

200

25. How do you make HTTP errors fail a shell check?

The deliberate missing route produces curl exit 22. In this demonstration the next command prints that captured status; in a CI script, preserve or explicitly propagate it instead of returning success from the final printf.

curl -fsS -o /dev/null http://host.docker.internal:3001/api/not-a-route
printf 'exit=%s\n' "$?"

Observed stdout and stderr:

exit=22
curl: (22) The requested URL returned error: 404

26. How do you check SSH options without logging in?

G prints effective client configuration instead of opening a connection. The destination is deliberately invalid, and no authentication was attempted. Real use also requires approved access and host-key verification.

ssh -G -F /dev/null [email protected] 2>/dev/null | awk '$1 == "hostname" || $1 == "user" || $1 == "port"'

Observed stdout:

user qa
hostname example.invalid
port 22

27. How do you inspect a cron entry safely?

This installs, lists and removes a user crontab only in the disposable container. This container uses dcron, whose delete option is -d; other implementations commonly use -r, so check your local manual. The five fields mean minute 0, hour 2, every day/month/weekday in the scheduler’s timezone. The scheduled execution was not observed; real cron environments also have a limited PATH.

printf '0 2 * * * /tmp/qa-linux/smoke.sh >> /tmp/qa-linux/cron.log 2>&1\n' > demo.cron
crontab demo.cron
crontab -l
crontab -d

Observed stdout:

0 2 * * * /tmp/qa-linux/smoke.sh >> /tmp/qa-linux/cron.log 2>&1

28. Why should shell variables be quoted?

Quoting keeps the filename with a space as one argument. Unquoted expansion can split it or expand wildcard characters, leading to misleading test artifacts.

report='run results.txt'
printf 'passed\n' > "$report"
cat "$report"

Observed stdout:

passed

29. How can a pipe hide a failing command?

Without pipefail, a successful final command can hide a previous failure in a Bash pipeline. This demonstration prints the pipeline status; a real gate must exit with it rather than merely logging it.

bash -c 'set -o pipefail; false | cat; printf "pipeline=%s\n" "$?"'

Observed stdout:

pipeline=1

30. How do you stop a process you started for a test?

Capture the PID when launching the disposable process and send TERM to that process. The wait status reflects termination by the signal. Do not use a broad name-based kill on a shared machine.

sleep 60 &
pid=$!
kill -TERM "$pid"
wait "$pid"
printf 'wait=%s\n' "$?"

Observed stdout:

wait=143

Likely follow-up: Does a listening port prove readiness? No. Follow it with an HTTP check and an assertion about the response that matters to users.

Practise it

Use ShopLite locally and collect a bounded, sanitized failure excerpt for a report. Explain what an HTTP status check proves and what still needs a business assertion.

Quick answers

Were these commands run on Linux?

Yes, in a disposable Alpine container with Bash and the required tools installed.

Are process identifiers and output identical on every machine?

No. These are captured fixture results; process IDs, versions, spacing and socket details can differ.

Sources

Want a project you can show in interviews?

The portfolio project kit walks you through testing a deliberately buggy app with Selenium or Playwright and API tests, then explaining it. The app itself is free.