bash trick to copy files to a previously visited directory - bash

here's the scenario
you are in bash
:~/dirA$ cd /dirb
:/dirb$ cp filex __here_i_want_trick_to_reference_dirA
example of a similar trick is cd -, which puts you into the previously visited directory.
I want this because, in reality, the paths I am dealing with are huge and I'm looking for a shortcut.
furthermore, a trick which handles this:
:a$ cd x
:x$ cd y
etc.
:y$ cp file _ref_to_original_dir_a
I am looking for the least intrusive way to accomplish this, if the 2nd part is not doable without too many shenanigans, then it's probably not worth it for my usage.
thanks
just an update - thanks for the replies.
http://www.hccp.org/modding-cd.html
That page describes what i am choosing. it just adds the alias to the mix for the pushd solution.

You can try using $OLDPWD. That variable should contain the path to the last directory you were in.

This should be really easy to do with pushd, and dirs.
You simply have to issue the pushd command in the directory you want to copy your files to, and use:
cp filex "$(dirs -l +1)"
You can find documentation on those builtin commands here, and examples of aliases to replace cd with them here.
For example:
alias cd='pushd '
alias cd-='popd'
alias cd--='popd -2'
alias cd---='popd -3'
alias d='dirs -v'
alias b='pushd +1'

You can use ~- instead of OLDPWD, which expands to the value of OLDPWD as explained here: http://www.thegeekstuff.com/2010/06/bash-tilde-expansion/. Reducing the number of keystrokes...

Well on my system (Ubuntu) there's an environment variable OLDPWD.
In case its different on your system, you should be able to find it with the following
mkdir nonsense_dir
cd nonsense_dir
cd ..
set | grep nonsense_dir
Hopefully there aren't too many instances of the string nonsense_dir in your environment and you can spot it easily.
Oh, and you probably want to remove the directory too
rmdir nonsense_dir

You can write your own cd function that stores the directory you are cd'ing to then does the actual cd. This variable would be something like LAST_CD_DIR. Then you can use that in another function you call that does the cp.

Related

Bash command line: Is there a way to use the first parameter's value as part of second parameter?

I frequently make temporary backups of files by making a file with nearly the same name, e.g.:
cp /some/long/path/code.php /some/long/path/code.phpcode.php.WIP_desc
Is there some way to shorten this without creating an alias?
You can use brace expansion in bash:
cp /some/long/path/code.php{,.WIP_desc}
Create a file named makeFileBackup with this content
#!/usr/bin/env bash
cp "$1" "$1.WIP_desc"
and then run chmod +x makeFileBackup.
Now you can use it as /path/to/makeFileBackup some_file.
As suggested in a command, you might want to use the above program without having to specify /path/to/ in front of it. Two general approaches are possible:
move makeFileBackup to, or create a link to it in a location that's already in PATH;
add to PATH the location where makeFileBackup is; in this case, you probably still don't want it to be in /home/yourusername but in its own directory.
Is creating a variable ok?
p=/some/long/path
cp $p/code.php $p/code.phpcode.php.WIP_desc
Double quote the expansion if p may contain white space.

How could I make a directory and navigate to the directory by only typing the name of the directory once using bash? [duplicate]

