10

I'm looking for a single linux command that allows me to do the equivalent of this:

cp /some/path/file /another/path/ && ln -sf /another/path/file /some/path/

If there isn't one, what's the best way to do this for a bunch of files?

itsadok
  • 1,839
  • 5
  • 21
  • 33

3 Answers3

7

A small note, is that you could use ln both times to make the command not actually move the data (assuming both paths are on the same filesystem).

ln /some/path/file /another/path/ && ln -sf /another/path/file /some/path/

But I assume that you want to move the content of /some/path/ to an other disk, and then create links to the new files so "no one" notices.

for f in `ls /some/path/`; do ln /some/path/$f /another/path/ && ln -sf /another/path/$f /some/path; done

Wrapping it in a bash function:

function cpln {
    for f in `ls $1`
    do
        ln $1/$f $2 && ln -sf $2/$f $1
    done
}
Mr Shark
  • 346
  • 3
  • 10
2

Theres my script you could use (takes two parameters /some/path/file and /another/path/ ):

#!/bin/bash
cp $1 $2
if [ "$?" -ne "0" ]; then
    echo "Some error"
    exit 1
    fi
ln -sf $2/${1##*/} ${1%/*}
Wayne Arthurton
  • 245
  • 2
  • 11
Kazimieras Aliulis
  • 2,324
  • 2
  • 26
  • 45
1

Seriously, I thought this was a really easy question.

Here's what I can do in perl:

#!/bin/perl
# Usage: cpln TARGETDIR SOURCE...
# Example: find tree/ -type f | xargs cpln commands/

$target = shift;

foreach(@ARGV) {
    m[(.*)/([^/]+)];
    system("cp $_ $target");
    system("ln -sf $target/$2 $1/");
}

I was hoping for something more elegant, but I guess I'll use that.

itsadok
  • 1,839
  • 5
  • 21
  • 33
  • 1
    To do it "in Perl," you should use File::Copy (or similar) and symlink(). Perl is not shell; avoid system(), and *especially* avoid passing whole command lines to system() (e.g., what if an argument contains a space?). Either way, always, always, ALWAYS check return values. – John Siracusa May 14 '09 at 14:53