Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

In Bash, suppose I visit a directory, and then another directory. I would like to copy a file from the first directory to the second directory, but without specifying the long pathnames of them. Is it possible?

My temporary solution is to use /tmp as a temporary place to store a copy of the file. cp myfile /tmp when I am in the first directory, and then cp /tmp/myfile . when I am in the second directory. But I may check if the file will overwrite anything in /tmp.

Is there something similar to a clipboard for copying and pasting a file?

share|improve this question
1  
You have to type the cd command, so you can just cd - to go back to the previous directory, up-arrow to recall the cd command, and edit the line to be cp instead of cd. (ctrl-a(beginning-of-line), alt-d (kill-word), cp -a, ctrl-e(end-of-line)). – Peter Cordes Mar 10 at 15:40
    
With Emacs and M-x term you can use Emacs' clipboard. – Pål GD Mar 10 at 17:56
1  
You can use Midnight Commander and forget about jumping through the hoops. – Deer Hunter Mar 10 at 19:29
    
@PålGD People say Emacs' is an operating system... Most have clipboards ;) – Volker Siegel Mar 13 at 11:18

Using Bash, I would just visit the directories:

$ cd /path/to/source/directory
$ cd /path/to/destination/directory

Then, I would use the shortcut ~-, which points to the previous directory:

$ cp -v ~-/file1.txt .
$ cp -v ~-/file2.txt .
$ cp -v ~-/file3.txt .

If one wants to visit directories in reverse order, then:

$ cp -v fileA.txt ~-
$ cp -v fileB.txt ~-
$ cp -v fileC.txt ~-
share|improve this answer
24  
+1 I'm using Unix/Linux shells for more than 20 years now, and I didnt' know that shortcut. – Dubu Mar 10 at 11:30
4  
Huh, that is a handy shortcut for "$OLDPWD". Why three separate cp commands, though? cp -a ~-/file[1-3].txt . – Peter Cordes Mar 10 at 15:32
4  
Actually, the three cp's are examples. In the real world, wildcard characters can also be used to simplify the copy task. – Anderson M. Gomes Mar 10 at 16:39
2  
I was going to mention something about pushd and parsing dirs...but this is far, far better. I suggest you add the fact that "$OLDPWD" is exactly equivalent to ~- and is more portable (helpful for those not using bash.) – Wildcard Mar 11 at 5:54
1  
~+ is likewise a shortcut for "$PWD" – Paul Evans Mar 12 at 21:23

If I saw that situation coming as a one-off, I might:

a=`pwd`
cd /somewhere/else
cp "$a/myfile" .

If there were directories that I found myself copying files out of semi-regularly, I would probably define some mnemonic variables for them in my .profile.

Edited to add:

After sleeping on it, I wondered how closely I could get to other GUI / OS behaviors where you select some number of files, "cut" or "copy" them, then "paste" them somewhere else. The best selection mechanism I could come up with was your brain/preferences plus the shell's globbing feature. I'm not very creative with naming, but this is the basic idea (in Bash syntax):

function copyfiles {
  _copypastefiles=("$@")
  _copypastesrc="$PWD"
  _copypastemode=copy
}

function cutfiles {
  _copypastefiles=("$@")
  _copypastesrc="$PWD"
  _copypastemode=cut
}

function pastefiles {
  for f in "${_copypastefiles[@]}"
  do
    cp "${_copypastesrc}/$f" .
    if [[ ${_copypastemode} = "cut" ]]
    then
      rm "${_copypastesrc}/$f"
    fi
  done
}

To use it, put the code into ~/.bash_profile, then cd to the source directory and run either copyfiles glob*here or cutfiles glob*here. All that happens is that your shell expands the globs and puts those filenames into an array. You then cd to the destination directory and run pastefiles, which executes a cp command for each source file. If you had previously "cut" the files, then pastefiles also removes the source file (or, tries to). This doesn't do any error-checking (of existing files, before potentially clobbering them with the cp; or that you have permissions to remove the files during a "cut", or that you can re-access the source directory after you move out of it).

share|improve this answer
2  
For your one-off, $OLDPWD already exists, which can be shortened to ~- in bash and zsh. – Gilles Mar 10 at 19:50

