I'm trying to back up some key files and directories of a machine, as root, including some of the /home data, hand-picking some files to reduce the tarball size. Everything is OK for the most part, since most files are owned by root anyway, but say I just try this:
# tar -cf backup.tar /home/user/file
When I restore the contents, /home/user/file is as expected owned by user, but /home/user is owned by root. I tried, however,
# tar -cf backup.tar /home
and in this case all /home owners are preserved. (Note that I don't need the -p flag as I'm root. Still I tried it...)
Is this normal behavior? If so, is there a way to hand-pick regular-user files to back up while keeping the /home ownership information? My goal is to simply untar everything from /.
Thanks!
To properly set permissions for directories, the tarball needs to contain entries for those directories, so you need to add them to the tarball.
When you create a tarball that only contains /home/user/file, and not /home/user, there is then no information about the permissions of /home/user in the tarball, so tar doesn't know what to do. It automatically creates the directories but has no permissions, owner or group to give them, so they get the defaults.
You could add the directories as well:
# tar -cf backup.tar --no-recursion /home/user /home/user/file
But this may not make things any simpler for you. Note the --no-recursion - that tells tar to not add everthing under a directory, just the directory itself. If you wanted to actually also add direcory trees, you would have to use find(1) to pass it every file under that directory manually. That would get ugly quickly.
Keep in mind that we are talking about backing up and restoring particular files. If you were to ever restore, you would presumably also create the unix accounts to restore to if they weren't there already. So there would be no need to set permissions on home directories, at least. The same cannot be said of subdirectories of those though.
Related
I'm trying to make snapshot backups of my user using rsync, the base user folder has a ton of hidden files and configurations that I'm not interested in backing up, however I am interested in the hidden folders inside of it's subdirectories.
Here is the layout
Source Directory
/Base
.ignore
.ignore2
.ignore3
/dir1
.keep
normalfiles
/dir2
.keep
normalfiles
Desired Backup Directory
/Backup
/dir1
.keep
normalfiles
/dir2
.keep
normalfiles
How can I ignore the first hidden files AND directories while preserving them in the subdirectories.
Solution
rsync -vrn --exclude="/.*" base/ base2/
By specifying the / before the file match /.* I managed to achieve what I was after. I have found this to be pretty useful when making snapshot backups of some mac's in my house. They tend to store tons of config information in the root folder for each user that isn't needed for my backups.
The hidden files for my own project configs and rc's is saved though since they aren't stored in the root directory.
I can not found "hidden folders inside of it's subdirectories" in your Code sample. Do you mean hidden files?
Here is a try:
rsync -nrv --include="/*/" --include="*/.*" --exclude="*" Base/ Base2/
-n simulate
-r recursive
-v verbose
With PHP I am using exec("tar -xf archive.tar -C /home/user/target/folder") to extract the contents of a specific archive (archive.tar) into the target directory (/home/user/target/folder), so that all existing contents of the target directory will be overwritten by the new ones that are contained in the archive.
It works fine and all files in the target directory are being overwritten after extract, but there is one directory in the archive that I would like to omit (from extracting and thus overwriting the existing one in the target folder)...
For example, the archive.tar contains:
folderA/
folderB/
folderC/
folderD/
fileA.php
fileB.php
fileC.xml
How could I extract (and overwrite) all except (for example) folderC/? In other words, I want folderC and its contents to remain intact in the user's directory and not be overwritten by the one contained in the tar archive.
Any suggestions?
(Tar on the hosting server is GNU version 1.23.)
You can use '--exclude' to omit a folder:
tar -xf archive.tar -C /home/user/target/folder" --exclude="folderC"
There is the --exclude PATTERN option in the tar tool.
Check: tar on linuxcommand.org
To be on the safe side, you could remove all write permissions from the folder. For example:
$ chmod 000 folderC/
An then do a normal tar extract (as regular user). You'll get some error messages on console, but your folder will remain untouched.... At the end of the tar, change back your folder original permissions. For example:
$ chmod 775 folderC/
Of course '--exclude' tar option is the right solution to this particular problem, but, if you are not completely 100% sure about a command syntax, and yor're handling critical data, my solution puts you on the safe side :-).
Write --exclude='./folder' at the beginning of the tar command.
In your case that is,
exec("tar -x --exclude='./C' -f archive.tar -C /home/user/target/folder")
Let's say I'm trying to tar.gz all the files and folders in /usr/local/bin/data/*
The file name would be data-2015-10-01.tar.gz. When I untar it, is it possible that the root directory would be data-2015-10-01 followed by the contents of whatever is inside of data/* ?
If not, how can I tar /usr/local/bin/data/* but start at the /data/ folder level?
I can't do this unfortunately since the program spits out /usr/local/bin/data/ and I'm unable to change it.
cd /usr/local/bin
tar ... /data/*
There are a couple of ways to do what I think you're trying to accomplish. First, you can use the -C option to tar when creating the archive. That changes tar's current working directory to that directory before creating the archive. Not strictly required in your case, but probably helpful.
# tar -C /usr/local/bin -czf data-2015-10-01.tar.gz data/*
That at least gets you to a single directory named data. If you have control of the extraction (manually or via a script you provide to whomever is unpacking this), then you can do something like this on the extraction:
# mkdir -f data-2015-10-01 && tar -C data-2015-10-01 --strip-components=1 -xzf data-2015-10-01.tar.gz
This will remove the first path, which is "data" and extract everything from there into the directory which is your current working directory, data-2015-10-01. So, it isn't specifically tar that's doing the renaming, but you will effectively end up with the same result.
I've accomplished something similar with a symlink. This is not a great solution if you have (or might have) symlinks in the directory structure you're trying to archive. I have to say that I prefer #geis' solution to strip out the top-level directory on extract, but this gives you another option.
ln -s /usr/local/bin/data data-2015-10-01
tar -cvhf data-2015-10-01.tar.gz data-2015-10-01/
rm data-2015-10-01
(Note the additional -h option in the tar invocation.)
How can I avoid the following types of errors, and force the
operation to occur?:
/bin/cp: cannot overwrite directory `./foo' with non-directory
/bin/cp: cannot overwrite non-directory `./usr/share/doc' with directory `/usr/share/doc'
To backup a partition, I want to copy a new version of a
directory onto an old version, to make them identical, with the
command:
/bin/cp -xau --remove-destination / .
The destination directory is in a ZFS filesystem that is being
regularly snapshotted. Relatively few files (or directories)
change.
That is why I don't want to just delete the whole
destination directory -- that will make the snapshot needlessly
large.
This is in Linux.
Thanks.
The following seems to work better (but not perfectly):
tar cf /mytmp/root.tar --one-file-system /
cd /backup/root
tar xvf /mytmp/root.tar --keep-newer-files
Note that this works better when /mytmp is not in the root
partition. :-)
The output from the 2nd tar command was 700K lines. I captured
it inside an emacs buffer and searched it for error messages.
There were two problems with not wanting to replace directories
with links, which I handled manually.
At my office, we have a network directory structure like this:
/jobs/2004/3999-job_name/...
/jobs/2004/4000-job_name/...
The issue is that employees rename the "4000-job_name" folders (which in turn breaks other things that rely on the name being consistent with a database).
How can I stop users from renaming the parent folder while still allowing them full control of that folder's contents?
Please keep in mind that this is a Samba share that Windows users will be accessing.
I think you want to do this:
chmod a=rx /jobs #chdir and lsdir allowed, modifying not
chmod a=rwx /jobs/* #allow everything to everyone in the subdirectories
Since the directories /jobs/* are in fact files in /jobs their names cannot be changed without the write permission for /jobs. In the subdirectories of /jobs/ everyone is allowed to do anything with the commands above.
Also, be sure to set the permissions of new directories to rwx as you add them.
(edit by Bill K to fix the examples--the solution was correct but he misread the question due to the strange coloring SO added)
The question has already been answered, so I'm just gonna make a brief remark: in your question, you use the terms "folder" and "directory" interchangeably. Those two are very different, and in my experience 99% of all problems with Unix permissions have to do with confusing the two. Remember: Unix has directories, not folders.
EDIT: a folder is two pieces of cardboard glued together, that contain files. So, a folder is a container, it actually physically contains the files it holds. So, obviously a file can only be in one container at a time. To rename a file, you not only need access to the folder, you also need access to the file. Same to delete a file.
A directory, OTOH, is itself a file. [This is, in fact, exactly how directories were implemented in older Unix filesystems: just regular files with a special flag, you could even open them up in an editor and change them.] It contains a list of mappings from name to location (think phone directory, or a large warehouse). [In Unix, these mappings are called links or hardlinks.] Since the directory only contains the names of the files, not the files themselves, the same file can be present in multiple directories under different names. To change the name of a file (or more precisely to change a name of a file, since it can have more than one), you only need write access to the directory, not the file. Same to delete a file. Well, actually, you can't delete a file, you can only delete an entry in the directory – there could still be other entries in other directories pointing to that file. [That's why the syscall/library function to delete a file is called unlink and not delete: because you just remove the link, not the file itself; the file gets automatically "garbage collected" if there are no more links pointing to it.]
That's why I believe the folder metaphor for Unix directories is wrong, and even dangerous. The number one security question on one of the Unix mailinglists I'm on, is "Why can A delete B's files, even though he doesn't have write access to them?" and the answer is, he only needs write access to the directory. So, because of the folder metaphor, people think that their files are safe, even if they are not. With the directory metaphor, it would be much easier to explain what's going on: if I want to delete you from my phonebook, I don't have to hunt you down and kill you, I just need a pencil!
If you make the parent directory--/jobs/2004/--non-writable for the users, they won't be able to rename that folder.
I did the following experiment on my own machine to illustrate the point:
ndogg#seriallain:/tmp$ sudo mkdir jobs
ndogg#seriallain:/tmp$ sudo mkdir jobs/2004
ndogg#seriallain:/tmp$ sudo mkdir jobs/2004/3999-job_name/
ndogg#seriallain:/tmp$ cd jobs/2004/
ndogg#seriallain:/tmp/jobs/2004$ sudo chown ndogg.ndogg 3999-job_name/
ndogg#seriallain:/tmp/jobs/2004$ ls -alh
total 12K
drwxr-xr-x 3 root root 4.0K 2009-03-13 18:23 .
drwxr-xr-x 3 root root 4.0K 2009-03-13 18:23 ..
drwxr-xr-x 2 ndogg ndogg 4.0K 2009-03-13 18:23 3999-job_name
ndogg#seriallain:/tmp/jobs/2004$ touch 3999-job_name/foo
ndogg#seriallain:/tmp/jobs/2004$ mv 3999-job_name/ blah
mv: cannot move `3999-job_name/' to `blah': Permission denied