Bypass `-C` flag when unzipping tar archive - devops

I have a .tar.gz archive with the following structure:
opt/client/py/utils/mappings/templates/config.json
opt/
opt/mag/
opt/mag/sw/
opt/mag/sw/apps/
opt/mag/sw/apps/service/
opt/mag/etc/
opt/mag/etc/service.environment
opt/mag/etc/service.toml
And this .tar.gz archive is extracted using this command:
tar -zxf ../service.tar.gz -C opt/mag/ --strip-components=2
Thee issue is this will extract the opt/client/py/utils/mappings/templates/config.json file inside opt/mag so it will become: opt/mag/py/utils/mappings/templates/config.json which is obviously wrong. Notice the removal of opt/client/ by --strip-components=2.
The issue is that I cannot change the unzip command
I've tried to hack it around by inserting 2 dummy directories to bypass --strip-components=2 something like this:
dummy1/dummy2/opt/client/py/utils/mappings/templates/config.json
opt/
opt/mag/
opt/mag/sw/
opt/mag/sw/apps/
opt/mag/sw/apps/service/
opt/mag/etc/
opt/mag/etc/service.environment
opt/mag/etc/service.toml
This way --strip-components=2 will remove dummy1/dummy2 and the config file will be extracted to /opt/mag/opt/client/py/utils/mappings/templates/config.json which is still wrong, because that -C opt/mag will force the extraction inside opt/mag.
Given the fact that I cannot change the unzip command is there anyway to bypass the -C switch or some way to hack it around?
Also, I cannot edit or move files on the container where this archive is extracted

Related

tar: unable to include folder but exclude content

I have a project folder with several directories
- archive
- include
- lib
- src
- src/obj (obj is a subdirectory of src)
I would like tar to pack these directories and their contents into a main.tar, then I will the main.tar into the archive directory.
tar cvz \
--exclude="*.obsolete" --exclude="*DS_Store" --exclude="./archive/*" \
-f main.tar \
./archive ./include ./lib ./src
I would like to exclude the contents of the archive directory but still package the empty directory itself. You can see I am also excluding some other stuff from various places, OSX likes to write .DS_Store files everywhere on my filesystem and I occasionally make copies of files and append .obsolete to the end while working on a new version.
Unfortunately, the empty archive directory is not included in main.tar.
According to this thread, my command should work.
How can the files be excluded from archive but the empty directory be packed into the tar file?
edit
The following fails:
--exclude="./archive/*"
The following works:
--exclude="./archive/*.*"
So the whole command is:
tar cvz \
--exclude="*.obsolete" --exclude="*DS_Store" --exclude="./archive/*.*" \
-f main.tar \
./archive ./include ./lib ./src

How to use gcovr with source files outside the current/build/run directory?

mkdir -p /tmp/build &&
cd /tmp/build &&
mkdir -p /tmp/src &&
echo "int main(){return 0;}" > /tmp/src/prog.c &&
gcc --coverage -o prog /tmp/src/prog.c &&
./prog &&
gcovr -v -r .
will output an empty report.
Scanning directory . for gcda/gcno files...
Found 2 files (and will process 1)
Processing file: /tmp/build/prog.gcda
Running gcov: 'gcov /tmp/build/prog.gcda --branch-counts --branch-probabilities --preserve-paths --object-directory /tmp/build' in '/tmp/build'
Finding source file corresponding to a gcov data file
currdir /tmp/build
gcov_fname #tmp#src#prog.c.gcov
[' -', ' 0', 'Source', '/tmp/src/prog.c\n']
source_fname /tmp/build/prog.gcda
root /tmp/build
fname /tmp/src/prog.c
Parsing coverage data for file /tmp/src/prog.c
Filtering coverage data for file /tmp/src/prog.c
Gathered coveraged data for 0 files
------------------------------------------------------------------------------
GCC Code Coverage Report
Directory: .
------------------------------------------------------------------------------
File Lines Exec Cover Missing
------------------------------------------------------------------------------
------------------------------------------------------------------------------
TOTAL 0 0 --%
------------------------------------------------------------------------------
However if I manually run
gcov /tmp/build/prog.gcda --branch-counts --branch-probabilities --preserve-paths --object-directory /tmp/build
I get correct results
File '/tmp/src/prog.c'
Lines executed:100.00% of 1
No branches
No calls
Creating '#tmp#src#prog.c.gcov'
It seems that gcovr did not extract the coverage from the otherwise correct gcov output. This only happens if the source file is outside the current directory (same as build directory, same as output directory, same as run directory), and gcc ics called with an absolute path to the source file.
How can I fix this?
Edit
Fixed in upstream gcovr for relative paths, but looks like a bug for absolute paths.
See https://github.com/gcovr/gcovr/issues/169.
What I understood from your code up there is that you made everything and ran the program but you are still inside build directory where the object file resides.
So, what you need to understand is:
gcovr -v -r <path>
this -r flag takes the root directory, which means the parent directory inside which the source and object directory resides. So that it can trace them both and generate coverage data and whatever else you want it to generate.
Try doing that and it will work.
For your understanding:
The .gcno files that gets generated after compilation is just the flowchart kind of data for that particular source file.
Then later when you execute the program, a .gcda file gets generated for each source file. This file contains real coverage data, but for gcovr all these three files are necessary (.gcno, .gcda, sourceFile)
Hope it helped. :)
update:
Back with the work around
You can supply your coverage data location as a pure arg (no option) and point the root to your sources.
gcovr .../path/To/GCDA -r .../path/to/src/ [rest desired flags]
This will solve your problem for sure.
Worked for me in covering my projects.
Gcovr only generates reports for source files within your project. This is intended to exclude coverage from library headers etc.
The question is, which files are in your project? This is determined by the -r root path.
If you are in /tmp/build and root is . aka /tmp/build and the source file is /tmp/src/prog.c, then that source file is clearly outside of your project. In the verbose output, gcovr will report Filtering coverage data for file /tmp/src/prog.c.
If you are in /tmp/build and root is .. aka /tmp and the source file is /tmp/src/prog.c, then that source file is within the project.
If you are in /tmp/build and root is . aka /tmp/build and the source file is ../src/prog.c, then gcovr seems to do something questionable: It joins the file name with the current directory and checks that. So we actually see /tmp/build/../src/prog.c. As far as gcovr is concerned, that's within your project. It seems this behaviour is necessary to include code that is symlinked into a project.
You can disable this “is the source within the project?” filter by providing your own, better filter. For example, you can ask gcovr to only report coverage for sources under /tmp/src:
gcovr -r . -f /tmp/src

