Using subshells frivolously
In a comment you expressed concern about using subshells frivolously.
Often there's a tradeoff between using a subshell or writing more complex code to avoid.
There's an overhead of subshells so it's a good practice to avoid them,
when the alternative is simple enough.
An important factor is if the script will be used in a loop or not.
One-off uses of subshell won't be noticeable,
but that can change when called in a nested loop.
For getting the absolute path of another directory,
I think it's a fine tradeoff to use a subshell,
because it's very simple to write,
and the alternative is complex and error prone,
that is, computing the same in native Bash,
especially the processing of symbolic links.
I think you did right to separate the cases of the current directory and a different directory, and not using a subshell in the first one, since it's unnecessary.
Aside from the (cd ...)
, there are other subshells in this code that can be avoided, see the next sections.
Consider $PWD
instead of pwd -P
If you don't have a very specific need for the effect of pwd -P
,
consider using simply $PWD
.
It's not exactly the same thing with respect to symbolic links,
but it does give you an absolute path that might be good enough for your intents and purposes.
Consider cmd ...
instead of echo "$(cmd ...)"
Instead of:
echo "$(pwd -P)/$(ls -rt | tail -n 1)"
You could eliminate one subshell and the echo with the equivalent:
ls -t "$(pwd -P)"/* | head -n 1
Avoiding duplication
As another answer pointed out,
there is duplicate logic in the implementation of the cases of the current directory and another directory.
A simple way to avoid the duplication is a recursive call to the same function, that is (cd "$1" && last_file)
.
I prefer this over the solution offered in that answer,
because this avoids an unnecessary subshell in the case of the current directory.
Error handling
The script doesn't handle errors.
When the specified directory doesn't exist,
it would be better to return a failure explicitly,
otherwise the output might be misleading.
Alternative implementation
Putting the above suggestions together, also assuming set -u
is in effect, as another answer suggested:
last_file() {
if [[ "${1+x}" ]]
then
[ -d "$1" ] || return 1
(cd "$1" && last_file)
else
ls -t "$PWD"/* | head -n 1
fi
}
last_download() { last_file ~/Downloads; }
\$\endgroup\$