Correct syntax for including .* directories with tar
up vote
2
down vote
favorite
I'm trying to include files that match */*/.thisdirectory/*
in a tar archive. What's the correct syntax? Apparently this is not:
> find .
.
./bar
./bar/.a
./bar/.a/baz
./foo
./foo/.a
> tar --include "*[.]a*" -cvf a.tar .
>
tar
add a comment |
up vote
2
down vote
favorite
I'm trying to include files that match */*/.thisdirectory/*
in a tar archive. What's the correct syntax? Apparently this is not:
> find .
.
./bar
./bar/.a
./bar/.a/baz
./foo
./foo/.a
> tar --include "*[.]a*" -cvf a.tar .
>
tar
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I'm trying to include files that match */*/.thisdirectory/*
in a tar archive. What's the correct syntax? Apparently this is not:
> find .
.
./bar
./bar/.a
./bar/.a/baz
./foo
./foo/.a
> tar --include "*[.]a*" -cvf a.tar .
>
tar
I'm trying to include files that match */*/.thisdirectory/*
in a tar archive. What's the correct syntax? Apparently this is not:
> find .
.
./bar
./bar/.a
./bar/.a/baz
./foo
./foo/.a
> tar --include "*[.]a*" -cvf a.tar .
>
tar
tar
asked May 6 '16 at 23:45
cbmanica
1336
1336
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
up vote
1
down vote
I'm assuming you're using FreeBSD tar¹ as this is the only implementation I know with a --include
option.
When you pass --include
, only explicitly included files are traversed. When building an archive, if a directory isn't traversed then neither it nor any of its contents can be included. Since you're tarring .
but not including .
, the sole command line argument doesn't get included, and you get an empty archive.
To reach the .a
directories, you would need to include all the parent directories. The thing is, if you do that, then all of their contents will be included as well. You can use --exclude
to exclude them, but then you need an exclude pattern that doesn't exclude the dot directories that you want to include. At this point --include
is no longer of any use. The --include
option is rarely useful when creating an archive, it's rather more useful when copying part of an existing archive (because when doing that, there's no recursive traversal, just iteration through the list of members of the input archive).
tar --exclude='./*/[!.]*' -cvf a.tar .
Note that all files in the toplevel directory are included. I don't think there's a way to include only those directories that will have non-empty contents.
To get only the ./*/.*
directories and nothing else (in particular not their parent directories), you need to pass them as arguments to tar, rather than let tar recurse to find them.
tar -cvf a.tar ./*/.[!.]*/
Remove the trailing slash to include files that aren't directories (or symlinks to directories). Add ./*/..?*/
to include directories whose name begins with ..
if you have those.
¹ Possibly under a different operating system.
add a comment |
up vote
1
down vote
If your shell is bash, you can use the GLOBIGNORE
variable to hide the .
and ..
directories. This does automatically also set the dotglob
option, so *
now matches both hidden and non-hidden files:
GLOBIGNORE=".:.."
tar czf tarball-with-hidden-files.tgz directory/*
To expand on this a bit: by default, *
does not match hidden files (files starting with a .
), which includes the current (.
) and parent (..
) directories of any directory. If you want a glob (e. g. a command line wildcard) to match them, you need to set the dotglob
option, but this can cause really bad things to happen if ..
matches *
and you do something like rm -fr /home/olduser/*
(because olduser/..
matches, which is /home/
and now you've just fried everyones' home directories. Which is where GLOBIGNORE
comes into play- it blacklists things from matching wildcards. As a really simple use-case:
ghoti@home:~/scratch$ ls -ld ?dotfile
ls: cannot access '?dotfile': No such file or directory
ghoti@home:~/scratch$ touch _dotfile .dotfile
ghoti@home:~/scratch$ ls -ld ?dotfile
-rw-rw-r-- 1 ghoti ghoti 0 May 6 16:58 _dotfile
ghoti@home:~/scratch$ GLOBIGNORE=".:.."
ghoti@home:~/scratch$ ls -ld ?dotfile
-rw-rw-r-- 1 ghoti ghoti 0 May 6 16:58 _dotfile
-rw-rw-r-- 1 ghoti ghoti 0 May 6 16:58 .dotfile
What does this mean for you? Well, as in the quick example at the top of this answer, once you set GLOBIGNORE
to ignore .
and ..
, you can use *
to match hidden directories like the ones you're trying to archive:
tar czf mytarball.tgz directory/* # this will include things like directory/.hiddenfile
To point this at your specific example of a directory called .a
:
ghoti@home:~/scratch$ mkdir -p example example/foo/.a example/bar/.a example/foo/_a example/bar/_a
ghoti@home:~/scratch$ touch example/{foo,bar}/{.,_}a/file
ghoti@home:~/scratch$ find example/
example/
example/foo
example/foo/_a
example/foo/_a/file
example/foo/.a
example/foo/.a/file
example/bar
example/bar/_a
example/bar/_a/file
example/bar/.a
example/bar/.a/file
ghoti@home:~/scratch$ GLOBIGNORE=".:.."
ghoti@home:~/scratch$ tar cvzf withdotfiles.tgz example/*/?a
example/bar/_a/
example/bar/_a/file
example/bar/.a/
example/bar/.a/file
example/foo/_a/
example/foo/_a/file
example/foo/.a/
example/foo/.a/file
ghoti@home:~/scratch$ unset GLOBIGNORE
ghoti@home:~/scratch$ tar cvzf withoutdotfiles.tgz example/*/?a
example/bar/_a/
example/bar/_a/file
example/foo/_a/
example/foo/_a/file
I must be missing something, because that doesn't improve the situation at all:> GLOBIGNORE=".:.." tar --include "*[.]a*" -cvf a.tar . >
The .* directories get included just fine without--include
but trying to restrict what gets tarred fails utterly...
– cbmanica
May 6 '16 at 23:53
@cbmanica the command you show in no way resembles DopeGhoti's example nor does it*/*/.thisdirectory/*
so clarifications are needed on what files you want to include.
– Julie Pelletier
May 6 '16 at 23:58
I thought it was extremely clear that I want to include files that match ".foo" from a current directory. If my command didn't match that, maybe that's because I at no time indicated I was dealing with a tgz.
– cbmanica
May 7 '16 at 0:01
I suppose given thatfind . | grep "[.]thisdirectory" > files; tar -cf my.tar -T files
does what I want, this is all academic, but I get tired of SO being so willfully pedantic in response to all questions.
– cbmanica
May 7 '16 at 0:02
Without specific questions, it's exceedingly difficult to give specific answers.
– DopeGhoti
May 7 '16 at 0:06
|
show 4 more comments
up vote
0
down vote
Rather jumping on an old horse here, but, since I can't find any evidence of anyone pointing out the apparently "intended" way that this should be done with tar:
The issue, as has been noted elsewhere, is that tar is quite literal with "--include", and it won't traverse into directories foo and bar to find your .a files, if the --include filters them off first.
The clue to the trick to using tar as you'd like to use it /is/ included in the man page, but it's fairly well obfuscated: --include is "supposed" to be used to filter existing archives; Also, there is a magic argument @- that causes tar to treat a read from STDIN as a read from an existing archive.
Put together, you can use one promiscuous tar statement to create an archive of everything below the current directory, and stuff it onto STDOUT. You then pipe this into a tar that's going to use the --include option, and that reads from STDIN.
In your case, this looks something like:
tar -cf - / | tar -cf myfiles.tar --include=".a" @-
Soyokaze:test$ ls -lR
total 32
drwxr-xr-x 6 tyler staff 204 Nov 29 14:24 bar/
drwxr-xr-x 4 tyler staff 136 Nov 29 14:23 foo/
./bar:
total 0
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baa.a
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baaa.a
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baz
drwxr-xr-x 2 tyler staff 68 Nov 29 14:24 boos/
./bar/boos:
total 0
./foo:
total 0
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baa.a
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baz.a
Soyokaze:test$ tar -cf - */ | tar -cf myfiles.tar --include="*.a" @-
Soyokaze:test$ tar -tf myfiles.tar
bar/baa.a
bar/baaa.a
foo/baa.a
foo/baz.a
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
I'm assuming you're using FreeBSD tar¹ as this is the only implementation I know with a --include
option.
When you pass --include
, only explicitly included files are traversed. When building an archive, if a directory isn't traversed then neither it nor any of its contents can be included. Since you're tarring .
but not including .
, the sole command line argument doesn't get included, and you get an empty archive.
To reach the .a
directories, you would need to include all the parent directories. The thing is, if you do that, then all of their contents will be included as well. You can use --exclude
to exclude them, but then you need an exclude pattern that doesn't exclude the dot directories that you want to include. At this point --include
is no longer of any use. The --include
option is rarely useful when creating an archive, it's rather more useful when copying part of an existing archive (because when doing that, there's no recursive traversal, just iteration through the list of members of the input archive).
tar --exclude='./*/[!.]*' -cvf a.tar .
Note that all files in the toplevel directory are included. I don't think there's a way to include only those directories that will have non-empty contents.
To get only the ./*/.*
directories and nothing else (in particular not their parent directories), you need to pass them as arguments to tar, rather than let tar recurse to find them.
tar -cvf a.tar ./*/.[!.]*/
Remove the trailing slash to include files that aren't directories (or symlinks to directories). Add ./*/..?*/
to include directories whose name begins with ..
if you have those.
¹ Possibly under a different operating system.
add a comment |
up vote
1
down vote
I'm assuming you're using FreeBSD tar¹ as this is the only implementation I know with a --include
option.
When you pass --include
, only explicitly included files are traversed. When building an archive, if a directory isn't traversed then neither it nor any of its contents can be included. Since you're tarring .
but not including .
, the sole command line argument doesn't get included, and you get an empty archive.
To reach the .a
directories, you would need to include all the parent directories. The thing is, if you do that, then all of their contents will be included as well. You can use --exclude
to exclude them, but then you need an exclude pattern that doesn't exclude the dot directories that you want to include. At this point --include
is no longer of any use. The --include
option is rarely useful when creating an archive, it's rather more useful when copying part of an existing archive (because when doing that, there's no recursive traversal, just iteration through the list of members of the input archive).
tar --exclude='./*/[!.]*' -cvf a.tar .
Note that all files in the toplevel directory are included. I don't think there's a way to include only those directories that will have non-empty contents.
To get only the ./*/.*
directories and nothing else (in particular not their parent directories), you need to pass them as arguments to tar, rather than let tar recurse to find them.
tar -cvf a.tar ./*/.[!.]*/
Remove the trailing slash to include files that aren't directories (or symlinks to directories). Add ./*/..?*/
to include directories whose name begins with ..
if you have those.
¹ Possibly under a different operating system.
add a comment |
up vote
1
down vote
up vote
1
down vote
I'm assuming you're using FreeBSD tar¹ as this is the only implementation I know with a --include
option.
When you pass --include
, only explicitly included files are traversed. When building an archive, if a directory isn't traversed then neither it nor any of its contents can be included. Since you're tarring .
but not including .
, the sole command line argument doesn't get included, and you get an empty archive.
To reach the .a
directories, you would need to include all the parent directories. The thing is, if you do that, then all of their contents will be included as well. You can use --exclude
to exclude them, but then you need an exclude pattern that doesn't exclude the dot directories that you want to include. At this point --include
is no longer of any use. The --include
option is rarely useful when creating an archive, it's rather more useful when copying part of an existing archive (because when doing that, there's no recursive traversal, just iteration through the list of members of the input archive).
tar --exclude='./*/[!.]*' -cvf a.tar .
Note that all files in the toplevel directory are included. I don't think there's a way to include only those directories that will have non-empty contents.
To get only the ./*/.*
directories and nothing else (in particular not their parent directories), you need to pass them as arguments to tar, rather than let tar recurse to find them.
tar -cvf a.tar ./*/.[!.]*/
Remove the trailing slash to include files that aren't directories (or symlinks to directories). Add ./*/..?*/
to include directories whose name begins with ..
if you have those.
¹ Possibly under a different operating system.
I'm assuming you're using FreeBSD tar¹ as this is the only implementation I know with a --include
option.
When you pass --include
, only explicitly included files are traversed. When building an archive, if a directory isn't traversed then neither it nor any of its contents can be included. Since you're tarring .
but not including .
, the sole command line argument doesn't get included, and you get an empty archive.
To reach the .a
directories, you would need to include all the parent directories. The thing is, if you do that, then all of their contents will be included as well. You can use --exclude
to exclude them, but then you need an exclude pattern that doesn't exclude the dot directories that you want to include. At this point --include
is no longer of any use. The --include
option is rarely useful when creating an archive, it's rather more useful when copying part of an existing archive (because when doing that, there's no recursive traversal, just iteration through the list of members of the input archive).
tar --exclude='./*/[!.]*' -cvf a.tar .
Note that all files in the toplevel directory are included. I don't think there's a way to include only those directories that will have non-empty contents.
To get only the ./*/.*
directories and nothing else (in particular not their parent directories), you need to pass them as arguments to tar, rather than let tar recurse to find them.
tar -cvf a.tar ./*/.[!.]*/
Remove the trailing slash to include files that aren't directories (or symlinks to directories). Add ./*/..?*/
to include directories whose name begins with ..
if you have those.
¹ Possibly under a different operating system.
answered May 7 '16 at 23:09
Gilles
524k12610481578
524k12610481578
add a comment |
add a comment |
up vote
1
down vote
If your shell is bash, you can use the GLOBIGNORE
variable to hide the .
and ..
directories. This does automatically also set the dotglob
option, so *
now matches both hidden and non-hidden files:
GLOBIGNORE=".:.."
tar czf tarball-with-hidden-files.tgz directory/*
To expand on this a bit: by default, *
does not match hidden files (files starting with a .
), which includes the current (.
) and parent (..
) directories of any directory. If you want a glob (e. g. a command line wildcard) to match them, you need to set the dotglob
option, but this can cause really bad things to happen if ..
matches *
and you do something like rm -fr /home/olduser/*
(because olduser/..
matches, which is /home/
and now you've just fried everyones' home directories. Which is where GLOBIGNORE
comes into play- it blacklists things from matching wildcards. As a really simple use-case:
ghoti@home:~/scratch$ ls -ld ?dotfile
ls: cannot access '?dotfile': No such file or directory
ghoti@home:~/scratch$ touch _dotfile .dotfile
ghoti@home:~/scratch$ ls -ld ?dotfile
-rw-rw-r-- 1 ghoti ghoti 0 May 6 16:58 _dotfile
ghoti@home:~/scratch$ GLOBIGNORE=".:.."
ghoti@home:~/scratch$ ls -ld ?dotfile
-rw-rw-r-- 1 ghoti ghoti 0 May 6 16:58 _dotfile
-rw-rw-r-- 1 ghoti ghoti 0 May 6 16:58 .dotfile
What does this mean for you? Well, as in the quick example at the top of this answer, once you set GLOBIGNORE
to ignore .
and ..
, you can use *
to match hidden directories like the ones you're trying to archive:
tar czf mytarball.tgz directory/* # this will include things like directory/.hiddenfile
To point this at your specific example of a directory called .a
:
ghoti@home:~/scratch$ mkdir -p example example/foo/.a example/bar/.a example/foo/_a example/bar/_a
ghoti@home:~/scratch$ touch example/{foo,bar}/{.,_}a/file
ghoti@home:~/scratch$ find example/
example/
example/foo
example/foo/_a
example/foo/_a/file
example/foo/.a
example/foo/.a/file
example/bar
example/bar/_a
example/bar/_a/file
example/bar/.a
example/bar/.a/file
ghoti@home:~/scratch$ GLOBIGNORE=".:.."
ghoti@home:~/scratch$ tar cvzf withdotfiles.tgz example/*/?a
example/bar/_a/
example/bar/_a/file
example/bar/.a/
example/bar/.a/file
example/foo/_a/
example/foo/_a/file
example/foo/.a/
example/foo/.a/file
ghoti@home:~/scratch$ unset GLOBIGNORE
ghoti@home:~/scratch$ tar cvzf withoutdotfiles.tgz example/*/?a
example/bar/_a/
example/bar/_a/file
example/foo/_a/
example/foo/_a/file
I must be missing something, because that doesn't improve the situation at all:> GLOBIGNORE=".:.." tar --include "*[.]a*" -cvf a.tar . >
The .* directories get included just fine without--include
but trying to restrict what gets tarred fails utterly...
– cbmanica
May 6 '16 at 23:53
@cbmanica the command you show in no way resembles DopeGhoti's example nor does it*/*/.thisdirectory/*
so clarifications are needed on what files you want to include.
– Julie Pelletier
May 6 '16 at 23:58
I thought it was extremely clear that I want to include files that match ".foo" from a current directory. If my command didn't match that, maybe that's because I at no time indicated I was dealing with a tgz.
– cbmanica
May 7 '16 at 0:01
I suppose given thatfind . | grep "[.]thisdirectory" > files; tar -cf my.tar -T files
does what I want, this is all academic, but I get tired of SO being so willfully pedantic in response to all questions.
– cbmanica
May 7 '16 at 0:02
Without specific questions, it's exceedingly difficult to give specific answers.
– DopeGhoti
May 7 '16 at 0:06
|
show 4 more comments
up vote
1
down vote
If your shell is bash, you can use the GLOBIGNORE
variable to hide the .
and ..
directories. This does automatically also set the dotglob
option, so *
now matches both hidden and non-hidden files:
GLOBIGNORE=".:.."
tar czf tarball-with-hidden-files.tgz directory/*
To expand on this a bit: by default, *
does not match hidden files (files starting with a .
), which includes the current (.
) and parent (..
) directories of any directory. If you want a glob (e. g. a command line wildcard) to match them, you need to set the dotglob
option, but this can cause really bad things to happen if ..
matches *
and you do something like rm -fr /home/olduser/*
(because olduser/..
matches, which is /home/
and now you've just fried everyones' home directories. Which is where GLOBIGNORE
comes into play- it blacklists things from matching wildcards. As a really simple use-case:
ghoti@home:~/scratch$ ls -ld ?dotfile
ls: cannot access '?dotfile': No such file or directory
ghoti@home:~/scratch$ touch _dotfile .dotfile
ghoti@home:~/scratch$ ls -ld ?dotfile
-rw-rw-r-- 1 ghoti ghoti 0 May 6 16:58 _dotfile
ghoti@home:~/scratch$ GLOBIGNORE=".:.."
ghoti@home:~/scratch$ ls -ld ?dotfile
-rw-rw-r-- 1 ghoti ghoti 0 May 6 16:58 _dotfile
-rw-rw-r-- 1 ghoti ghoti 0 May 6 16:58 .dotfile
What does this mean for you? Well, as in the quick example at the top of this answer, once you set GLOBIGNORE
to ignore .
and ..
, you can use *
to match hidden directories like the ones you're trying to archive:
tar czf mytarball.tgz directory/* # this will include things like directory/.hiddenfile
To point this at your specific example of a directory called .a
:
ghoti@home:~/scratch$ mkdir -p example example/foo/.a example/bar/.a example/foo/_a example/bar/_a
ghoti@home:~/scratch$ touch example/{foo,bar}/{.,_}a/file
ghoti@home:~/scratch$ find example/
example/
example/foo
example/foo/_a
example/foo/_a/file
example/foo/.a
example/foo/.a/file
example/bar
example/bar/_a
example/bar/_a/file
example/bar/.a
example/bar/.a/file
ghoti@home:~/scratch$ GLOBIGNORE=".:.."
ghoti@home:~/scratch$ tar cvzf withdotfiles.tgz example/*/?a
example/bar/_a/
example/bar/_a/file
example/bar/.a/
example/bar/.a/file
example/foo/_a/
example/foo/_a/file
example/foo/.a/
example/foo/.a/file
ghoti@home:~/scratch$ unset GLOBIGNORE
ghoti@home:~/scratch$ tar cvzf withoutdotfiles.tgz example/*/?a
example/bar/_a/
example/bar/_a/file
example/foo/_a/
example/foo/_a/file
I must be missing something, because that doesn't improve the situation at all:> GLOBIGNORE=".:.." tar --include "*[.]a*" -cvf a.tar . >
The .* directories get included just fine without--include
but trying to restrict what gets tarred fails utterly...
– cbmanica
May 6 '16 at 23:53
@cbmanica the command you show in no way resembles DopeGhoti's example nor does it*/*/.thisdirectory/*
so clarifications are needed on what files you want to include.
– Julie Pelletier
May 6 '16 at 23:58
I thought it was extremely clear that I want to include files that match ".foo" from a current directory. If my command didn't match that, maybe that's because I at no time indicated I was dealing with a tgz.
– cbmanica
May 7 '16 at 0:01
I suppose given thatfind . | grep "[.]thisdirectory" > files; tar -cf my.tar -T files
does what I want, this is all academic, but I get tired of SO being so willfully pedantic in response to all questions.
– cbmanica
May 7 '16 at 0:02
Without specific questions, it's exceedingly difficult to give specific answers.
– DopeGhoti
May 7 '16 at 0:06
|
show 4 more comments
up vote
1
down vote
up vote
1
down vote
If your shell is bash, you can use the GLOBIGNORE
variable to hide the .
and ..
directories. This does automatically also set the dotglob
option, so *
now matches both hidden and non-hidden files:
GLOBIGNORE=".:.."
tar czf tarball-with-hidden-files.tgz directory/*
To expand on this a bit: by default, *
does not match hidden files (files starting with a .
), which includes the current (.
) and parent (..
) directories of any directory. If you want a glob (e. g. a command line wildcard) to match them, you need to set the dotglob
option, but this can cause really bad things to happen if ..
matches *
and you do something like rm -fr /home/olduser/*
(because olduser/..
matches, which is /home/
and now you've just fried everyones' home directories. Which is where GLOBIGNORE
comes into play- it blacklists things from matching wildcards. As a really simple use-case:
ghoti@home:~/scratch$ ls -ld ?dotfile
ls: cannot access '?dotfile': No such file or directory
ghoti@home:~/scratch$ touch _dotfile .dotfile
ghoti@home:~/scratch$ ls -ld ?dotfile
-rw-rw-r-- 1 ghoti ghoti 0 May 6 16:58 _dotfile
ghoti@home:~/scratch$ GLOBIGNORE=".:.."
ghoti@home:~/scratch$ ls -ld ?dotfile
-rw-rw-r-- 1 ghoti ghoti 0 May 6 16:58 _dotfile
-rw-rw-r-- 1 ghoti ghoti 0 May 6 16:58 .dotfile
What does this mean for you? Well, as in the quick example at the top of this answer, once you set GLOBIGNORE
to ignore .
and ..
, you can use *
to match hidden directories like the ones you're trying to archive:
tar czf mytarball.tgz directory/* # this will include things like directory/.hiddenfile
To point this at your specific example of a directory called .a
:
ghoti@home:~/scratch$ mkdir -p example example/foo/.a example/bar/.a example/foo/_a example/bar/_a
ghoti@home:~/scratch$ touch example/{foo,bar}/{.,_}a/file
ghoti@home:~/scratch$ find example/
example/
example/foo
example/foo/_a
example/foo/_a/file
example/foo/.a
example/foo/.a/file
example/bar
example/bar/_a
example/bar/_a/file
example/bar/.a
example/bar/.a/file
ghoti@home:~/scratch$ GLOBIGNORE=".:.."
ghoti@home:~/scratch$ tar cvzf withdotfiles.tgz example/*/?a
example/bar/_a/
example/bar/_a/file
example/bar/.a/
example/bar/.a/file
example/foo/_a/
example/foo/_a/file
example/foo/.a/
example/foo/.a/file
ghoti@home:~/scratch$ unset GLOBIGNORE
ghoti@home:~/scratch$ tar cvzf withoutdotfiles.tgz example/*/?a
example/bar/_a/
example/bar/_a/file
example/foo/_a/
example/foo/_a/file
If your shell is bash, you can use the GLOBIGNORE
variable to hide the .
and ..
directories. This does automatically also set the dotglob
option, so *
now matches both hidden and non-hidden files:
GLOBIGNORE=".:.."
tar czf tarball-with-hidden-files.tgz directory/*
To expand on this a bit: by default, *
does not match hidden files (files starting with a .
), which includes the current (.
) and parent (..
) directories of any directory. If you want a glob (e. g. a command line wildcard) to match them, you need to set the dotglob
option, but this can cause really bad things to happen if ..
matches *
and you do something like rm -fr /home/olduser/*
(because olduser/..
matches, which is /home/
and now you've just fried everyones' home directories. Which is where GLOBIGNORE
comes into play- it blacklists things from matching wildcards. As a really simple use-case:
ghoti@home:~/scratch$ ls -ld ?dotfile
ls: cannot access '?dotfile': No such file or directory
ghoti@home:~/scratch$ touch _dotfile .dotfile
ghoti@home:~/scratch$ ls -ld ?dotfile
-rw-rw-r-- 1 ghoti ghoti 0 May 6 16:58 _dotfile
ghoti@home:~/scratch$ GLOBIGNORE=".:.."
ghoti@home:~/scratch$ ls -ld ?dotfile
-rw-rw-r-- 1 ghoti ghoti 0 May 6 16:58 _dotfile
-rw-rw-r-- 1 ghoti ghoti 0 May 6 16:58 .dotfile
What does this mean for you? Well, as in the quick example at the top of this answer, once you set GLOBIGNORE
to ignore .
and ..
, you can use *
to match hidden directories like the ones you're trying to archive:
tar czf mytarball.tgz directory/* # this will include things like directory/.hiddenfile
To point this at your specific example of a directory called .a
:
ghoti@home:~/scratch$ mkdir -p example example/foo/.a example/bar/.a example/foo/_a example/bar/_a
ghoti@home:~/scratch$ touch example/{foo,bar}/{.,_}a/file
ghoti@home:~/scratch$ find example/
example/
example/foo
example/foo/_a
example/foo/_a/file
example/foo/.a
example/foo/.a/file
example/bar
example/bar/_a
example/bar/_a/file
example/bar/.a
example/bar/.a/file
ghoti@home:~/scratch$ GLOBIGNORE=".:.."
ghoti@home:~/scratch$ tar cvzf withdotfiles.tgz example/*/?a
example/bar/_a/
example/bar/_a/file
example/bar/.a/
example/bar/.a/file
example/foo/_a/
example/foo/_a/file
example/foo/.a/
example/foo/.a/file
ghoti@home:~/scratch$ unset GLOBIGNORE
ghoti@home:~/scratch$ tar cvzf withoutdotfiles.tgz example/*/?a
example/bar/_a/
example/bar/_a/file
example/foo/_a/
example/foo/_a/file
edited May 7 '16 at 23:11
Gilles
524k12610481578
524k12610481578
answered May 6 '16 at 23:50
DopeGhoti
42.9k55382
42.9k55382
I must be missing something, because that doesn't improve the situation at all:> GLOBIGNORE=".:.." tar --include "*[.]a*" -cvf a.tar . >
The .* directories get included just fine without--include
but trying to restrict what gets tarred fails utterly...
– cbmanica
May 6 '16 at 23:53
@cbmanica the command you show in no way resembles DopeGhoti's example nor does it*/*/.thisdirectory/*
so clarifications are needed on what files you want to include.
– Julie Pelletier
May 6 '16 at 23:58
I thought it was extremely clear that I want to include files that match ".foo" from a current directory. If my command didn't match that, maybe that's because I at no time indicated I was dealing with a tgz.
– cbmanica
May 7 '16 at 0:01
I suppose given thatfind . | grep "[.]thisdirectory" > files; tar -cf my.tar -T files
does what I want, this is all academic, but I get tired of SO being so willfully pedantic in response to all questions.
– cbmanica
May 7 '16 at 0:02
Without specific questions, it's exceedingly difficult to give specific answers.
– DopeGhoti
May 7 '16 at 0:06
|
show 4 more comments
I must be missing something, because that doesn't improve the situation at all:> GLOBIGNORE=".:.." tar --include "*[.]a*" -cvf a.tar . >
The .* directories get included just fine without--include
but trying to restrict what gets tarred fails utterly...
– cbmanica
May 6 '16 at 23:53
@cbmanica the command you show in no way resembles DopeGhoti's example nor does it*/*/.thisdirectory/*
so clarifications are needed on what files you want to include.
– Julie Pelletier
May 6 '16 at 23:58
I thought it was extremely clear that I want to include files that match ".foo" from a current directory. If my command didn't match that, maybe that's because I at no time indicated I was dealing with a tgz.
– cbmanica
May 7 '16 at 0:01
I suppose given thatfind . | grep "[.]thisdirectory" > files; tar -cf my.tar -T files
does what I want, this is all academic, but I get tired of SO being so willfully pedantic in response to all questions.
– cbmanica
May 7 '16 at 0:02
Without specific questions, it's exceedingly difficult to give specific answers.
– DopeGhoti
May 7 '16 at 0:06
I must be missing something, because that doesn't improve the situation at all:
> GLOBIGNORE=".:.." tar --include "*[.]a*" -cvf a.tar . >
The .* directories get included just fine without --include
but trying to restrict what gets tarred fails utterly...– cbmanica
May 6 '16 at 23:53
I must be missing something, because that doesn't improve the situation at all:
> GLOBIGNORE=".:.." tar --include "*[.]a*" -cvf a.tar . >
The .* directories get included just fine without --include
but trying to restrict what gets tarred fails utterly...– cbmanica
May 6 '16 at 23:53
@cbmanica the command you show in no way resembles DopeGhoti's example nor does it
*/*/.thisdirectory/*
so clarifications are needed on what files you want to include.– Julie Pelletier
May 6 '16 at 23:58
@cbmanica the command you show in no way resembles DopeGhoti's example nor does it
*/*/.thisdirectory/*
so clarifications are needed on what files you want to include.– Julie Pelletier
May 6 '16 at 23:58
I thought it was extremely clear that I want to include files that match ".foo" from a current directory. If my command didn't match that, maybe that's because I at no time indicated I was dealing with a tgz.
– cbmanica
May 7 '16 at 0:01
I thought it was extremely clear that I want to include files that match ".foo" from a current directory. If my command didn't match that, maybe that's because I at no time indicated I was dealing with a tgz.
– cbmanica
May 7 '16 at 0:01
I suppose given that
find . | grep "[.]thisdirectory" > files; tar -cf my.tar -T files
does what I want, this is all academic, but I get tired of SO being so willfully pedantic in response to all questions.– cbmanica
May 7 '16 at 0:02
I suppose given that
find . | grep "[.]thisdirectory" > files; tar -cf my.tar -T files
does what I want, this is all academic, but I get tired of SO being so willfully pedantic in response to all questions.– cbmanica
May 7 '16 at 0:02
Without specific questions, it's exceedingly difficult to give specific answers.
– DopeGhoti
May 7 '16 at 0:06
Without specific questions, it's exceedingly difficult to give specific answers.
– DopeGhoti
May 7 '16 at 0:06
|
show 4 more comments
up vote
0
down vote
Rather jumping on an old horse here, but, since I can't find any evidence of anyone pointing out the apparently "intended" way that this should be done with tar:
The issue, as has been noted elsewhere, is that tar is quite literal with "--include", and it won't traverse into directories foo and bar to find your .a files, if the --include filters them off first.
The clue to the trick to using tar as you'd like to use it /is/ included in the man page, but it's fairly well obfuscated: --include is "supposed" to be used to filter existing archives; Also, there is a magic argument @- that causes tar to treat a read from STDIN as a read from an existing archive.
Put together, you can use one promiscuous tar statement to create an archive of everything below the current directory, and stuff it onto STDOUT. You then pipe this into a tar that's going to use the --include option, and that reads from STDIN.
In your case, this looks something like:
tar -cf - / | tar -cf myfiles.tar --include=".a" @-
Soyokaze:test$ ls -lR
total 32
drwxr-xr-x 6 tyler staff 204 Nov 29 14:24 bar/
drwxr-xr-x 4 tyler staff 136 Nov 29 14:23 foo/
./bar:
total 0
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baa.a
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baaa.a
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baz
drwxr-xr-x 2 tyler staff 68 Nov 29 14:24 boos/
./bar/boos:
total 0
./foo:
total 0
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baa.a
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baz.a
Soyokaze:test$ tar -cf - */ | tar -cf myfiles.tar --include="*.a" @-
Soyokaze:test$ tar -tf myfiles.tar
bar/baa.a
bar/baaa.a
foo/baa.a
foo/baz.a
add a comment |
up vote
0
down vote
Rather jumping on an old horse here, but, since I can't find any evidence of anyone pointing out the apparently "intended" way that this should be done with tar:
The issue, as has been noted elsewhere, is that tar is quite literal with "--include", and it won't traverse into directories foo and bar to find your .a files, if the --include filters them off first.
The clue to the trick to using tar as you'd like to use it /is/ included in the man page, but it's fairly well obfuscated: --include is "supposed" to be used to filter existing archives; Also, there is a magic argument @- that causes tar to treat a read from STDIN as a read from an existing archive.
Put together, you can use one promiscuous tar statement to create an archive of everything below the current directory, and stuff it onto STDOUT. You then pipe this into a tar that's going to use the --include option, and that reads from STDIN.
In your case, this looks something like:
tar -cf - / | tar -cf myfiles.tar --include=".a" @-
Soyokaze:test$ ls -lR
total 32
drwxr-xr-x 6 tyler staff 204 Nov 29 14:24 bar/
drwxr-xr-x 4 tyler staff 136 Nov 29 14:23 foo/
./bar:
total 0
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baa.a
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baaa.a
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baz
drwxr-xr-x 2 tyler staff 68 Nov 29 14:24 boos/
./bar/boos:
total 0
./foo:
total 0
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baa.a
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baz.a
Soyokaze:test$ tar -cf - */ | tar -cf myfiles.tar --include="*.a" @-
Soyokaze:test$ tar -tf myfiles.tar
bar/baa.a
bar/baaa.a
foo/baa.a
foo/baz.a
add a comment |
up vote
0
down vote
up vote
0
down vote
Rather jumping on an old horse here, but, since I can't find any evidence of anyone pointing out the apparently "intended" way that this should be done with tar:
The issue, as has been noted elsewhere, is that tar is quite literal with "--include", and it won't traverse into directories foo and bar to find your .a files, if the --include filters them off first.
The clue to the trick to using tar as you'd like to use it /is/ included in the man page, but it's fairly well obfuscated: --include is "supposed" to be used to filter existing archives; Also, there is a magic argument @- that causes tar to treat a read from STDIN as a read from an existing archive.
Put together, you can use one promiscuous tar statement to create an archive of everything below the current directory, and stuff it onto STDOUT. You then pipe this into a tar that's going to use the --include option, and that reads from STDIN.
In your case, this looks something like:
tar -cf - / | tar -cf myfiles.tar --include=".a" @-
Soyokaze:test$ ls -lR
total 32
drwxr-xr-x 6 tyler staff 204 Nov 29 14:24 bar/
drwxr-xr-x 4 tyler staff 136 Nov 29 14:23 foo/
./bar:
total 0
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baa.a
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baaa.a
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baz
drwxr-xr-x 2 tyler staff 68 Nov 29 14:24 boos/
./bar/boos:
total 0
./foo:
total 0
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baa.a
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baz.a
Soyokaze:test$ tar -cf - */ | tar -cf myfiles.tar --include="*.a" @-
Soyokaze:test$ tar -tf myfiles.tar
bar/baa.a
bar/baaa.a
foo/baa.a
foo/baz.a
Rather jumping on an old horse here, but, since I can't find any evidence of anyone pointing out the apparently "intended" way that this should be done with tar:
The issue, as has been noted elsewhere, is that tar is quite literal with "--include", and it won't traverse into directories foo and bar to find your .a files, if the --include filters them off first.
The clue to the trick to using tar as you'd like to use it /is/ included in the man page, but it's fairly well obfuscated: --include is "supposed" to be used to filter existing archives; Also, there is a magic argument @- that causes tar to treat a read from STDIN as a read from an existing archive.
Put together, you can use one promiscuous tar statement to create an archive of everything below the current directory, and stuff it onto STDOUT. You then pipe this into a tar that's going to use the --include option, and that reads from STDIN.
In your case, this looks something like:
tar -cf - / | tar -cf myfiles.tar --include=".a" @-
Soyokaze:test$ ls -lR
total 32
drwxr-xr-x 6 tyler staff 204 Nov 29 14:24 bar/
drwxr-xr-x 4 tyler staff 136 Nov 29 14:23 foo/
./bar:
total 0
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baa.a
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baaa.a
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baz
drwxr-xr-x 2 tyler staff 68 Nov 29 14:24 boos/
./bar/boos:
total 0
./foo:
total 0
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baa.a
-rw-r--r-- 1 tyler staff 0 Nov 29 14:23 baz.a
Soyokaze:test$ tar -cf - */ | tar -cf myfiles.tar --include="*.a" @-
Soyokaze:test$ tar -tf myfiles.tar
bar/baa.a
bar/baaa.a
foo/baa.a
foo/baz.a
answered Nov 29 at 19:33
W Ray
1
1
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f281624%2fcorrect-syntax-for-including-directories-with-tar%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown