LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Need to create a shell script that copies all files owned by a user (https://www.linuxquestions.org/questions/linux-newbie-8/need-to-create-a-shell-script-that-copies-all-files-owned-by-a-user-904920/)

BrainOfSweden 09-25-2011 11:02 AM

Need to create a shell script that copies all files owned by a user
 
So I need to create a shell script that looks into the /shared catalog, and then archives all files owned by a specific user, and puts that archive in his home folder. The script is supposed to copy the entire /shared catalog basically, but it needs to ignore any sub catalogs that doesn't contain files that he owns.

This is actually a school assignment, but searching for help online is allowed. Here are the hints from the assignment
• Combine the power of find, cp and tar in a shell script
• Have a look at the -exec parameter to find
• Have a look at the $PATH shell variable

I've tried to understand the -exec param, but the only thing I get to work is find -executable, I don't understand how to combine the commands so that it actually copies the files that it found. I looked in the man page, but I didn't really get it

EricTRA 09-25-2011 11:23 AM

Hello and Welcome to LinuxQuestions,

Let me thank you upfront for indicating this is a school assignment. It's a bit of custom that LQ users don't offer ready made solutions, especially not when homework is involved. You'll find us at our best if you show us what you already have 'invented/found out' by yourself and where your code is failing. Then we'll point you in the right direction. You'll learn a lot more that way then when someone provides you a working solution. So, show us what you've got and we'll help you out fixing what's missing.

Looking forward to your participation in the forums. Have fun with Linux.

Kind regards,

Eric

BrainOfSweden 09-25-2011 03:38 PM

I know how to make an archive with the tar command. According to the instructions in the assignment, I suppose that it's easier to combine find with cp, and make a tar out of a temporary directory. Then removing that directory of course, wich is why I believe they put "the script should remove any temporary files or directories that it created" in the instructions. Doing said actions is not a problem for me, the problem is how to only copy executable files, and skip empty folders. I have read the man page, and as far as I understand, I'm supposed to use
Code:

find -executable cp /target/directory{} +
The problem is that I'm not exactly sure how to combine these commands, I've tried a number of ways to do it, and even if i don't get an error message, the target directory remains empty. I'm actually kinda clueless here.
I maybe should mention this is a task required for a higher grade,thus we are required to search for the information ourselfs, since the lectures only gives us information on how to perform basic tasks.

EricTRA 09-26-2011 12:21 AM

Hello,

I think you're confusing -executable with -exec which is completely different. If you run for example:
Code:

find . -type f -executable
you'll get a list of executable files in the directory where you execute the command (.). If you execute:
Code:

find . -executable
you'll be presented with a list of the executable files and the directories in the directory where you executed the find command since directories also have the executable bit set to allow you to cd into them.

This is what the man page says for -executable:
Quote:

Matches files which are executable and directories which are searchable (in a file name resolution sense). This takes into account access control lists and other permissions artefacts which the -perm test ignores. This test makes use of the access(2) system call, and so can be fooled by NFS servers which do UID mapping (or root-squashing), since many systems implement access(2) in the client's kernel and so cannot make use of the UID mapping information held on the server. Because this test is based only on the result of the access(2) system call, there is no guarantee that a file for which this test succeeds can actually be executed.
Now, on the other hand the -exec option is what I think you're looking for. If you use find with that option, like this:
Code:

find . -type f -name 'test*' -exec cp /target/directory '{}' \;
all the files in the current directory that begin with test will be copied to /target/directory. Explanation for the above from the man page of find (command is substituted):
Quote:

Runs 'cp' on every file in or below the current directory. Notice that the braces are enclosed in single quote marks to protect them from interpretation as shell script punctuation. The semicolon is similarly protected by the use of a backslash, though single quotes could have been used in that case also.
From the man page of find:
Quote:

-exec command ;
Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of `;' is encountered. The string `{}' is replaced by the current file name being processed everywhere it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find. Both of these constructions might need to be escaped (with a `\') or quoted to protect them from expansion by the shell. See the EXAMPLES section for examples of the use of the -exec option. The specified command is run once for each matched file. The command is executed in the starting directory. There are unavoidable security problems surrounding use of the -exec action; you should use the -execdir option instead.
Hope this helps you on your way. It would be helpful if you posted what you already have to see if you need any help or pointers on other commands.

Kind regards,

Eric

BrainOfSweden 09-26-2011 08:26 AM

Quote:

Originally Posted by EricTRA (Post 4482249)
I think you're confusing -executable with -exec which is completely different.

Yes, I noticed I mixed them up. So I've tried your example, but something is pretty wrong. In my script I start with mkdir to create a temporary directory that I will later archive and then delete. But when it reaches the find command, wich in my script looks like this
Code:

find -executable (since I wan't executable files right) -exec cp -r /target/directory '{}' \;
And at that point, i reach an endless loop, wich in the example above would be /directory/directory/directory/directory... until it says "Filename too long". Looking in target, I can see that directory is created, but empty. Instead, I have a directory in the shared directory, but also in all sub directories. True for all these is that they contain themselves, over and over again, until "Filename too long". I screwed something up badly here.

unSpawn 09-27-2011 05:49 PM

Why would you copy the tree when tar accepts files on the command line like 'tar -f /home/username/archive.tar `find /shared_catalog -type f -user username 2>/dev/null`' so you can put the archive in /home like required w/o requiring any intermediate steps?

crts 09-27-2011 07:10 PM

Quote:

Originally Posted by BrainOfSweden (Post 4482540)
Yes, I noticed I mixed them up. So I've tried your example, but something is pretty wrong. In my script I start with mkdir to create a temporary directory that I will later archive and then delete. But when it reaches the find command, wich in my script looks like this
Code:

find -executable (since I wan't executable files right) -exec cp -r /target/directory '{}' \;
And at that point, i reach an endless loop, wich in the example above would be /directory/directory/directory/directory... until it says "Filename too long". Looking in target, I can see that directory is created, but empty. Instead, I have a directory in the shared directory, but also in all sub directories. True for all these is that they contain themselves, over and over again, until "Filename too long". I screwed something up badly here.

Hi,

I assume that your target directory is inside the directory that you are searching, right? In this case use the -path and -prune option so that it won't try to copy itself to itself. Also use '-type f' to only copy files and not directories.

Finally, correct your cp command:
Code:

cp SOURCE DEST
or
cp -t TARGET SOURCE


EricTRA 09-28-2011 12:46 AM

Quote:

Originally Posted by BrainOfSweden (Post 4482540)
Yes, I noticed I mixed them up. So I've tried your example, but something is pretty wrong. In my script I start with mkdir to create a temporary directory that I will later archive and then delete. But when it reaches the find command, wich in my script looks like this
Code:

find -executable (since I wan't executable files right) -exec cp -r /target/directory '{}' \;
And at that point, i reach an endless loop, wich in the example above would be /directory/directory/directory/directory... until it says "Filename too long". Looking in target, I can see that directory is created, but empty. Instead, I have a directory in the shared directory, but also in all sub directories. True for all these is that they contain themselves, over and over again, until "Filename too long". I screwed something up badly here.

Hello,

It would be very helpful to us if you'd post what you've written so far in order to help you troubleshoot. It's kind of walking in the dark without your code. Looking at parts of a script or separate commands without seeing the entire picture is a bad idea since we don't know what you're doing next in your script.

Kind regards,

Eric

BrainOfSweden 09-28-2011 01:26 AM

Thanks everyone for helping me out. And sorry for maybe acting like such a noob, I am one when it comes to Linux though ;)
This command acutally helped, it fulfills all the requirements. Only owned files, no empty directories, no trash left behind.
Quote:

Originally Posted by unSpawn;4483859'tar
-f /home/username/archive.tar `find /shared_catalog -type f -user username 2>/dev/null`

I had no idea tar was that powerful. Thanks again.

snooly 09-28-2011 07:22 AM

Quote:

Originally Posted by BrainOfSweden (Post 4484121)
Thanks everyone for helping me out. And sorry for maybe acting like such a noob, I am one when it comes to Linux though ;)
This command acutally helped, it fulfills all the requirements. Only owned files, no empty directories, no trash left behind.

I had no idea tar was that powerful. Thanks again.

but do you understand how it works?


All times are GMT -5. The time now is 10:05 AM.