What does ../../ located within a file path means? [duplicate] - bash

This question already has answers here:
What is double dot(..) and single dot(.) in Linux?
(4 answers)
Closed 9 months ago.
I saw some shell scripts that cd into some file path that starts with an alias and have /../../ in between, for example:
$exampleroot/../../folder/subfolder/filename.zip
i understand that /../ means root path but what does this /../../ refer to? does it mean capturing all misc sub folders in between regardless of the folders name?
Thanks

.. means the parent directory, i.e. the one that contains $exampleroot. ../../ is therefore two levels up:
$ pwd
/tmp
$ mkdir -pv foo/bar
mkdir: created directory 'foo/bar'
$ cd foo/bar/
$ pwd
/tmp/foo/bar
$ cd ../..
$ pwd
/tmp

An example might help. Suppose $exampleroot is /one/two/three/four (and this is a directory). Then:
$exampleroot/.. is equivalent to /one/two/three
$exampleroot/../.. is /one/two
$exampleroot/../../folder is /one/two/folder
$exampleroot/../../folder/subfolder/filename.zip is /one/two/folder/subfolder/filename.zip
(Note: If /one/two/three/four is not a directory, then /one/two/three/four/.. is not a valid path. And there are some weird exceptions if there's something like a symbolic link in the path, because going up a level in the directory hierarchy is not the same as un-following a symbolic link.)

Related

Should I use the first and/or last slash in commands in bash? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 years ago.
Improve this question
What is the canonical way of using trailing and first slashes in Linux OS?
Which of these commands are the most canonical and preferred and unambiguous one should use in tutorials and script that are public?:
Let's say we want to tell the reader of our article to go into the "etc" folder in Ubuntu. What should we write as the command?
Here are the options I can think of:
cd etc
cd /etc
cd etc/
cd /etc/
So, which one is the less ambiguous and preferred way of telling that to our readers?
Not sure if there is a canonical version, but these are different commands:
cd etc <-- change directory to 'etc' only if 'etc' exists in the current working directory
cd /etc <-- change directory to the 'etc' directory in the root of the file system
cd etc/ <-- same as item 1. The trailing forward-slash makes it clear that this is a directory, but this isn't necessary since the 'cd' command provides ample context
cd /etc/ <-- same as item 2. The trailing forward-slash makes it clear that this is a directory, but this isn't necessary since the 'cd' command and leading forward slash provide ample context
As far as the trailing forward-slash goes, I don't think it's necessary unless you need to indicate that something is a directory when it's otherwise unclear. In most cases it's not necessary and looks awkward. As long as you're communicating what a command is/does, extra details aren't necessary.
Read documentation of GNU bash and download then study its source code (since it is free software), syscalls(2), chdir(2), path_resolution(7), credentials(7).
cd etc or cd etc/ are changing the current directory (of your bash process) to the etc directory in the current working directory.
cd /etc or cd /etc/ are changing the current directory (of your shell) to the /etc directory in the root directory . See inode(7), the stat(1) and ls(1) commands, the stat(2) system call.
You could prefer in your documentation, for readability, cd /etc/ or cd etc/ to remind your reader that /etc/ is an existing directory.
Notice the existence of the chroot(2) system call (used by the chroot(1) command) which could change the root directory (of your shell process). It is unusual to do so, and that system call can fail (like many others, see errno(3)...). In rare cases, you would use the chroot(1) command.
Also, consider changing your shell with the chsh(1) command. I prefer zsh (see file /etc/shells documented in shells(5)). You could try the es shell.

purpose of chdir with a single dot (cd .)

This might appear a noob question.
While working in bash, if we run cd ., it stays in the current folder.
I understand the functionality, however, I am not able to understand the rationale of this functionality?
What would be some practical ways to use this?
The primary use case I've seen for cd . is to test whether your file handle on the current directory is still valid.
If you're on a directory from a network share -- NFS, or the like -- it can be possible for directories to be remotely deleted, but for the local client to still believe they're accessible and in use.
cd . is a way to trigger an error if your handle on the current working directory is no longer valid.
This is the only "practical" case that came to my mind
$ cd .
cd: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
when your process has a current working directory referencing a directory that has been removed by another process.
That command has no functionality. But in a POSIX-compliant environment, if you add a -P option, then it has functionality: it resolves symlinks. So for example on a Mac, if you cd to a path with a symlink:
cd /System/Library/Frameworks/AppKit.framework/Versions/Current
...then do cd -P . ... you will point to:
/System/Library/Frameworks/AppKit.framework/Versions/C
. is a special file that represents the current directory.
There are plenty of things which make use of directories and it is sometimes useful to refer to the current directory.
Changing the directory to the current directory is not one of those.
A simple example where cd . fails:
mkdir my_error
cd my_error
rm -rf ../my_error
cd .
When the rm is embedded in a difficult script or can be done by some other cleanup process, is can be an useful check.
I use a build script which removes and recreates a directory.
The old directory disappears and new appears with new inode.
If, in one of my shells my $PWD is that reappeared directory and I notice
it became unusable (and I know it was recreated), I just
$ cd .
to get the (new) directory useable again and can continue my work there.

Script location execution

I've been working on a script but always with a fixed directory (/opt/mw/script).
I need to change that to be able to execute the script from any directory.
I think I will need to add a "." at the beginning of the line to be able to execute the script?
For example ./mw/script
Is this correct?
Thanks
You already can execute that script from any directory with that absolute file path. It's the relative file paths (that start with ./ or ../) that can only be executed from a specific directory.
You need to add the "." if the script is in the current directory (e.g. ./script), but it is optional if the script is already inside another directory (e.g. mw/script).
Also notice that if your script contains relative references to other files and directories, you may need to use this trick to properly refer to them from any directory.
For instance, consider the following script using absolute paths:
#!/bin/bash
# lists all files in this directory
ls /opt/mw
If it is converted to relative paths as follows:
#!/bin/bash
# lists all files in this directory
ls mw
Then this script will only work if you run it from its own directory (e.g. cd /opt/ && ./script).
But then you can generalize it like this:
#!/bin/bash
SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
# lists all files in this directory
ls $SCRIPT_DIR/mw
Now the script works even when executed from another directory.

Adding shortcut(soft-link) of a directory to global PATH so that it can be accessed from everywhere

I'm trying to put all my symlinks in one directory (I'll call this symlinks directory). I've exported the path of that directory and put it in my .bashrc file. The symlinks to executable applications are running fine but I'm having hard time making symlinks for my directory. This is what I tried.
ln -s ~/mydir/ m
where m is supposed to be my symlink to mydir directory.
This works only when I'm inside symlinks directory. Trying cd m or even just m didn't work from outside that directory. I get:-
bash: cd: m: No such file or directory
Okay, so I thought maybe the PATH doesn't recognize directory paths. So I tried creating a bash script.
#!/bin/sh
cd ~/mydir/
Tried this, m...permission denied. Okay I thought and did chmod +x m to that file. And when I run that script like m then nothing. I tried ./m, still nothing.
I'm close to losing my mind to do such a simple task.
PATH is used to look for commands and I think a command ought to be a file or a symlink to a file.
So, cd m doesn't work as here the command is "cd" (not m). The lookup for "m" does not happen in PATH.
Just m does not work as the "m" found in PATH is a link to a directory and not a file. You can try creating another "m" which points to a file and put it in a directory later in the PATH and it will be recognized when you run just m.
The script you created does work, except that the cd now happens in a new shell and is lost at the end of the script. You can check this by putting an ls after the cd in your script.
There are a few ways to achieve what you want to do.
One option is to use the CDPATH variable. This is the search path for the cd command. Check man bash for details but basically, all you need to do is add your symlinks directory to CDPATH.
export CDPATH=~/symlinks:$CDPATH
cd m ## will cd to linked directory
Alternatively, you can create aliases or functions and put it in your .bashrc or another file which you then source.
alias m="cd ~/mydir"
m() {
cd ~/mydir
}
And now you can just type m to cd to mydir

Create folder in same directory as shell script [duplicate]

This question already has answers here:
How do I get the directory where a Bash script is located from within the script itself?
(74 answers)
Closed 8 years ago.
I'm new to Shell Scripting:
I'm trying to create a script that asks for user input as to the folder name, finds the directory the script is being run from, and creates a folder within that same directory with a bunch of files (I can do that part)
My issue is I can't seem to figure out how to make the script find its current directory without explicitly spelling it out.
I want to be able to run it from anywhere and have it create the folder right next to it without the user having to path it from the home folder every time.
Could someone help with this?
You could try this one liner:
DIR="$( cd "$( dirname "$0" )" && pwd )
Will leave you with a $DIR variable that contains the full path to the current directory. See this answer for more information!
script_dir=$(dirname "$0")
$0 is the name of the running script, as entered on the command line (for example: ./bin/script)
If you want the full path:
script_dir=$(cd -P -- "$(dirname "$0")" && pwd -P)

Resources