What does 'cd -' stand for? - linux

In a bash shell script today I noticed the below command at the end of the script. I know what is cd but I am unaware of the significance of a dash after it.
cd -
What does this mean? Google naively truncates the - so I am unable to find its answer.

If a single dash is specified as the argument, it will be replaced by the value of OLDPWD.
The OLDPWD is set by cd command and it is the previous working directory.

cd - returns to the directory you were previously.
For instance:
marcelo#marcelo:~$ cd /opt
marcelo#marcelo:/opt$ cd /usr/bin
marcelo#marcelo:/usr/bin$ cd -
/opt
marcelo#marcelo:/opt$
I was in /opt, changed to /usr/bin, and then went back to /opt with cd -

cd - brings you back to the last directory.
$ cd ~/Desktop
$ pwd
/Users/daknok/Desktop
$ cd /
$ pwd
/
$ cd -
$ pwd
/Users/daknok/Desktop

cd - returns to the previous directory you were in.
Say I'm in /usr/ and I type cd /var/local/someplace/else
Then I use cd - I'll return to /usr

From the manual
An argument of - is equivalent to $OLDPWD. If a non-empty directory
name from CDPATH is used, or if - is the first argument, and the
directory change is successful, the absolute pathname of the new
working directory is written to the standard output. The return
value is true if the directory was successfully changed; false
otherwise
Therefore the - is equivalent to the $OLDPWD, which holds the last directory which the shell was in, and is set by the previous cd invocation.

From the man found here : http://ss64.com/bash/cd.html
Quickly get back
$ cd -

cd - bring you back to the last directory you were.
e.g.
cd ~/Documents
cd ~
cd /
Now you are in '/', and if you run 'cd -' you will be in '~'. BTW, run 'cd -' once again, you will return to '/' but not '~/Documents'

“ Current Directory “ Is what the bash cd terminal command means. It means “ keep me in this directory “

Related

"No such file or directory" while in link path

When compiling, I always place the build in a separate directory. For example:
mkdir build
cd ./build
(cd ..; ./bootstrap)
../configure
make
Since I have plenty of RAM the aim is to compile on a TMPFS.
The script gets the name of the project, uses it for the name for the directory created in $XDG_RUNTIME_DIR/build and finally links it.
# setup-build.sh
#!/usr/bin/bash
set -e
my_project_name=$(basename $(pwd))
my_project_build_dir="$XDG_RUNTIME_DIR/build/$my_project_name"
mkdir -p $my_project_build_dir
ln -s "$my_project_build_dir" "$(pwd)/build"
The script runs without a problem. But, when I do cd ./build; ../configure it returns an error: bash: ../configure: No such file or directory. The file most certainly does exist, but Bash can't find it!
I altered the script to this:
#!/usr/bin/bash
set -e
my_project_src_dir="$(pwd)"
my_project_name="$(basename $(pwd))"
my_project_build_dir="$XDG_RUNTIME_DIR/build/$my_project_name"
mkdir -p "$my_project_build_dir"
ln -s "$my_project_build_dir" "$(pwd)/build"
cd "$my_project_build_dir"
echo "$my_project_src_dir" > "./project-src-dir.txt"
To compile I have to type cd ./build; $(cat ./project-src-dir.txt)/configure; make. This causes Bash complete to partial break, though. As in I can't TAB complete file names from $my_project_src_dir with this method, but TAB completion for arguments works fine. Ifautoconf is needed: (cd $(cat ./project-src-dir.txt); ./bootstrap). If anyone has any other ideas I would still prefer to be able to just do ../configure, although this will have to do for now.
Edit: Had to change my_project_name="$(basename '$my_project_src_dir') to my_project_name="$(basename $(pwd))" as it was taking '$my_project_src_dir' literally.

How to navigate to a single child directory without knowing its name using shell command?

I need to run a script in a remote machine from my JAVA code using runCommand() method. Now I can't always know the full path of the script as a particular directory name keeps changing. For example the path looks like this : /a/b/xxxxx/script . xxxx is the directory name that keeps changing and its the only single directory under /a/b/. Is there any shell command using which I can get the directory name ? I know using JAVA,but I specifically need shell command.
If there is only a single self-directory, another fool-proof way of doing it would be
cd */.
*/. is that this expands to the "self directory" (named .) in any subdirectory, which is of course the sub-directory itself. Refer the below example of how it works.
E.g.
$ pwd
/home/dude/
$ mkdir -p a/b/ldsnds/c
$ cd a/b/*/.
$ pwd
/home/dude/a/b/ldsnds
$ cd -
/home/dude/
$ cd a/b/*/./c
$ pwd
/home/dude/a/b/ldsnds/c
Below should give you the name of the directory in the directory "b".
$ find /a/b -type d -maxdepth 1 2> /dev/null
If you are so sure that it would always be one directory in /a/b then just store the output of find in a variable and move ahead.
Note: 2> /dev/null is just to get rid of errorneous warnings.

