<aside>
📌 The command ls -lid / /.. . /usr/bin sparc*
lists detailed information about the root (/) directory, its parent (the root again /.. ), the current directory(.), the /usr/bin
directory, and any entries in the current directory matching the pattern sparc*
.
For /usr/bin
, the '4' in the third column represents the number of hard links to this directory. Since the inode of the current directory (denoted by .
) and the inode of /usr/bin
are the same, it confirms that we are in the /usr/bin
directory.
To explain the 4 hard links:
.
), which counts as one link...
), which adds another link.These two links account for the minimum of 2 hard links that every directory has.
/usr/bin
, there are two additional subdirectories (sparcv7
and sparcv9
), each contributing one more hard link.We can identify these subdirectories because their file type starts with 'd' in the ls -l
output. Therefore, the remaining two hard links are from the subdirectories sparcv7
and sparcv9
.
</aside>
<aside>
📌 Based on the second line, we see that the number of hard links to the root directory (/
) is 35. Since the root directory has one self-referential link (.
) and one link from its parent directory (..
, which is itself), the remaining 33 links must correspond to subdirectories within the root directory. Therefore, /
has 33 subdirectories, assuming all links are directories and there are no symbolic links.
</aside>
<aside>
📌 Removing save-excursion
will cause the point (cursor) to move during the execution of the function line-number-at-pos
and not return to its original position, which can be confusing for the user. Removing save-restriction
means that any narrowing applied to the buffer will not be restored after the function runs, causing the user's view of the buffer to change unexpectedly when widen
is called. This alteration disrupts the user's context and buffer state.
save-excursion
: This ensures that after executing the block of code (including potential buffer movements), the cursor will return to its original position.save-restriction
: This ensures that any narrowing of the buffer is restored after executing the block, maintaining the user's original view.
</aside>#!/bin/sh
if [ "$#" -lt 2 ]; then
echo "Arguments are missing."
exit 1
fi
dir_to_copy_from="$1"
exit_status=0
for f in "$@"; do
if [ "$f" != "$dir_to_copy_from" ]; then
base=$(basename "$f") # gets the basename (i.e. C in A/B/C)
#base="${f##*/}" #
cp "$dir_to_copy_from/$base" "$f"
if [ "$?" -ne 0 ]; then
exit_status=1
fi
fi
done
exit $exit_status
<aside>
📌 ${f##*/}
extracts the basename from a full file path by removing everything up to and including the last slash (/
), leaving only the filename.
${f}
: This references the variable f
.##
: This is the longest match removal operator.*/
: This pattern matches everything up to and including the last slash (/
).Examples: Removing everything up to the last dot:
filename="archive.tar.gz"
extension="${filename##*.}"
echo "$extension" # Output: gz
Removing a prefix and then removing a suffix:
file="backup-2021-12-01.tar.gz"
no_prefix="${file##backup-}"
no_suffix="${no_prefix%%.tar.gz}"
echo "$no_suffix" # Output: 2021-12-01
</aside>
The instructor answer:
#!/bin/bash
status=ok
first=yes
for arg in "$@"; do # "$@" is a list of the command line args, each quoted to take care of whitespace
if [[ $first == yes ]]; then
# Skip the first argument
first=no
else
base=$(basename "$arg") # gets the basename (i.e. C in A/B/C)
if ! cp "$1/$base" "$arg"; then
status=notok
fi
fi
done
if [[ $status == ok ]]; then
exit 0
else
exit 1
fi
<aside>
📌 The first make
call failed due to a circular dependency involving prog.h
and prog
. Specifically, prog.h
depends on prog
, but prog
also depends on prog.h
through prog.o
. When make
tried to generate prog.h
by running ./prog <prog.in.h >prog.h
, it failed because prog
was not built yet. Despite the failure, prog.h
was touched or created, updating its timestamp. On the second make
call, make
considered prog.h
up-to-date because its timestamp was newer than its dependencies (prog.in.h
and prog
), and proceeded to compile prog.o
and link it to create prog
. The initial problem diagnosis was incorrect because it overlooked the circular dependency and the implications of make
's timestamp-based dependency tracking.