How to download a file in a shell script after connecting to another server via ssh? - linux

My goal:
having a shellscript for a cronjob (on MacOSX Snow Leopard) that connects to a Debian machine with ssh (public/private key login), executes a tar command and downloads the tarred file afterwards.
My problem:
The login works, also the execution of some commands. But how can I download a file back to the local machine?
This is what I have so far:
This is the content of the shell script so far:
#!/bin/bash
ssh user#remotehost << 'ENDSSH'
tar -C / -czf /home/user/stuff.tar.gz /home/user/stuff
ENDSSH

Short and simple, no heredoc needed.
ssh -Te none user#remotehost "tar -C / -cz /home/user/stuff" >stuff.tar.gz

Stream it back.
#!/bin/bash
ssh user#remotehost << 'ENDSSH' > stuff.tar.gz
tar -C / -czf - /home/user/stuff
ENDSSH

this might be want you want.
scp stuff.tar.gz user#remotehost:/"directory to place this file"/

Simply rsync the file once it's created:
#!/bin/bash
ssh user#remotehost tar -C / -czf /home/user/stuff.tar.gz /home/user/stuff
rsync -chavP --stats user#remotehost:/home/user/stuff.tar.gz .
This does initiate a second connection to remotehost but will save you copying data across the network when the file has not changed (much) since the last time it was archived.

Why downloading the tar file and not create the tar content on stdout?
Ie:
ssh user#machine '(' cd /the/dir '&&' tar cf - list of files ')' >archive.tar

I. How to compress files or folders via SSH
For different compressed formats, you need to use different command lines:
Zip
To compress a file or folder to a zip file:
zip -r file.zip file
Bz2
To compress a file (ONLY) to a bz2 file:
Bzip2 -zk file
Gz
To compress a file (ONLY) to a gz file:
gzip -c file > file.gz
By the way, you need to change the above "file" to the file name with extension (if any) you want to compress, while you can replace the following "xxx" with any keywords:
Tar
To compress one file or folder to a tar file:
tar -cvf xxx.tar file
To compress multiple files and/or folders to a tar file:
tar -cvf xxx.tar file1 file2 folder1 folder2 ...
Tar.bz2
To compress one file or folder to a tar.bz2 file:
tar -cvjf xxx.tar.bz2 file
To compress multiple files and/or folders to a tar.bz2 file:
tar -cvjf xxx.tar.bz2 file1 file2 folder1 folder2 ...
Tar.gz
To compress one file or folder to a tar.gz file:
tar -cvzf xxx.tar.gz file
To compress multiple files and/or folders to a tar.gz file:
tar -cvzf xxx.tar.gz file1 file2 folder1 folder2 ...
II. How to extract file via SSH
To extract a file will be easier, since you don't need to worry about folders:
Zip
To extract a zip file:
unzip file.zip
Bz2
To extract a bz2 file:
bunzip2 file.bz2
Gz
To extract a gz file:
gzip -d file.gz
Tar
To extract a tar file:
tar -xvf file.tar
Tar.bz2
To extract a tar.bz2 file:
tar -xvjf file.tar.bz2
Tar.gz
To extract a tar.gz file:
tar -xvzf file.tar.gz
By the way, you need to replace the above "file"s of the compressed files with the real file names.
Bonus:
Besides remote servers, the above command lines are also available for a Mac OS computer with the Terminal application.

Related

Archive all the files from source directory into a xyz.gz file and move that to target directory using UNIX shell script

Requirement: Archive files using UNIX shell script into .gz format without directory structure
I am using below command
tar -C source_dir -zcvf target_dir/xyz.gz source_dir
example:
tar -C /home/log -zcvf /home/archive/xyz.gz /home/log
here xyz.gz contains /home/log
It's creating xyz.gz file maintaining the directory structure. I want only files to be archive without directory structure.
You can try the following command:
$ cd /home/log
$ tar zcvf /home/archive/xyz.gz *
You can use the --transform option to strip leading path components from the archived file names using a sed espression:
tar -C /home/log -zcvf /home/archive/xyz.gz --transform 's_.*/__' /home/log
This however will also write an entry for each encountered directory. If you don't want that, you can use find to find only regular files and pass them to tar on stdin like this:
cd /home/log
find -type f -print0 | tar -zcvf /home/archive/xyz.gz --transform 's_.*/__' --verbatim-files-from --null -T -
Note that this may create multiple entries with the same name in the tar archive, if files with the same name exist in different subdirectories. Also you should probably use the conventional .tar.gz or .tgz extension for the compressed tar archive.

