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.
Related
For school, I have to switch between my top level directory which is git-basics-lab-online-web-sp-000 back to the sub directory I made which is called my-repository.
I was switching back and forth no problem using {cd} but when I tried to switch back to my-repository using
cd my-repository
my terminal is now saying
bash: cd: my-repository: No such file or directory
what did I do wrong?! How come it worked before but now it's giving me this message?
Perhaps we are missing more information. That is, if you moved correctly from one directory to another, there is no reason why it should disappear just like that.
Besides cd, there are other commands that will help you to know which directory you are in, and where you can go. I summarize them below:
Show the full path to the current directory:
pwd
List files and folders (except hidden ones):
ls
Enter the dir directory (assuming it exists where we are):
cd dir
Exit dir (see edit):
cd ..
Obviously each command has a number of options that increase its functionality. You can always access them with the man command (for example, man cd will show you the cd command help).
That is, once the terminal showed you the error you mention, you can run ls to verify, for example, if you typed the folder name wrong. Then you can also try pwd to confirm that you are where you think you are. And finally you can move with cd to where you think you are.
EDIT: As suggested by Roadowl, cd - and cd .. are not strictly the same thing (in the example I assume we go one directory at a time).
I will try to illustrate this with an example to show the difference.
Suppose we have the dirc folder inside dirb and this, in turn, inside dira ( dira/dirb/dirc ). Let us also suppose that we are in dira. To enter directly to dirc we would have to execute cd dirb/dirc. And this is where the difference is illustrated:
If we run cd .. we are going to be positioned in dirb.
If we run cd - we will go back to the dira directory we were in before running the command.
This error message simply means that the directory/file you specified could not be found at your current location. If you look to the left of where you are typing, your current directory should be displayed, something like /you/are/here/ >
You can type cd .. to navigate up one level (towards the root directory).
If you are sure the directory exists you are trying to cd into, then you probably just aren't currently in the right location, and you need to either cd .. or cd somewhereelse until you get there.
I'm currently going through this tutorial: https://learnpythonthehardway.org/book/appendix-a-cli/ex11.html Even after going over it, I couldn't figure out how to move a file up one directory.
I'm currently in testdirectory1.
I created a subdirectory subd3.
I successfully moved a file called testfile1copy.py into subd3 via mv file1copy.py subd3/
Now, how do I move that file back to testdirectory1?
mv subd3/file1copy.py .
. references the current directory. If $PWD is the full path of testdirectory1 (some shells will automatically set that variable for you), you could also do:
mv "$PWD/subd3/file1copy.py" "$PWD"
I feel like I'm missing something very basic so apologies if this question is obtuse. I've been struggling with this problem for as long as I've been using the bash shell.
Say I have a structure like this:
├──bin
├──command (executable)
This will execute:
$ bin/command
then I symlink bin/command to the project root
$ ln -s bin/command c
like so
├──c (symlink to bin/command)
├──bin
├──command (executable)
I can't do the following (errors with -bash: c: command not found)
$ c
I must do?
$ ./c
What's going on here? — is it possible to execute a command from the current directory without preceding it with ./ and also without using a system wide alias? It would be very convenient for distributed executables and utility scripts to give them one letter folder specific shortcuts on a per project basis.
It's not a matter of bash not allowing execution from the current directory, but rather, you haven't added the current directory to your list of directories to execute from.
export PATH=".:$PATH"
$ c
$
This can be a security risk, however, because if the directory contains files which you don't trust or know where they came from, a file existing in the currently directory could be confused with a system command.
For example, say the current directory is called "foo" and your colleague asks you to go into "foo" and set the permissions of "bar" to 755. As root, you run "chmod foo 755"
You assume chmod really is chmod, but if there is a file named chmod in the current directory and your colleague put it there, chmod is really a program he wrote and you are running it as root. Perhaps "chmod" resets the root password on the box or something else dangerous.
Therefore, the standard is to limit command executions which don't specify a directory to a set of explicitly trusted directories.
Beware that the accepted answer introduces a serious vulnerability!
You might add the current directory to your PATH but not at the beginning of it. That would be a very risky setting.
There are still possible vulnerabilities when the current directory is at the end but far less so this is what I would suggest:
PATH="$PATH":.
Here, the current directory is only searched after every directory already present in the PATH is explored so the risk to have an existing command overloaded by an hostile one is no more present. There is still a risk for an uninstalled command or a typo to be exploited, but it is much lower. Just make sure the dot is always at the end of the PATH when you add new directories in it.
You could add . to your PATH. (See kamituel's answer for details)
Also there is ~/.local/bin for user specific binaries on many distros.
What you can do is add the current dir (.) to the $PATH:
export PATH=.:$PATH
But this can pose a security issue, so be aware of that. See this ServerFault answer on why it's not so good idea, especially for the root account.
I have written a bash script which is dependent on current folder structure,
What should I do to make it runnable in any other folder(become portable)?
let me explain more: I want the script to delete all the files in current directory that the script is running,
or to delete all the files that are in the parent folder,
what is the solution?
cd "$(dirname "$0")"
Add this to the top of your script to have it cd to the directory the script is installed at. Then you can use relative paths and they'll be relative to the script dir and not the user's pwd.
If for whatever reason dirname isn't available, here's an equivalent statement that uses basename instead.
cd "${0%%/$(basename "$0")}"
Don't use absolute paths in your script.
we need more information to give you a proper answer...BUT some tips if you need to make it portable are to store any files that you need on a network share and simply make a new folder off of / such as /temporaryScriptFolder/ and mount the network share to that empty folder, allowing you easy access to any resources that are necessary.
How do I remove certain files from a different directory than $PWD using the bash shell script.
Looking at the documentation for rm, it appears that rm only works in $PWD.
Am I forced to use this method:
oDir=$PWD
cd directorytoremovefiles
rm files
cd oDir
rm certainly does work for deleting files in another directory.
Whatever gave you that idea from the man page, I certainly hope it's not this:
rm removes each specified file. By
default, it does not remove
directories.
The documentation you refer to, talks only about having write & execute permission to the directory you are deleting from.
So you only need:
rm directorytoremovefiles/files
As pointed out by YYC,
rm $DIR/files
rm will take any path, relative or absolute. If there is no slash at the beginning of directorytoremovefiles then it is a relative path and you may need to store PWD for later. However, you can do this with pushd and popd or a cd - once you're finished. Or, if you run the cd and rm commands in parens they will run in a subshell, like this: ( cd directory; rm files) then your working shell will not change directory.