I think the ~- is the right answer, but note that bash has a built-in line editor that can copy/paste text.

If you are in emacs mode you can recall your cd command from the history, and use Control-u to kill the line into the bash "clipboard" called the kill-ring (there are other ways too). You can then yank this string into a new command at any time with Control-y. Obviously, in your example this depends on you having used an absolute directory name in your cd command.

You can also use the interesting default key-binding of Meta-.. This copies the last word from the previous command into your current line. If repeated, each time it goes back one command in the history. So if you do a cd /x, then cd /y followed by cdMeta-.Meta-. you will have /x in your input.

share|improve this answer

Expanding on the answer from Anderson M. Gomes, Bash allows you to refer to any prior directory in your directory stack by typing ~N (or ~+N) where N is the position on the dir stack. For example:

# go some places
$ cd /path/to/source/directory
$ pushd /path/to/destination/directory
$ pushd $HOME
$ pushd /tmp

# show the current dir stack
$ dirs -v
0 /tmp
1 ~
2 /path/to/destination/directory
3 /path/to/source/directory

Now you can copy a file between two past directories, neither of them the current one, with:

cp -v ~3/file1.txt ~2

To solve the original poster's problem, you would do:

$ cd /path/to/source/directory
$ pushd /path/to/destination/directory

# show the current dir stack
$ dirs -v
0 /path/to/destination/directory
1 /path/to/source/directory

# copy
cp -v ~1/file[123].txt .

With a large set of files, you could list them in a manifest file and then do the copy from the source dir:

$ cd /path/to/destination/directory
$ pushd /path/to/source/directory

# copy
cp -v `files_to_copy.list` ~1

See also: this section of the Bash man page


Similarly, in Tcsh, you can use the =2 notation (rather than ~2) to refer to the second dir on your dir stack.

See also: this section of the Tcsh man page

share|improve this answer

when you are in the first directory, lets say the source or src in short, execute

src=${PWD}

then cd in to second directory and execute:

cp -i ${src}/filename .

the -i option will ask if you want to overwrite, if there is a duplicate file

share|improve this answer
    
Thanks. It is even better without specifying the filename. – Tim Mar 10 at 4:14

A variation on anderson-m-gomes response. Using Bash, I would just visit the directories:

$ cd /path/to/source/directory
$ cd /path/to/destination/directory

Then, I would use the variable $OLDPWD, which points to the previous directory:

$ cp -v $OLDPWD/file1.txt .

If one wants to visit directories in reverse order, then:

$ cp -v fileA.txt $OLDPWD/
share|improve this answer
3  
+1, but you forgot to "quote" your variable expansions. If $OLDPWD contains spaces, this breaks. Also, I always use cp -a. Also, it's unfortunate that tab-completion is broken on variable expansions. You can use ctrl-alt-e to shell-expand the current command line, though, after typing the $OLDPWD part. – Peter Cordes Mar 10 at 15:30
1  
~- is a shortcut for $OLDPWD – Gilles Mar 10 at 19:51
    
I was just pointing out another variation, since Unix/Linux is full of them. Funny, that I've been using Linux for >20 years, and I'd never seen ~- before. Plus, $OLDPWD is easy to remember. – Scott Carlson Mar 14 at 17:54

You can use xclip:

NAME
       xclip - command line interface to X selections (clipboard)

SYNOPSIS
       xclip [OPTION] [FILE]...

DESCRIPTION
       Reads  from standard in, or from one or more files, and makes the data available as an X selection for pasting
       into X applications. Prints current X selection to standard out.

Example:

$ cd /path/to/dir1
$ xclip-copyfile file1 file2
$ cd /path/to/dir2
$ xclip-pastefile
file1 file2

Also visit xsel.

share|improve this answer
    
That does a tar | gzip into / out of the X clipboard. Kinda clunky compared to cp, and doesn't generalize to making symlinks or hardlinks. (cp -as or cp -al) – Peter Cordes Mar 10 at 15:44

If in bash, I would use pushd and popd. These commands keep a handy FIFO stack of directories for later use. You can consult the stack anytime using dirs.

As such I would do:

pushd .
cd /somewhere/else
cp "`popd`/myfile"
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.