shell script Move and Copy - linux

I have a folder named rules in
/srv/www/htdocs/downloads
and I have another folder with the same name rules in here:
/srv/www/htdocs/didebansnort/core/snort/
I want to copy the folder rules in upper one to the second path
Also I want to know what is the syntax for moving?

the same that you use when you copy/move things in shell. That's why they called shell scripts:)
Copying (from -> to)
cp -r /srv/www/htdocs/downloads/rules /srv/www/htdocs/didebansnort/core/snort/rules
we use cp -r to copy directory (r stands for recursive)
and simple cp for copying of a single file.
Moving (from -> to)
mv /srv/www/htdocs/downloads/rules /srv/www/htdocs/didebansnort/core/snort/rules
This is for nix/mac/cygwin
P.S.
While in the shell you can simply type in this to get a complete manual:
man command_name

If the directory /srv/www/htdocs/didebansnort/core/snort/rules is not empty you cannot just move /srv/www/htdocs/downloads/rules to /srv/www/htdocs/didebansnort/core/snort. You'll either need to delete the existing directory or devise some merging strategy. Fore example, copying over cp -r /srv/www/htdocs/downloads/rules /srv/www/htdocs/didebansnort/core/snort/rules (as nix showed) will result in overwriting all duplicate files.

Related

Bash, copy files from folder to another

I have a problem with an Uni OS Course assignment.
Basically the task says:
Deliver now a file for assessment. The content of the file is: one line, containing a command that
copies all files with prefix "2016", from directory "ExercisesOS" to directory "OSLab".
Consider the current directory to be "~" when writing such command.
I have already tried with that code:
cp /ExercisesOS/2016* /OSLab
but it performs me two error.
How can I write the correct command?
You probably want to copy from the directory you are working.
To check where you are working:
$ pwd
/home/userdir
To copy from your working directory:
$ cp ExerciseOS/2016* OSLab/
mkdir OSLab && cp /ExercisesOS/2016* OSLab
This solution would assume that the directory 'OSLab' isn't already created.

How can I preserve aliases when copying folders on the command line in OSX?

I'm trying to write a personal backup command-line utility on OSX. Let's say I have two folders:
foo/bar/
foo/baz/
foo/bar contains, among other things, OSX aliases to files in foo/baz:
foo/bar/file_alias# -> foo/baz/file
I want to copy both foo/bar and foo/baz to an external hard drive, but for various reasons I do not just want to copy the entire folder foo. I can't figure out a way to copy these folders separately and make the aliases come out right in the end:
cp -r foo/bar /external_hd/foo/bar follows the aliases, replacing them with the original files.
cp -R foo/bar /external_hd/foo/bar preserves the aliases, but they (not surprisingly) continue to point to the original files (e.g. foo/baz/file, not external_hd/foo/baz/file).
rsync -avE foo/bar /external_hd/foo/bar (see this question) seems to do the same thing as cp -R.
Is there any way to accomplish this without copying the entire parent folder foo?
I know of no way where you can automatically copy folders and relink symbolic links to a new destination without some manual intervention. If you know the new paths its quite simple to script, though.
For your specific example; the following should do the trick to relink:
cd /external_hd/foo
find . -type l | while read x; do y=$(readlink "$x" | sed s'|/foo|/external_hd/foo|'); ln -sf "$y" "$x";done
rsync will get you close, the command:
rsync -avHER --safe-links foo/{bar,baz} /external_hd/
will copy the two folders, preserve "safe" relative symlinks between, and ignore "unsafe" symlinks - those that may reference files outside of the copied tree. Change it to:
rsync -avHER --copy-unsafe-links foo/{bar,baz} /external_hd/
and "safe" relative symlinks are preserve and "unsafe" symlinks are replaced by their destination.
If you only have "safe" relative symlinks the first option will do, the second option may do if some extra copying is OK.
However, the definition of "safe" is over-restrictive. Any absolute symlink is "unsafe" even if its target is within the copied tree. Furthermore even a relative link which goes too far towards the root, or maybe is just too complicated, is also "unsafe".
If you need to fix this it should be possible, as the above options show rsync is pretty close to what you need and the source code is available from Apple's Open Source site. Examine the code around the options --links, --copy-links, --copy-unsafe-links & unsafe-links and you may find fixing the definition of "safe" is fairly easy (and you can re-write the symlinks to use the shortest possible relative path at the same time).
HTH

