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.
filewont execute but./filewill 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-thisvsrm ./-who-uses-filenames-like-this– n.st Aug 04 '17 at 16:02