Difference between path.normalize and path.resolve in Node.js - node.js

What is the difference (if any) between path.normalize(your_path) and path.resolve(your_path)?
I know path.resolve(...) can accept multiple arguments, but is the behavior with a single argument the same as calling path.normalize()?
EDIT: If they are supposed to behave the same way, I don't understand the purpose of exposing the path.normalize(...) function when you can simply pass the path into path.resolve(...) Or, maybe, it's for documentation purposes. For example, they say in the documentation for path.resolve(...):
... The resulting path is normalized, and ...
Exposing the path.normalize(...) makes it easier to explain what "normalized" means? I don't know.

path.normalize gets rid of the extra ., .., etc. in the path. path.resolve resolves a path into an absolute path. Example (my current working directory was /Users/mtilley/src/testing):
> path.normalize('../../src/../src/node')
'../../src/node'
> path.resolve('../../src/../src/node')
'/Users/mtilley/src/node'
In other words, path.normalize is "What is the shortest path I can take that will take me to the same place as the input", while path.resolve is "What is my destination if I take this path."
Note however that path.normalize() is much more context-independent than path.resolve(). Had path.normalize() been context-dependent (i.e. if it had taken into consideration the current working directory), the result in the example above would've been ../node, because that's the shortest path one could take from /Users/mtilley/src/testing to /Users/mtilley/src/node.
Ironically, this means that path.resolve() produces a relative path in absolute terms (you could execute it anywhere, and it would produce the same result), whereas path.normalize() produces an absolute path in relative terms (you must execute it in the path relative to which you want to calculate the absolute result).

From the docs:
Another way to think of resolve is as a sequence of cd commands in a shell.
Links to path.resolve and path.normalize in the documentation. I mostly don't want to just provide links in an answer but the Node.js docs are very decent.

Related

Why do we write dots (.) in path.resolve()?

The code shown below are examples used to explain path.resolve() on https://nodejs.org/api/path.html
path.resolve('/foo/bar', './baz');
// Returns: '/foo/bar/baz'
path.resolve('/foo/bar', '/tmp/file/');
// Returns: '/tmp/file'
path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif');
// If the current working directory is /home/myself/node,
// this returns '/home/myself/node/wwwroot/static_files/gif/image.gif'
I noticed that all dots are just omited.
./baz is converted to baz in the first example.
../gif/image.gif is converted to /gif/image.gif in the 3rd example.
Then, why bother writing these dots?
What would happen if these dots didn't exist in the two examples?
Thx!
The path.resolve() method is used to resolve a sequence of path-segments to an absolute path.
It works by processing the sequence of paths from right to left, prepending each of the paths until the absolute path is created. The resulting path is normalized and trailing slashes are removed as required.
If no path segments are given as parameters, then the absolute path of the current working directory is used.
The passed argument is a series of file paths that would be resolved together to form an absolute path.

Node Path Normalise trailing periods .. and

Can anyone explain to me why this holds true:
Normalize a string path, taking care of '..' and '.' parts.
When multiple slashes are found, they're replaced by a single one;
when the path contains a trailing slash, it is preserved. On Windows
backslashes are used.
Example:
path.normalize('/foo/bar//baz/asdf/quux/..')
// returns '/foo/bar/baz/asdf'
When I would expect it to return
'/foo/bar/baz/asdf/quux'
This is from the Node Documentation
http://nodejs.org/api/path.html#path_path_normalize_p
Edit
After running some test I know "why" this is happening, but do not understand the logic behind it.
Below are three examples with their input and output.
/foo/bar//baz/asdf/quux/.. /foo/bar//baz/asdf
/foo/bar//baz/asdf/quux/. /foo/bar//baz/asdf/quux
/foo/bar//baz/asdf/quux/ /foo/bar//baz/asdf/quux/
So for the original I can see that the double period ".." removed the final folder and the single period "." removes the trailing slash. I understand that when including files in parental folders you would prefix a path with ../ I am assuming that you can actually place this anywhere within a path, although there seems little point to me currently to be able to place it say mid path.
A double colon (..) means the parent directory as is standard in Linux. So, /foo/bar//baz/asdf/quux/.. basically selects the parent directory of /foo/bar//baz/asdf/quux

Compose string manipulation operations in shell script

I'm trying to remove the directory prefix from $soy:
a=${soy#*$PREFIX}
then changing slashes per dots:
b=${a//\//.}
the goal is to convert a file-path to a module path inside a program.
Anyways, is there any way to do this i one expression using composition?
This doesn't work :(
${${soy#*$PREFIX}//\//.}
According to this blog comment at Linux Journal, you can't do multiple operations in one expression.

How do I avoid storing redirections in a boost::filesystem::path?

I'm using Boost::Filesystem to traverse around directories in Linux.
Every time I need to re-define the path to be one directory back, I do something similar to this:
auto p = boost::filesystem::current_path();
p /= "../";
The problem is, that when I output 'p', it will show me the path with "../" still tacked on.
How do I get this evaluated each time I decide to go back a directory. I would like going back a directory to make the path shorter- instead of making the path longer and longer every time.
I thought one of these functions might do it, as they take a path by reference,
boost::filesystem::absolute(...)
boost::filesystem::canonical(...)
but after calling them and re-outputting 'p', the result still shows a "../";
path& make_preferred() does not work either.
canonical or absolute is the way to do it. Do you use the returned path? The given path is taken as a constant reference so it is not modified in place. From the boost manuals:
path canonical(const path& p, const path& base = current_path());
path canonical(const path& p, system::error_code& ec);
path canonical(const path& p, const path& base, system::error_code& ec);
Overview: Converts p, which must exist, to an absolute path that has
no symbolic link, dot, or dot-dot elements.

what does paper.path() with no arguments mean?

Im sure of paper.path("path string") .But some examples use path method with no arguments.
I looked into the docs paper.path, its saying the path string is optional, but it hasn't said what happens when there is no path string.
You're correct that it allows empty paths. The definition from W3C is:
svg-path:
wsp* moveto-drawto-command-groups? wsp*
allowing any amount of white space surrounding zero or one of the moveto/drawto command groups.
From that W3C documentation page:
Note that the BNF allows the path ā€˜dā€™ attribute to be empty. This is not an error, instead it disables rendering of the path.
In other words, it's a path with no elements in it. Without this, you'd probably have to have some kludge like m 0 0 if you wanted a path to do nothing.

Resources