Recursively copy contents of directory to all target directories

I have a directory containing a set of subdirectories and files. I need to recursively copy all the content of this directory to all the subdirectories of another directory, also recursively.
How do I achieve this, preferably without using a script and only with the cp command?
You can write this in a script but you don't have to. Just write it line by line in the terminal:
# $TARGET is the directory containing subdirectories where you want to STORE the copies
# $SOURCE is the directory containing the subdirectories you want to COPY
for dir in $(ls $TARGET); do
cp -r $SOURCE/* $TARGET/$dir
done
Only uses cp and runs on both bash and zsh.
You can't. cp can copy multiple sources but will only copy to a single destination. You need to arrange to invoke cp multiple times - once per destination - for what you want to do; using, as you say, a loop or some other tool.
The first part of the command before the pipe instruct tar to create an archive of everything in the current directory and write it to standard output (the – in place of a file-name frequently indicates stdout).
tar cf - * | ( cd /target; tar xfp -)
The commands within parentheses cause the shell to change directory to the target directory and untar data from standard input. Since the cd and tar commands are contained within parentheses, their actions are performed together.
The -p option in the tar extraction command directs tar to preserve permission and ownership information, if possible given the user executing the command. If you are running the command as superuser, this option is turned on by default and can be omitted.
Also you can use the following command, but it seems to be quite slower than tar;
cp -a * /target

rsync - copy files with same name

I have some different files with the same name and I want to copy all of them to the destination which has a flat structure (no directories, just files), is there any way to append some text onto one of the file names so that both can be copied.
Need to use rsync because there are some files that I need to exclude from the copy.
For example:
dir1/file1.txt
dir1/dir2/file1.txt
both get copied, and in the destination there is:
file1.txt
file1.txt.txt
typically, when I want to do some complex name-mungling, I just write the list of files (with find dir1 >listfiles) and fix it with a text editor.
for example, s/^.*\/([^\/]+)$/cp \0 destination/\1/ converts a file like
dir1/file1.txt
dir1/dir2/file1.txt
to a script like:
cp dir1/file1.txt destination/file1.txt
cp dir1/dir2/file1.txt destination/file1.txt
then you could do something like cut -f 3 <listfiles | sort | uniq -d to find those with the same destination filename. then go back to the editor and fix those lines.
After a few minutes you get a full script for exactly the copy you want, without surprises because you can see each command and apply the best fix for each case.
As far as i know there is no default option in rsync to do that. But i guess that since you are copying files with the same name but from different directories, you are using
multiple rsync commands.
So, this gives you two options:
Create folders..
rsync -av /home/user1/file1 /media/foo/user1/file1
rsync -av /home/user2/file1 /media/foo/user2/file1
etc..
or rename the files with an id
rsync -av /home/user1/file1 /media/foo/parent_dir-file1
rsync -av /home/user2file1 /media/foo/parent_dir-file1
etc..
If you want to use the second solution you can build a simple script. As you are using rsync i suppose that you know the basics on GNU-Linux, so a simple bash script would be enough!
A basic ID is to get the parent folder name and add it as variable to the path of the rsync command. ( it won't always work )
IF you want to be sure of a good id you can for example set a counter and increment like
file1-1
file1-2
file1-3
But you will loose the track of its absolute path.
All the solutions can work, its up to you to choice the one that feed your needs!

One-line copy command when source and dest path are the same

I want to backup a file in some-other sub-directory different from my current directory like this:
cp /aaa/bbb/ccc/ddd/eeee/file.sh /aaa/bbb/ccc/ddd/eeee/file.sh.old
As you see both source and dest dir are the same, so common convention would be to change to the common directory, perform the copy im ./, then change back to the original directory.
Is there a single-line command to accomplish the copy in this situation?
Yes. Use this:
cp /aaa/bbb/ccc/ddd/eeee/{file.sh,file.sh.old}
The curly braces will cause the first part of the string to be reused for each of the items separated by commas. Bash is what expands the above into two separate paths and then passes it to cp. To see what Bash would be passing to cp, simply add an echo to the beginning:
echo cp /aaa/bbb/ccc/ddd/eeee/{file.sh,file.sh.old}
You will see that produces your original statement:
cp /aaa/bbb/ccc/ddd/eeee/file.sh /aaa/bbb/ccc/ddd/eeee/file.sh.old
You're just using a Bash trick to save on typing.

Resources