Staying in another folder, how can i tar specific files from another directory?

Thanks for your support,
I have the following folder structure on my linux laptop
/home
/A
/B
In folder "B", I have files of type *.csv, *.dat.
Now from folder A, How can I create a tar file containing files *.csv in folder B. I am running the command in folder A
Here is the command, I have tried but its not working,
In /home/A folder, I am running the following command
tar -cf /home/A/Sample1.tar -C /home/B/ZSBSDP4 *.csv
and also tried with this,
tar -cf /home/A/Sample1.tar -C /home/B/ZSBSDP4 --wildcards *.csv
For both of the commands, I get the following error,
tar: *.csv: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
In the tar file, I dont want to include the whole folder structure and this is the reason, I am using option -C (capital)
Moreover, the following command works but it tars all *.csv and *.dat files.
tar -cf /home/A/Sample1.tar -C /home/B/ZSBSDP4 .
You can edit the names in the tar command to remove the path. (Assuming that you have GNU tar.)
tar -cf /home/A/Sample1.tar --transform 's,.*/\([^/]*\),\1,' /home/B/ZSBSDP4/*.csv
Note that if you specify more source directories on the command, you could accidentally put more than one file with the same name in the tar file. Then when unpacking, the last one will overwrite those with the same name that precede it.
You can use the --exclude=PATTERN option:
tar -cf /home/A/Sample1.tar -C /home/B/ZSBSDP4 . --exclude=*.dat
Other "local file selection" options listed in the man page: http://linux.die.net/man/1/tar

Unzip a single file in a tbz archive

I have the following archived directory:
itunes20140618.tbz
I want to extract single file from it called:
itunes20140618/video
How would I do this?
So far, I am doing
$ bzip2 -d /tmp/itunes20140618.tbz
But it seems to create a tar directory of everything. How would I extract just the single video file?
There are a few different versions of tar around, but on my machine I can do this:
tar xjf archive.tbz filename
To extract filename from archive.
If that doesn't work you can use:
bzip2 -dc archive.tbz | tar xvf - filename
Which uses bzip2 to extract to stdout and then pipe to tar.
In both cases you can replace the x option with t to get a list of files. Eg:
tar tjf archive.tbz
You can use the tar command and pass the path of the desired file or folder as an argument to it:
tar xjf test.tbz /path/to/file/in/archive

How do I tar a directory without retaining the directory structure?

I'm working on a backup script and want to tar up a file directory:
tar czf ~/backup.tgz /home/username/drupal/sites/default/files
This tars it up, but when I untar the resulting file, it includes the full file structure: the files are in home/username/drupal/sites/default/files.
Is there a way to exclude the parent directories, so that the resulting tar just knows about the last directory (files)?
Use the --directory option:
tar czf ~/backup.tgz --directory=/home/username/drupal/sites/default files
Hi I've a better solution when enter in the specified directory it's impossible (Makefiles,etc)
tar -cjvf files.tar.bz2 -C directory/contents/to/be/compressed .
Do not forget the dot (.) at the end !!
cd /home/username/drupal/sites/default/files
tar czf ~/backup.tgz *
Create a tar archive
tar czf $sourcedir/$backup_dir.tar --directory=$sourcedir WEB-INF en
Un-tar files on a local machine
tar -xvf $deploydir/med365/$backup_dir.tar -C $deploydir/med365/
Upload to a server
scp -r -i $privatekey $sourcedir/$backup_dir.tar $server:$deploydir/med365/
echo "File uploaded.. deployment folders"
Un-tar on server
ssh -i $privatekey $server tar -xvf $deploydir/med365/$backup_dir.tar -C $deploydir/med365/
To gunzip all txt (*.txt) files from /home/myuser/workspace/zip_from/
to /home/myuser/workspace/zip_to/ without directory structure of source files use following command:
tar -P -cvzf /home/myuser/workspace/zip_to/mydoc.tar.gz --directory="/home/myuser/workspace/zip_from/" *.txt
If you want to tar files while keeping the structure but ignore it partially or completely when extracting, use the --strip-components argument when extracting.
In this case, where the full path is /home/username/drupal/sites/default/files, the following command would extract the tar.gz content without the full parent directory structure, keeping only the last directory of the path (e.g. files/file1).
tar -xzv --strip-components=5 -f backup.tgz
I've found this tip on https://www.baeldung.com/linux/tar-archive-without-directory-structure#5-using-the---strip-components-option.
To build on nbt's and MaikoID's solutions:
tar -czf destination.tar.gz -C source/directory $(ls source/directory)
This solution:
Includes all files and folders in the directory
Does not include any of the directory structure (or .) in the final product
Does not require you to change directories.
However, it requires the directory to be given twice, so it may be most useful in another script. It may also be less efficient if there are a lot of files/folders in source/directory. Adjust the subcommand as necessary.
So for instance for the following structure:
|- source
| |- one
| `- two
`- working
the following command:
working$ tar -czf destination.tar.gz -C ../source $(ls ../source)
will produce destination.tar.gz where both one and two (and sub-files/-folders) are the first items.
This worked for me:
gzip -dc "<your_file>.tgz" | tar x -C <location>
For me -C or --directory did not work, I use this
cd source/directory/or/file
tar -cvzf destination/packaged-app.tgz *.jar
# this will put your current directory to what it previously was
cd -
Kindly use the below command to generate tar file without directory structure
tar -C <directoryPath> -cvzf <Path of the tar.gz file> filename1 filename2... filename N
eg:
tar -C /home/project/files -cvzf /home/project/files/test.tar.gz text1.txt text2.txt
tar -Cczf ~/backup.tgz /home/username/drupal/sites/default/files
-C does the cd for you

Updating a single file in a compressed tar

Given a compressed archive file such as application.tar.gz which has a folder application/x/y/z.jar among others, I'd like to be able to take my most recent version of z.jar and update/refresh the archive with it.
Is there a way to do this other than something like the following?
tar -xzf application.tar.gz
cp ~/myupdatedfolder/z.jar application/x/y
tar -czf application application.tar.gz
I understand the -u switch in tar may be of use to avoid having to untar the whole thing, but I'm unsure how to use it exactly.
Well, I found the answer.
You can't use tar -u with a zipped archive. So the solution I used was the following. Note that I moved the z.jar file to a folder I created in the current directory called application/x/y for this purpose.
gzip -d application.tar.gz
tar -uf application.tar application/x/y/z.jar
gzip application.tar
When I did a tar -tf application.tar (after the update, before the gzip) it showed up properly.
If the file you want to update is text file. Then you can use vim editor directly to open the tarball that contains the file and open it, just like open folder using vim editor. Then modify the file and save it and quit.
However, if the file is a binary. I have no idea about the solution.
in my case, I had to delete the file and then add the new file with the following steps:
my tar file
file.tar
└── foo.json
└── bar.json
└── dir
└── zoo.json
and I wanted only to modify/update foo.json file without extracting and re-creating the whole tar file file.tar, Here are the commands:
tar -x -f file.tar foo.json # extract only foo.json file to my current location
# now modify the file foo.json as you want ...
tar --delete -f file.tar foo.json # delete the foo.json file from the file.tar
tar -uf file.tar foo.json # add the specific file foo.json to file.tar
compressed file:
if it is compressed file, like file.tar.gz, you will need to extract the tar file from the compressed file (in this example gzip) by using gunzip file.tar.gz which will create for you the tar file file.tar. then you will be able to do the above steps.
at the end you should compress the tar file again by using gzip file.tar which will create for you compressed file with the name file.tar.gz
sub directories:
in order to handle sub dirs you will have to keep the same structure also in the file system:
tar -x -f file.tar dir/zoo.json
# now modify the file dir/zoo.json as you want ...
tar --delete -f file.tar dir/zoo.json
tar -uf file.tar dir/zoo.json
view the file structure:
by using the less command, you can view the structure of the file:
less file.tar
drwxr-xr-x root/root 0 2020-10-18 11:43 foo.json
drwxr-xr-x root/root 0 2020-10-18 11:43 bar.json
drwxr-xr-x root/root 0 2020-10-18 11:43 dir/zoo.json

Resources