CertGrid CertGrid
Hands-on Lab·Linux Foundation Certified System Administrator

Files, directories and where things live

The commands in this guide are the ones you will type most and get wrong least - until a filename has a space in it, or a cp -r puts a directory somewhere you did not expect. This covers ls -l field by field, what stat knows that ls does not, the five file types, and the two shell behaviours - globbing and quoting - that make the difference between a command that works and one that half works.

Essential Commands Guide 5 of 38 Beginner

GNU coreutils. cp -T and --strip-components are GNU extensions and are what the exam images have. The globbing behaviour differs by SHELL rather than by distribution, and the login shell here is zsh.

Everything on this page runs on the one Ubuntu host.
Server NameIP AddressOSRolesCPURAMHDD
LFCS-A01192.168.0.70Ubuntu 26.04 LTSPrimary host - most guides run only here2 Core4 GB50 GB

This guide includes

Use this for the commands you will type most and get wrong quietly. This matters because cp -r changes meaning depending on whether the destination already exists - which is how a script that worked yesterday nests a directory inside itself.

Before you start

  1. What ls -l actually tells you

    One directory containing a file, two directories, a symlink and a hidden file.

    bash Example session
    mkdir -p ~/ess/files && cd ~/ess/files && printf 'one\ntwo\nthree\n' > report.txt && mkdir -p logs archive && ln -s report.txt current.txt && touch .hidden && lsarchivecurrent.txtlogsreport.txtcd ~/ess/files && ls -ltotal 12drwxrwxr-x 2 sysadmin sysadmin 4096 Aug 29 09:40 archivelrwxrwxrwx 1 sysadmin sysadmin   10 Aug 29 09:40 current.txt -> report.txtdrwxrwxr-x 2 sysadmin sysadmin 4096 Aug 29 09:40 logs-rw-rw-r-- 1 sysadmin sysadmin   14 Aug 29 09:40 report.txtcd ~/ess/files && ls -la --time-style=long-isototal 20drwxrwxr-x 4 sysadmin sysadmin 4096 2026-08-29 09:40 .drwxrwxr-x 3 sysadmin sysadmin 4096 2026-08-29 09:40 ..-rw-rw-r-- 1 sysadmin sysadmin    0 2026-08-29 09:40 .hiddendrwxrwxr-x 2 sysadmin sysadmin 4096 2026-08-29 09:40 archivelrwxrwxrwx 1 sysadmin sysadmin   10 2026-08-29 09:40 current.txt -> report.txtdrwxrwxr-x 2 sysadmin sysadmin 4096 2026-08-29 09:40 logs-rw-rw-r-- 1 sysadmin sysadmin   14 2026-08-29 09:40 report.txt

    Expected resultls omitting .hidden entirely; ls -l showing the symlink as current.txt -> report.txt; ls -la adding ., .. and the hidden file.

    Success conditionYou can read a directory listing field by field.

  2. The other flags worth having

    -d, -h, -F and -i.

    bash Example session
    cd ~/ess/files && ls -ldh logs; echo "---"; ls -1F; echo "---"; ls -i report.txtdrwxrwxr-x 2 sysadmin sysadmin 4.0K Aug 29 09:40 logs---archive/current.txt@logs/report.txt---789196 report.txt

    Expected result4.0K for the directory itself, then archive/, current.txt@, logs/ with type suffixes, then the inode number.

    Success conditionYou can list a directory without listing its contents.

  3. What stat knows that ls does not

    The same file, fully described.

    bash Example session
    cd ~/ess/files && stat report.txt  File: report.txt  size: 14        	Blocks: 8          IO Block: 4096   regular fileDevice: 252,0	Inode: 789196      Links: 1Access: (0664/-rw-rw-r--)  Uid: ( 1000/sysadmin)   Gid: ( 1000/sysadmin)Access: 2026-08-29 09:40:52.878729254 +0000Modify: 2026-08-29 09:40:52.878729254 +0000Change: 2026-08-29 09:40:52.878729254 +0000 Birth: 2026-08-29 09:40:52.878729254 +0000cd ~/ess/files && stat -c '%A %a %h %U:%G %s %y %n' report.txt logs current.txt-rw-rw-r-- 664 1 sysadmin:sysadmin 14 2026-08-29 09:40:52.878729254 +0000 report.txtdrwxrwxr-x 775 2 sysadmin:sysadmin 4096 2026-08-29 09:40:52.879729251 +0000 logslrwxrwxrwx 777 1 sysadmin:sysadmin 10 2026-08-29 09:40:52.880729247 +0000 current.txt

    Expected resultInode, blocks, device, the mode as both 0664 and -rw-rw-r--, and four timestamps - Access, Modify, Change and Birth.

    Success conditionYou can get any single fact about a file, scriptably.

  4. The five file types

    The first character of the mode, and what each one means.

    bash Example session
    cd ~/ess/files && for f in report.txt logs current.txt /dev/null /dev/sda; do printf '%-14s %s\n' "$(basename $f)" "$(stat -c '%F  mode=%A' $f)"; donereport.txt     regular file  mode=-rw-rw-r--logs           directory  mode=drwxrwxr-xcurrent.txt    symbolic link  mode=lrwxrwxrwxnull           character special file  mode=crw-rw-rw-sda            block special file  mode=brw-rw----mkdir -p ~/ess/files && cd ~/ess/files && printf 'one\ntwo\nthree\n' > report.txt && mkdir -p logs archive && ln -s report.txt current.txt && touch .hidden && lsarchivecurrent.txtlogsreport.txt

    Expected resultregular file, directory, symbolic link, character special file (/dev/null), block special file (/dev/sda) - and file identifying a gzip header and an ELF binary.

    Success conditionYou can tell what kind of thing you are looking at.

  5. cp, and the destination that changes the meaning

    The same cp -r command, run against a destination that does and does not already exist.

    Read the find output each time.

    bash Example session
    mkdir -p ~/ess/n/logs && cd ~/ess/n && printf 'x\n' > logs/report.txt && mkdir -p dest && cp -r logs dest && find dest | sortdestdest/logsdest/logs/report.txtcd ~/ess/n && cp -r logs dest && find dest | sort; echo "--- identical: the second copy MERGED into dest/logs, it did not nest"destdest/logsdest/logs/report.txt--- identical: the second copy MERGED into dest/logs, it did not nestcd ~/ess/n && rm -rf dest && cp -r logs dest && find dest | sort; echo "--- dest did NOT exist, so it BECAME the copy of logs"destdest/report.txtdest/second.txt--- dest did NOT exist, so it BECAME the copy of logs

    Expected resultWith dest existing: dest/logs/report.txt. Run again: identical - it merged. With dest absent: dest/report.txt - dest became the copy.

    Success conditionYou can predict where a recursive copy lands.

  6. So use -T when a script depends on it

    cp -T says "the destination is the thing itself", whether or not it exists.

    bash Example session
    cd ~/ess/n && rm -rf dest && mkdir dest && cp -rT logs dest && find dest | sort; echo "--- cp -T ignores whether dest exists and always means 'dest IS the copy'"destdest/report.txtdest/second.txt--- cp -T ignores whether dest exists and always means 'dest IS the copy'cd ~/ess/n && cp -rT logs dest && find dest | sort; echo "--- so -T is repeatable, which is what you want in a script"destdest/report.txtdest/second.txt--- so -T is repeatable, which is what you want in a script

    Expected resultdest/report.txt both times - the same result whether it is the first run or the fifth.

    Success conditionYou have a copy that is safe to repeat.

  7. Globbing, which the shell does and the command never sees

    The expansion happens before the command runs - and what happens when nothing matches depends on the shell.

    zsh Example session
    cd ~/ess/files && bash -c 'echo *.txt; echo "---"; echo *.nomatch; echo "---"; echo logs/*'current.txt---*.nomatch---logs/renamed.txt logs/report-backup.txt logs/report.txtcd ~/ess/files && bash -c 'ls -d [cm]*; echo "---"; ls -d ??????.bin 2>&1; echo "---"; shopt -s nullglob; echo "with nullglob: [$(echo *.nomatch)]"'current.txtmaybe.gz---random.bin---with nullglob: []cd ~/ess/files && echo *.nomatch 2>&1 | head -2; echo "--- zsh errors where bash passes the pattern through"zsh:2: no matches found: *.nomatch--- zsh errors where bash passes the pattern through

    Expected resultbash printing *.nomatch unchanged when nothing matches; nullglob making it empty; and zsh giving **no matches found: *.nomatch**.

    Success conditionYou know who expands your wildcards.

  8. Quoting, and the space in a filename

    One file called two words.txt, and the difference one pair of quotes makes.

    bash Example session
    cd ~/ess/files && touch 'two words.txt' && bash -c 'for f in *.txt; do printf "[%s]\n" "$f"; done'[current.txt][two words.txt]cd ~/ess/files && bash -c 'f="two words.txt"; ls -l $f 2>&1 | tail -2; echo "--- quoted:"; ls -l "$f"'ls: cannot access 'two': No such file or directoryls: cannot access 'words.txt': No such file or directory--- quoted:-rw-rw-r-- 1 sysadmin sysadmin 0 Aug 29 09:40 two words.txtcd ~/ess/files && bash -c 'v=world; echo "double: $v"; echo "escaped: \$v"'double: worldescaped: $v

    Expected resultUnquoted $f producing two errors - cannot access 'two' and cannot access 'words.txt' - and the quoted form working.

    Success conditionYou can handle filenames you did not choose.

  9. Removing things, and the two safeties

    rmdir, rm -r, and the file whose name looks like a flag.

    bash Example session
    cd ~/ess/files && ls; echo "--- rmdir only removes empty:"; rmdir dest 2>&1 | tail -1; rmdir archive/logs-copy 2>&1 | tail -1archivecurrent.txtdestlogsmaybe.gzprograndom.bintwo words.txt--- rmdir only removes empty:rmdir: failed to remove 'dest': Directory not emptyrmdir: failed to remove 'archive/logs-copy': Directory not emptycd ~/ess/files && rm -r dest && echo "dest gone" && ls -d dest 2>&1 | tail -1dest gonels: cannot access 'dest': No such file or directorycd ~/ess/files && touch -- -weird-name && ls -l -- -weird-name && rm -- -weird-name && echo "removed a file whose name starts with a dash"-rw-rw-r-- 1 sysadmin sysadmin 0 Aug 29 09:40 -weird-nameremoved a file whose name starts with a dash

    Expected resultrmdir: failed to remove 'dest': Directory not empty twice, then rm -r working, then a file called -weird-name created and removed.

    Success conditionYou can remove what you meant to remove.

Troubleshooting

Official sources