extract a file from xz file

I have a huge file file.tar.xz containing many smaller text files with a similar structure. I want to quickly examine a file out of the compressed file and have a glimpse of files content structure. I don't have information about names of the files within the compressed file. Is there anyway to extract a single file out given the above the above scenario?
Thank you.
EDIT: I don't want to tar -xvf file.tar.xz.
Based on the discussion in the comments, I tried the following which worked for me. It might not be the most optimal solution, the regex might need some improvement, but you'll get the idea.
I first created a demo archive:
cd /tmp
mkdir demo
for i in {1..100}; do echo $i > "demo/$i.txt"; done
cd demo && tar cfJ ../demo.tar.xz * && cd ..
demo.tar.xz now contains 100 txt files.
The following lists the contents of the archive, selects the first file and stores the path within the archive into the variable firstfile:
firstfile=`tar -tvf demo.tar.xz | grep -Po -m1 "(?<=:[0-9]{2} ).*$"`
echo $firstfile will output 1.txt.
You can now extract this single file from the archive:
tar xf demo.tar.xz $firstfile

How to tar my C++ files on a linux server?

I know this is a simple question, but I'm not sure why the tar process isn't working and I can't find a definitive answer on here. When doing the tar command:
tar -cvjf<assign2comp.tar.bz2> <assign2.cpp header.cpp header.h>
I'm getting the error, Missing name for redirect.
Our professor shows this code as the example so I'm not sure what I'm doing wrong.
tar -cvjf<filename.tar.bz2> <files you want in archive>
Then to extract:
tar -jxvf filename.tar.bz2
So I want to archive the assign2.cpp header.cpp and header.h files then test the extract command to make sure I can access them.
Thanks for the help!
drop the < and > characters from commands. e.g. tar -cvjf assign2comp.tar.bz2 assign2.cpp header.cpp header.h
When you were told to use <file> it means to write your filename there, without < and >. So:
tar -cvjf assign2comp.tar.bz2 assign2.cpp header.cpp header.h
This is a common convention on Unix: <file> means a filename is required, [host] means a host is optional, and so on.

Unpack tar.gz folder to part of filename

I have a file dagens_130325.tar.gz containing the folder dagens. In one folder I have hundreds of these daily info. I would like to unpack dagens_130325.tar.gz/dagens to 130325 with all the files inside. Then 130326 etc.
Is there a way to do it?
Not sure this is the right stack where to ask this kind of question, however try with
tar -zxvf dagens_130325.tar.gz -C /tmp/130325 dagens
This way, the folder dagens for the archive dagens_130325.tar.gz is going to be extracted into /tmp/130325. However, note that the target folder must exist, otherwise the command will fail
So, supposedly you have 4 archives in the form dagens_1.tar.gz, dagens_2.tar.gz, ..., you can write an extract.sh file containing
#!/bin/bash
for i in {1..4}
do
mkdir /tmp/$i
FILE="dagens_$i.tar.gz"
tar -zxvf $FILE -C /tmp/$i dagens
done
Having this file the execute permission, being in the same folder as your archives and executing it should produced the result you asked.
This was the solution I came up with in the end
#!/bin/bash
search_dir=/yourdir/with/tar.gz
for entry in "$search_dir"/*.tar.gz
do
substring=$(basename "$entry")
echo $substring
sub2=${substring:7:6}
tar -xvzf $substring
rm -rf $sub2
mv dagens $sub2
done
use
#!/bin/bash
for file in dagens_*.tar.gz
do
from=${file%_*} #removes chars after _
to=${file#*_} #removes chars before _
to=${to%.t*} #removes chars after .t (.tar.gz)
tar -zxf $file --show-transformed --transform "s/$from/$to/"
done

Resources