CogniSkill · Linux Foundations for IT Professionals
Content review copy. This does not replace the site theme. For SC-300, this preview shows additions; the existing teaching is retained on import.
This course teaches filesystem context, commands, permissions and diagnostic evidence through a small local lab. The final project is a runbook for a service that cannot read a configuration file. You will distinguish what the evidence proves from what it merely suggests, and propose a narrow repair with a verification plan. You will not practise by changing a production service or granting broad access to its files.
Use a Linux terminal with a normal user account and a new practice directory. A local virtual machine or a Linux environment approved by your organization is suitable. A macOS terminal shares many shell concepts, but its utilities and permission features are not identical to Linux. Windows PowerShell is a different shell. These examples assume Bash and ordinary Linux command-line utilities.
Four chapters, with practical work
- Know where commands act
- Understand permissions before proposing a repair
- Collect diagnostic evidence without mixing conclusions into it
- Build a service-access investigation runbook
Applied capability and learning route
Diagnose file-access failures from identity, directory traversal and service context.
Follow the lessons in order: establish the model, trace the supplied evidence, attempt the case, compare the worked solution, and complete the changed-condition project. The target is intermediate reasoning within this stated scope, not mastery of the entire profession or product. If a prerequisite is unfamiliar, pause and use the linked foundational teaching before attempting the project.
All teaching, explained answers and core synthetic practice are free. Some operational labs require separately available software, a licensed test tenant or an authorized lab; offline completion does not claim hands-on product proficiency.
How to complete this course
Study the worked examples, attempt the exercises before opening solutions, and submit your own project notes. Completion records are self-reported; practical competence requires the stated verification.
Know where commands act
A shell is an interpreter, not the whole operating system
The terminal displays a shell session. The shell reads command text, expands certain expressions, starts commands and connects input and output. A command might be built into the shell or be an executable file. pwd reports your working directory; it does not tell you the directory used by a service that started earlier under a different account.
Run these inspection commands:
printf 'Shell variable: %s\n' "$SHELL"
pwd
id
command -v bash
command -v printf
Record the working directory and your effective user and group identities. $SHELL commonly describes the configured login shell; it does not by itself prove which interpreter is executing a particular script. command -v shows how the shell resolves a name. A shell function, alias or executable path can influence what actually runs. Do not assume that copying a short command name guarantees the same behavior on every machine.
id establishes useful context for access reasoning. A service account may have different groups and a different environment. A successful read in your terminal cannot prove that the service can read the same file.
Build a bounded practice directory
Choose a directory where you are allowed to create practice files. The following commands create a unique lab directory and print its absolute path:
lab_dir=$(mktemp -d "${TMPDIR:-/tmp}/ck-linux.XXXXXX")
printf 'Practice directory: %s\n' "$lab_dir"
mkdir -p "$lab_dir/config" "$lab_dir/logs"
printf 'endpoint=example.invalid\nmode=read-only\n' > "$lab_dir/config/agent.conf"
printf 'INFO agent started\nERROR config unreadable\n' > "$lab_dir/logs/agent.log"
ls -ld "$lab_dir" "$lab_dir/config" "$lab_dir/logs"
Keep the printed path. mktemp chooses a unique name, which avoids reusing a directory that may already contain important files. All writes in this lab are limited to that directory. The endpoint is a reserved example name; no network connection is needed.
The shell variable exists only in the current shell session unless you export it. A new terminal will not necessarily know lab_dir. This is why a troubleshooting note should include the absolute path rather than saying “read the config in my current folder.”
Relative paths depend on working directory
cd "$lab_dir"
pwd
cat config/agent.conf
cat "$lab_dir/config/agent.conf"
cd "$lab_dir/logs"
pwd
cat ../config/agent.conf
All three reads should show the same two configuration lines. config/agent.conf is a relative path interpreted from the current working directory. $lab_dir/config/agent.conf becomes an absolute path when the variable holds the path printed earlier. .. refers to the parent directory of the current path.
Now predict the result of cat config/agent.conf while still inside the logs directory. It should fail because that relative path points at logs/config/agent.conf, which the lab did not create. This is a path-resolution failure, not a reason to grant more permissions.
A path can also refer through a symbolic link. The displayed name and the underlying target may differ. In a real case, inspect the path's components and link targets before asserting which file the process opened. A service working directory, container mount or chroot can make its view different from your interactive shell's view.
File names are data, including their spaces
printf 'training note\n' > "$lab_dir/config/review notes.txt"
cat "$lab_dir/config/review notes.txt"
The quoted path is one argument. Without the quotes, shell word splitting can turn it into separate arguments, causing a command to inspect the wrong paths or fail unexpectedly. Quoting protects argument boundaries; it does not prove that the path is safe or authorized.
Do not build a cleanup command until you can explain exactly which directory it targets. This course deliberately leaves cleanup as an explicit review task. Deleting a whole directory is a state-changing operation; a convenient wildcard does not establish ownership of every matching file.
Evidence exercise
Write down the path used by the successful read, your working directory, your user identity and the two lines returned. Then record the deliberate relative-path failure. Your explanation should identify the changed context without treating the error as a mysterious Linux behavior. A good incident note lets another person repeat the observation under the same context.
Reasoning model
File access depends on the effective identity and every relevant directory boundary, not just the final file mode. Directory execute permission permits traversal; file read permission permits reading content. A service can run as a different user from the administrator’s shell. Broad permission changes may hide a diagnosis while exposing unrelated data. Start with read-only inspection and the least change consistent with the intended access model.
Official reference for further study
Understand permissions before proposing a repair
Ordinary mode bits describe three identity classes
For a regular file, the basic read, write and execute bits apply to owner, group and other identities. A long listing such as -rw-r----- describes a regular file whose owner can read and write, whose group can read, and whose other identities have no basic permissions. The displayed owner and group determine which class may apply to the process.
Inspect the lab file:
ls -l "$lab_dir/config/agent.conf"
stat -c 'mode=%a owner=%U group=%G path=%n' "$lab_dir/config/agent.conf"
id
stat prints the chosen format explicitly. Record the actual mode rather than assuming a tutorial's default. File creation permissions can be influenced by the process's creation mode and umask. A file that was readable in one lab may not have the same mode in another environment.
The basic identity classes are not an additive checklist in which a process always combines every visible bit. The ordinary owner/group/other selection rules matter. Extended ACLs and privileged capabilities can affect effective access too. Inspect those mechanisms when present; a nine-character permission display may not describe the entire policy.
Directory execute permission means traversal
For a directory, read permission lets a process list names; execute/search permission lets it traverse the directory and resolve entries. Write permission relates to modifying directory entries, often in combination with search permission. These meanings differ from executing a regular program file.
A readable configuration file behind an unsearchable parent directory can still be inaccessible. To reason about /srv/agent/config/agent.conf, inspect access to /, /srv, /srv/agent, /srv/agent/config and the file itself. If namei is installed, namei -l can help show path components. If it is unavailable, inspect each known parent with ls -ld and state the limitation.
Do not fix a path traversal issue by making every file executable. Execute permission on a data file is unrelated to the directory search permission the process needs.
Practise a reversible owner-mode change
The following exercise changes only the lab file you created:
before_mode=$(stat -c '%a' "$lab_dir/config/agent.conf")
printf 'Original mode: %s\n' "$before_mode"
chmod u-r "$lab_dir/config/agent.conf"
ls -l "$lab_dir/config/agent.conf"
cat "$lab_dir/config/agent.conf"
printf 'Read exit status: %s\n' "$?"
chmod "$before_mode" "$lab_dir/config/agent.conf"
cat "$lab_dir/config/agent.conf"
A normal, unprivileged owner should be unable to read the file after removing the owner-read bit, then should be able to read it again after restoration. If you are running as root or with an effective privilege that bypasses the relevant check, the expected failure may not occur. Record that difference and repeat in a suitable unprivileged environment. Do not call a privileged successful read proof that the ordinary service identity has access.
The restoration uses the mode captured before the change. A repair that guesses a mode without recording the starting point loses useful evidence and may overwrite an intentional policy. In a real environment, ownership, ACLs and other controls also need consideration.
Umask is a creation constraint
umask influences the permissions allowed when a process creates files or directories. It does not retroactively change every existing file. Inspect it with umask, and record the value in a reproducibility note if newly created modes matter to your test.
If you practise a different umask, do it in a subshell so that the parent shell's setting survives:
(
umask 077
printf 'private practice\n' > "$lab_dir/config/private-note.txt"
stat -c '%a %n' "$lab_dir/config/private-note.txt"
)
umask
For a normal newly created regular file with the usual non-executable creation request, the private note should have mode 600. The final umask runs in the parent shell and should show its original setting. State your observed result, including any environment-specific difference.
A restrictive creation policy can be useful, but it can also reveal a missing handoff contract: a collector creates a file privately while a separate reader expects group access. The solution needs an agreed owner/group and sharing boundary, not a universal recommendation to make files public.
Case reasoning
A service has effective user agent, supplemental group telemetry, and no elevated privileges. The configuration file is owned by root:telemetry with mode 640. Its parent directory is owned by root:root with mode 700. Under ordinary mode-bit reasoning, identify why the group-readable file remains inaccessible. The group has read permission on the file, but the service cannot traverse the parent directory.
A proposed repair of chmod 777 on the directory would grant write access broadly and exceeds the read-only objective. Propose a narrowly scoped directory access design for the intended service group, verify that unrelated identities remain excluded, and have the system owner approve the actual change. This is a reasoning exercise, not a command to run against /srv on your own machine.
Evidence laboratory — attempt before reading the solution
Fictional lab paths: /srv/team owned root:team with mode750; /srv/team/report.txt owned alice:team with mode640. User bob belongs to team. Service user agent belongs only to agents. No ACLs, special security modules or other exceptions are in this simplified case. Predict whether bob and agent can traverse the directory and read the file. An administrator reads it successfully as root and concludes the service should work; explain the missing comparison.
Official reference for further study
Collect diagnostic evidence without mixing conclusions into it
Exit status is a separate signal
Commands normally return an exit status. Zero usually communicates successful completion according to that command's contract. Non-zero values communicate other outcomes; their precise meanings depend on the command. A successful cat proves that this process could read the specified file at that moment. It does not prove that the file contents are semantically correct or that a service loaded them.
Capture status immediately, because a later command can replace $?:
cat "$lab_dir/config/agent.conf"
read_status=$?
printf 'Configuration read status: %s\n' "$read_status"
Do not run printf first and then record its status as the result of cat. This is an easy way to produce an apparently clean diagnostic report after the operation you intended to check failed.
Standard output and standard error have different purposes
cat "$lab_dir/config/missing.conf" > "$lab_dir/logs/read-output.txt" 2> "$lab_dir/logs/read-error.txt"
read_status=$?
printf 'Missing-file status: %s\n' "$read_status"
wc -c "$lab_dir/logs/read-output.txt" "$lab_dir/logs/read-error.txt"
cat "$lab_dir/logs/read-error.txt"
The output file should be empty, the error file should contain a diagnostic, and the status should be non-zero. The exact error wording can depend on locale and implementation, so do not make your parser depend on one English sentence unless that is a documented interface.
> writes standard output to a file; 2> writes standard error. In this exercise the destinations are deliberate new lab files. A redirection can overwrite an existing file before the command succeeds. Do not treat output redirection as a harmless inspection operation when its destination contains valuable evidence.
The absence of normal output does not mean a command found no problems. It may have failed. A dependable collector preserves both outcome and diagnostic context.
A pipeline can conceal an upstream failure
Bash normally reports the exit status of the last command in a pipeline. A later command can succeed after an earlier command fails. In a subshell, compare the default behavior with pipefail:
(
false | cat
default_status=$?
set -o pipefail
false | cat
pipe_status=$?
printf 'Default=%s pipefail=%s\n' "$default_status" "$pipe_status"
)
Expected statuses are default 0 and pipefail non-zero. false is a deliberate failure command; cat can successfully consume the empty stream. The subshell keeps the changed shell option out of your parent session.
pipefail is a useful error boundary, not a complete error-handling strategy. A command may use a non-zero status for a normal negative result. grep, for example, distinguishes a match from no match and from an error. Your script must interpret the command's contract rather than declare every non-zero value a system incident.
Search logs with explicit context
grep -n -- 'ERROR' "$lab_dir/logs/agent.log"
printf 'Search status: %s\n' "$?"
grep -n -- 'TIMEOUT' "$lab_dir/logs/agent.log"
printf 'No-match status: %s\n' "$?"
The first search should report line 2 and status 0. The second should find no matching line and return status 1. Searching a nonexistent file should produce an error and a different status. These are three different observations.
The log fixture has no timestamps, process identifiers or request identifiers. It cannot establish an incident timeline or prove which service attempt emitted the error. A real log source needs those fields and an understood time zone. Keep the collection time separate from the event time.
Process evidence is a snapshot
A command such as ps can show current process identities and arguments. It cannot establish every process that ran yesterday. On Linux systems with the relevant tools, inspect a small snapshot:
ps -eo pid,user,comm --sort=pid | head -n 6
Results vary by environment. A short snapshot is an exercise in reading the fields, not a required process list. A process may start or exit while you inspect it; record the collection time and do not describe the snapshot as a permanent state.
Process arguments can contain sensitive information. Prefer a narrow set of fields for routine reporting. Do not paste a full diagnostic bundle into a public project submission. The course uses fictional paths and data so you can demonstrate the skill without exposing a work system.
Worked laboratory solution
Compare your reasoning with the worked solution
bob’s team membership gives directory read/execute and file read through group bits, so the stated path permits reading. agent has no matching group: the directory’s other bits are0, preventing traversal, and the file’s other bits also grant nothing. Root’s success is not evidence for the service identity. Inspect the actual service account and approved access requirement. A narrowly scoped group/permission design may be appropriate, but changing everything recursively to777 would expose more than required and obscure ownership intent.
Official reference for further study
Workbook already downloaded
Build a service-access investigation runbook
Work from a fixed case
Use this fictional case as your final project. A service named agent-reader should read /srv/agent/config/agent.conf. Its startup record at 09:10 UTC says “configuration read failed.” The service runs as user agent, group agent, supplemental group telemetry. It does not run as root. The supplied path evidence is:
/srv root:root 755
/srv/agent root:root 700
/srv/agent/config root:telemetry 750
/srv/agent/config/agent.conf root:telemetry 640
Interactive administrator: root
Administrator cat result: success
Service working directory: /var/lib/agent
Configured path: /srv/agent/config/agent.conf
First separate facts from hypotheses. The configuration path is absolute, so the service's different working directory is not itself the cause. The administrator's successful read occurs under a different privilege context. The ordinary service identity cannot traverse /srv/agent under the supplied basic mode bits. This is a supported explanation of the access failure, assuming no additional ACL, security module, namespace or mount rule changes the effective decision.
Do not change the case to fit your favorite tool. A diagnosis should remain tied to the supplied identity and path components.
Write the investigation sequence
Your runbook should establish the service identity, configured path, event time and actual error first. Next inspect each path component's owner, group, mode and relevant additional controls. Compare the configured path with the file the administrator tested. Check for symlinks, mounts or service isolation when the visible paths differ.
Record observations before proposing a repair. A worksheet with columns for command/context, observation, supported inference and next question is suitable. “The administrator can read it” belongs in observation; “therefore the service can read it” is an unsupported inference.
Include a branch for a missing path and a branch for a denied path. If a service points to a nonexistent file, widening permissions on a different file will not repair the configured path. If the file is accessible but contains an unsupported format, a permission change will not repair parsing. These branches make the runbook useful beyond a single copied example.
Design the narrow repair
Propose a policy in which the intended service identity can traverse the necessary directories and read the configuration, while unrelated identities remain excluded. The exact implementation depends on the owner-approved sharing model: a service group, a suitable ACL, or another controlled delivery design may be appropriate. Do not run an invented ownership command against a real /srv path.
For the supplied case, making /srv/agent traversable by the intended telemetry group could address the identified basic-mode barrier if the owner adopts that group design. Document the previous owner/group/mode, the proposed values, who authorizes the change and how they will be restored if verification fails. A broad recursive change can alter unrelated files and exceeds the single read objective.
The runbook must include negative checks. Confirm that an unrelated unprivileged identity still cannot read the file. Confirm that the service cannot write the file if it only needs to read it. Confirm that the path tested is the path actually configured. A successful read is one part of acceptance, not the whole policy.
Verify the service outcome separately
After an approved repair in a real environment, repeat the read under the actual service identity or use the service's supported diagnostic path. Then verify the service's own load result. A readable file with invalid syntax can still cause startup failure. If a restart is needed, document its operational impact and owner-approved timing; a teaching example does not authorize it.
Record before/after event evidence and a rollback trigger. A repaired file-access test that leaves the service failing should reopen the investigation rather than be declared a success. A report should retain uncertainty about controls you did not inspect.
Independent challenge cases
Case A changes only the configured path to config/agent.conf, while keeping the working directory /var/lib/agent. Explain why the service now resolves a different path. Case B makes the parent directories accessible to the service but gives the file mode 600 owned by root. Explain why the original directory repair is insufficient. Case C keeps all ordinary access valid but the service log reports an invalid configuration key. Explain why additional permissions are not a supported repair.
For each case, state one discriminating observation that would help select the correct branch. Avoid collecting every possible command merely to make the runbook look long. Useful diagnostics reduce uncertainty in a defined decision.
Deliverable and self-review
Submit the lab observations, the fixed-case evidence map and your runbook with three challenge branches. Include an identity-aware acceptance matrix: service read allowed, service write denied, unrelated-user read denied, correct path confirmed, format accepted and service load confirmed. Mark any check that is a design proposal rather than an executed test.
Explain why root's successful read is weak evidence for ordinary service access; why directory execute permission differs from executable-file permission; why an empty pipeline output needs an exit-status check; and why the previous file mode must be captured before a practice change.
The course is complete when you can choose a command for a specific evidence question, predict its limits, and propose a narrow verified repair. The website's completion record tracks your study; it does not grant Linux administration authority or certify a production change.
References: https://www.gnu.org/software/coreutils/manual/html_node/File-permissions.html and https://www.gnu.org/software/bash/manual/html_node/Pipelines.html
Transfer project — changed conditions
Create the case only in an authorized disposable lab, or manually trace permission bits if you cannot create users. Add a readable file inside a nontraversable parent and explain the result. Add a service that writes output and distinguish read from write requirements. Submit the effective identity, each path component, expected permission decision and a proposed least-privilege correction with a negative test for an unrelated user.
Practical assessment rubric
Score each dimension 0–2: 0 = absent or materially incorrect; 1 = partly correct with an unresolved gap; 2 = correct, explicit and supported by the supplied evidence or an actual labeled lab result.
- Evidence/model: identify the relevant entities, inputs, assumptions and boundaries without inventing facts.
- Main result: derive the case-specific expected result, calculation or decision and show the intermediate reasoning.
- Failure/boundary: test the changed condition and explain why the original conclusion does or does not transfer.
- Verification: supply reproducible steps and expected/observed results; label manual traces as manual, not executed.
- Communication/safety: explain limitations, owners and a proportionate next action without unsafe or unnecessary access.
Target: at least 8/10, with no zero in main result or communication/safety. This is a local learning rubric, not an accredited certification standard. A written/manual solution demonstrates reasoning only; operational competence additionally requires the relevant executable lab in an authorized environment. The native multiple-choice score is separate and does not automatically grade this rubric.
Submission template
- My input/evidence and assumptions:
- Expected result with calculations or trace:
- My implementation/decision and justification:
- Changed-condition result:
- Observed execution, or explicitly labeled manual trace:
- Failure and recovery evidence:
- Unverified limitation and next action:
- Self-score with evidence for each dimension:
Remediation
If the main result is wrong, reconstruct the supplied case from the raw inputs before changing code or controls. If the boundary case is wrong, identify the assumption that changed and rerun both the original and changed case. If verification is missing, do not convert a prediction into an observed result. Reattempt the transfer task without copying the worked solution, then explain it to another person.
Official reference for further study
Assessment: explain your decisions
Choose an answer and write your reason before opening each explanation. Then explain why the other choices do not fit the evidence. Use missed questions to revisit the lesson. This knowledge check is only one part of assessment: complete the practical transfer project as well. It does not predict certification-exam success.
1. What does pwd show?
- Current working directory
- All passwords
- A privilege grant
Answer and explanation
Current working directory — pwd establishes path context.
2. Why quote a path with spaces?
- To change its permissions
- To pass it as one argument
- To encrypt it
Answer and explanation
To pass it as one argument — The shell otherwise separates words.
3. What is better than chmod 777 as a blanket fix?
- Disable all logging
- Always use root
- Inspect identity and grant required minimum access
Answer and explanation
Inspect identity and grant required minimum access — Access should match the intended task and identity.
4. Root can read a config, but the normal service user fails. What does the successful root read establish?
- That privileged process could read it in its context; service access still needs verification.
- The service must be using an incorrect password.
- Every service on the machine can read the config.
Answer and explanation
That privileged process could read it in its context; service access still needs verification. — Effective identities and privileges differ. Inspect every path component under the service context, plus relevant ACL or isolation controls. A privileged read is weak evidence for ordinary service access.
5. The file is group-readable, but its parent directory is inaccessible to the service group. Which basic permission is relevant to reaching the file?
- World-write access on all parent directories.
- Directory search/execute access along the path.
- Execute permission on the configuration file.
Answer and explanation
Directory search/execute access along the path. — Directory search permission is needed to traverse the path. Making a data file executable does not solve a parent traversal barrier; broad write access exceeds the read objective.
6. In Bash, false | cat returns status 0 under the default pipeline rule. Why?
- The false command was silently corrected.
- The pipeline proves both commands succeeded.
- The default pipeline status comes from the final command; an upstream failure can be hidden.
Answer and explanation
The default pipeline status comes from the final command; an upstream failure can be hidden. — cat can successfully consume an empty stream after false fails. A deliberate pipefail boundary can surface the upstream failure, but each command status still needs interpretation under its own contract.
7. Can bob read the file under the supplied simplified model?
- Yes, through team group traversal and read permissions.
- No, because bob is not the owner.
- Yes only if every path is777.
Answer and explanation
Yes, through team group traversal and read permissions. — Group permissions can authorize access. Ownership is not the only applicable permission class.
8. Why does root’s successful read not verify the service?
- Root changes the file name automatically.
- The service has a different effective identity and permissions.
- All users have identical access.
Answer and explanation
The service has a different effective identity and permissions. — Testing as an administrator can bypass the boundary that fails for the service account.
9. What is wrong with a blanket recursive777 fix?
- It is the only way to permit group read.
- It guarantees service correctness forever.
- It grants broad access beyond the stated requirement and masks the intended boundary.
Answer and explanation
It grants broad access beyond the stated requirement and masks the intended boundary. — Least-privilege diagnosis should target the required identity/path. Broad permissions add exposure without proving the application works.
Use the explained questions above for offline practice. A scored attempt requires the course assessment on CogniSkill.ca.