Move script.sh to bin

I'm new to shell programming and I'm trying to create a simple script that gives me some infos on the status of the machine (i.e date, time, users logged in etc) on Scientific Linux 6 (I know it's old, but the department of my university runs on it so there's no escaping)
Basically I've created my script "sysinfo.sh"
#!/bin/sh
....
exit 0
as root user I want to move it so that I can be able to execute it anywhere and I thought the right way to do it was
sudo mv sysinfo.sh usr/local/bin
but I get the error message
mv: cannot move `sysinfo.sh' to `usr/local/bin': No such file or directory
then I looked for the PATH and it gives me
$ echo $PATH
/u/geo2/sw//System/tools/bin:/usr/bin:/bin
What is the right place to move my script?
Best practice for these kind of manipulation or learning is to have scripts in your $HOME/bin directory.
mkdir $HOME/bin
export PATH=$PATH:$HOME/bin
mv sysinfo.sh $HOME/bin
chmod +x $HOME/bin/sysinfo.sh
If you anyway want to move it to /usr/local/bin, why not do that with:
sudo mv sysinfo.sh /usr/local/bin
chmod +x /usr/local/bin/sysinfo.sh
chmod command will make the script executable.
from chmod man:
x -- The execute/search bits.
The command that you posted indicates that you were trying to use the absolute path for copying, but you missed a leading slash --
the directory should be /usr instead of usr.
Try
sudo mv sysinfo.sh /usr/local/bin
Note that unless an absolute path is specified, the shell looks for the path relative to the current working directory.
In this case, the shell was looking for the subdirectory usr under the current directory which was not found;
hence the error message.
Thank you very much!
In the end, I didn't realize that the directory /usr/local/bin wasn't in the PATH
So i just needed to
export PATH=$PATH:/usr/local/bin
sudo mv sysinfo.sh /usr/local/bin
:D

How to run a Linux shell command from a different directory without getting there?

How to run a Linux shell command from a different directory without actually getting there?
In the following, I want to run a make command, but without getting into the source code directory, i.e., from my home directory:
me#mypc:~$ ~/my/source/code/directory/make #This is wrong!
I have seen some examples which suggest as:
me#mypc:~$ cd ~/my/source/code/directory; make
But this ends up taking me into that source code directory, which I want to avoid.
There could the be the other option:
me#mypc:~$ cd ~/my/source/code/directory; make; cd ~
But it becomes complicated in cese.
I am wondering if there could be some way nicer and simpler than these?
You can try:
me#mypc:~$ (cd ~/my/source/code/directory; make)
Parentheses tell your shell to spawn a separate subshell, with its own current directory, and run the commands inside that subshell. After the command finishes, the subshell is closed, and you're back to your main shell, whose current directory never changed.
Do it in a subshell, e.g.
(cd ~/my/source/code/directory; make)
Alternately, you can use make's -C option, e.g.
make -C ~/my/source/code/directory
You can also use
pushd ~/my/source/code/directory; make; popd
or
current=`pwd`; cd ~/my/source/code/directory; make; cd "$current"
$ (cd directory && make)
You need to use && instead of ;. Consider something like
cd junk && rm -rf *
With &&, bash will abort if the directory junk does not exist. If you try cd junk; rm -rf * and junk doesn’t exist, you’ll delete everything in the current directory :(

bash: is there any kind of buffer for last visited paths?

look at this steps:
:~$ cd programacion/
:~/programacion$ cd sports/
:~/programacion/sports$ cd src/
:~/programacion/sports/src$ cd Sports/
:~/programacion/sports/src/Sports$ cd PlatformBundle/
:~/programacion/sports/src/Sports/PlatformBundle$ cd Entity/
:~/programacion/sports/src/Sports/PlatformBundle/Entity$ cd /
:/$
being in this moment in the last prompt, is there any way to go directly to programacion/sports/src/Sports/PlatformBundle/Entity since it is the last path i have visited?
You can use the following shortcut to the last directory:
cd -
For example:
kbrandt#alpine:~$ pwd
/home/kbrandt
kbrandt#alpine:~$ cd src
kbrandt#alpine:~/src$ cd -
/home/kbrandt
kbrandt#alpine:~$ cd -
/home/kbrandt/src
kbrandt#alpine:~/src$
Another option would be to use the $OLDPWD shell variable.
bash's pushd and popd do what you want, and more.
$ help pushd
$ help popd
You can also download the Teleport script, analogous to bash history, but for directories.

Resources