Is there any subtle difference between:
file
and
./file
as a relative path?
Is there any subtle difference between:
file
and
./file
as a relative path?
When used as a command name in a shell or in the exec*p()
libc functions, file
would look-up file
in $PATH
(or for a shell, possibly invoke the built-in version, or function by that name), while ./file
would run the one the current directory.
It's not that ./
triggers a special behaviour, it's just that if the command name doesn't contain any /
, it does a $PATH
lookup. ./cmd
is the most obvious way to give a path to cmd
that contains a /
.
The ./
prefix is also commonly used to make sure a file name doesn't start with a problematic character for some commands.
For instance:
rm ./-f
removes -f
, while rm -f
would call rm
with the -f
option (rm -- -f
would also work). Or:
cat ./-
awk '{print $1}' ./a==b.txt
where --
wouldn't help.
You find that as rm ./*
or awk ... ./*
in scripts where you don't know if the expansion of *
would yield problematic characters.
Yes. Several.
As mentioned in another answer, the exec*p()
family of library functions use whether the name contains a slash character as a test for whether path searching should be performed.
Programs can of course do their own path searches outwith the C library. They might be searching for things other than to execute them. Or they might want slightly different behaviour to that of the C library functions, which has some little-known surprises to those not aware of what the POSIX standard mandates. So they implement their own searching code. Usually they will follow the conventions of the C library, and if the name contains a slash character they will just use the name as-is.
Shells that have CDPATH
or cdpath
mechanisms perform this sort of search, and have this behaviour. Here is the TENEX C shell:
~> set cdpath=(/usr /) ~> cd ./etc ./etc: No such file or directory. ~> cd etc /etc /etc>
One of the ways of making sure that a filename that begins with a minus sign is not taken to be a command-line option is to prefix it with ./
. For examples:
rm ./-rf
is a filename, and rm -rf
is a command-line option.find ./-name wibble
is scanning two directory trees and finding everything; whereas find -name wibble
is scanning one directory tree and applying a pattern match.Sometimes the syntax of the command is defined such that something is only a filename at all if it begins with a full stop. Otherwise it is something else. In a way, this is a generalization of the minus sign as an option character convention.
With Dan Bernstein's multilog
from daemontools, Bruce Guenter's multilog
from daemontools-encore, the djbwares multilog
, and Laurent Bercot's s6-log
from s6, the command-line arguments are a logging script where the first letter of each argument indicates what kind of script command it is. To denote a log directory, one has to give a command string argument that starts with a slash or a full stop character. multilog ./t ./u
means log to two directories; whereas multilog t ./u
means log to one directory and prepend timestamps.
file
will search in your PATH
for the file.
./file
will ignore the PATH
and search in the current directory.
file
wont execute but./file
will however I don't think that is your question. – jesse_b Aug 04 '17 at 15:56./
when the file you're referring to would otherwise be misunderstood as a commandline argument, such as inrm -who-uses-filenames-like-this
vsrm ./-who-uses-filenames-like-this
– n.st Aug 04 '17 at 16:02