I'm searching for just one command — nothing with && or | — that creates a directory and then immediately changes your current directory to the newly-created directory. (This is a question someone got for his exams of "linux-usage", he made a new command that did that, but that didn't give him the points.) This is on a debian server if that matters.
I believe you are looking for this:
mkdir project1 && cd "$_"
define a bash function for that purpose in your $HOME/.bashrc e.g.
function mkdcd () {
mkdir "$1" && cd "$1"
}
then type mkdcd foodir in your interactive shell
So stricto sensu, what you want to achieve is impossible without a shell function containing some && (or at least a ; ) ... In other words, the purpose of the exercise was to make you understand why functions (or aliases) are useful in a shell....
PS it should be a function, not a script (if it was a script, the cd would affect only the [sub-] shell running the script, not the interactive parent shell); it is impossible to make a single command or executable (not a shell function) which would change the directory of the invoking interactive parent shell (because each process has its own current directory, and you can only change the current directory of your own process, not of the invoking shell process).
PPS. In Posix shells you should remove the functionkeyword, and have the first line be mkdcd() {
For oh-my-zsh users: take 'directory_name'
Reference: Official oh-my-zsh github wiki
Putting the following into your .bash_profile (or equivalent) will give you a mkcd command that'll do what you need:
# mkdir, cd into it
mkcd () {
mkdir -p "$*"
cd "$*"
}
This article explains it in more detail
I don't think this is possible but to all people wondering what is the easiest way to do that (that I know of) which doesn't require you to create your own script is:
mkdir /myNewDir/
cd !$
This way you don't need to write the name of the new directory twice.
!$ retrieves the last ($) argument of the last command (!).
(There are more useful shortcuts like that, like !!, !* or !startOfACommandInHistory. Search on the net for more information)
Sadly mkdir /myNewDir/ && cd !$ doesn't work: it retrieves the last of argument of the previous command, not the last one of the mkdir command.
Maybe I'm not fully understanding the question, but
>mkdir temp ; cd temp
makes the temp directory and then changes into that directory.
mkdir temp ; cd temp ; mv ../temp ../myname
You can alias like this:
alias mkcd 'mkdir temp ; cd temp ; mv ../temp ../'
You did not say if you want to name the directory yourself.
cd `mktemp -d`
Will create a temp directory and change into it.
Maybe you can use some shell script.
First line in shell script will create the directory and second line will change to created directory.

Parent directory of a script

So I am a rookie in Linux and I need some help. I have to write a bash script in which I have to use the parent directory of the script to create a file there, wherever the script would be. It should look like this:
If my script it's in "/home/student/", I need to create, using an in-script command another file called txt in /home/. Any ideas please? Thank you.
There's a subtlety if you want to be able to run your script from anywhere.
eg: if your script is in /home/myHome/someDir/someOther, and you want to create a file in /home/myHome/someDir wherever you are when you run your script.
To solve it, you just need to first derive the directory where your script is.
It can be done using:
SCRIPT_DIRECTORY="$(dirname "$0")"
touch "$SCRIPT_DIRECTORY/../myFile.txt"
Edit: Actually it can be even more subtle, if you want to handle symlinks. ie: if the symlink /home/myHome/mySymlink points at your script, and is the one actually being called, then the previous script will consider /home/myHome/ instead of /home/myHome/someDir/someOther
To handle this case you can do
if [ -L "$0" ] && [ -x $(which readlink) ]; then
ACTUAL_SCRIPT_FILE="$(readlink -mn "$0")"
else
ACTUAL_SCRIPT_FILE="$0"
fi
SCRIPT_DIRECTORY="$(dirname "$ACTUAL_SCRIPT_FILE")"
touch "$SCRIPT_DIRECTORY/../myFile.txt"
use .. to point to parent directory. So you could create a file using something like
MY_SCRIPTDIR="$(dirname $0)"
touch ${MY_SCRIPTDIR}/../abc.txt
From your command prompt or within shell script.
Unfortunately, the other answers either give you the current working directory instead of the directory the script is in, or they will not work if either the script or one of the directories along the way is a symbolic link rather than a real directory.
What will work is:
dirname $(readlink -f "$0")
Explanation:
"$0" is the name of the script as you type it in your command line. Quoting is important for the case it contains whitespace.
readlink will resolve any symbolic links along the way
dirname takes just the directory name from script's full path - it's better readable and safer for corner cases than manually looking for slashes etc.
Now, you will get the correct result even in a complex case: if your script is in /tmp and you create a symbolic link to it in /tmp/abc/, and your current directory will be /home and you run /tmp/abc/your-script, it will correctly output /tmp, not /home nor /tmp/abc.

Bash: cd using keyword expressions

Let's take the following directory listing as an example:
folder-1-one
folder-2-two
folder-3-three
Let's further assume, I want to cd into folder-1-one.
I could use tab completions but this becomes tedious if I have plenty of very similar folder names.
Instead I would like to use some sort of keyword expression. In the example case, 1 and one is unique to the folder I want to access.
Thus I am looking for something like cd 1 or cd one to quickly change into the desired directory without having to pay attention at what point the 1 or the one occur in the file name.
What would be a good solution for that use case?
You could use bash aliases to hardcode the directories you change to freqeuntly:
alias one='cd folder-1-one'
alias two='cd folder-2-two'
Alternatively you could look into using zsh, which supports fuzzy completion via 'oh-my-zsh'. Similar facilities for bash exist (although I can't vouch for them) - such as this one.
You can just use wildcards
cd *1*
cd *2*
cd *three
You can do:
cd *one
cd *two
etc.. but keep in mind that if there is another dir-one then you will get ambiguous warning.

Use `pbcopy` as path for cd command

I am using Automator on my Mac to set up a service that passes a selected folder to a bash shell script as arguments.
In the script I do:
for f in "$#"; do
printf "%q\n" "$f" | pbcopy
done
if I then do:
echo `pbpaste`
I get the path to my selected folder with spaces escaped (\). I then wanted to use this path to cd into that directory and do a bunch of other stuff (creating a blank directory structure). I hoped I could just do:
cd `pbpaste`
but this doesn't work.
If I type the path manually the cd works so I assume the is some issue with data types or returns or something??
I'll admit I don't really know what this script actually doing and may be going about this all wrong but but if anyone can explain what's going on here and how to get it working it that would be great but even better would be a pointer to a really good resource for a complete beginner to start learning about shell scripting.
I really like the idea of getting into this a bit more but all the resources I have found are either total basics (cd, ls, pwd etc) or really high level and assume a bunch of previous knowledge.
What I'd really like is a full language reference with some actual examples like you find for the languages I am more used to (HTML/CSS/JS/AS3), if such a thing exists.
Cheers for any help :)
I'm agree with #chepner's answer, but for google's results sake, to cd using pbpaste you simply do:
cd $(pbpaste)
When you use the %q format, you are adding literal backslashes to the string, which the shell does not process as escape characters when you use it with cd.
The clipboard is useful for interprocess communication; inside a single script, it's easier to just use variables to hold information temporarily. f already has the path name in it, so just use it:
cd "$f"
Notice I've quoted the expansion of f, so that any spaces in the path name are passed as part of the single argument to cd.

Resources