How to use TAR for directory range? - bash

I have a lot of dirs like:
/dir/1/
/dir/2/
...
/dir/1200/
I need to tar directories by range 0-999, 1000-1999, 2000-2999 into d0.tar.bz2, d1.tar.bz2, d2.tar.bz2 and etc.
I wrote this script:
#!/bin/bash
for i in {0..10}
do
let "tt = ($i+1)*1000"
let "ff = $i*1000"
tar -cfv /backups/d$i.tar.bz2 /dir/{$ff..$tt}
done
But I have errors while running:
tar: Removing leading `/' from member names
tar: /backups/d0.tar.bz2: Cannot stat: No such file or directory
tar: /dir/{0..1000}: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
What am I doing wrong?

What am I doing wrong?
Brace expansion happens before variable expansion, saying:
... /dir/{$ff..$tt}
would not work.
A workaround might be to use an array and Shell Parameter Expansion:
range=($(seq $ff $tt))
... "${range[#]/#//dir/}"

Related

must use full path with `-prune` in the find command? [duplicate]

This a really short question. But is there something syntatically wrong with placing a variable $example as an argument for tar in a bash file?
I have the file written as
//only portion that really matters
#!/bin/bash
...
tar -cvpzf $filename $backup_source
//here's the actual code
#!/bin/bash
backup_source="~/momobobo"
backup_dest="~/momobobo_backup/"
dater=`date '+%m-%d-%Y-%H-%M-%S'`
filename="$backup_dest$dater.tgz"
echo “Backing Up your Linux System”
tar -cvpzf $filename $backup_source
echo tar -cvpzf $filename $backup_source
echo “Backup finished”
//and heres the error
“Backing Up your Linux System”
tar: ~/momobobo: Cannot stat: No such file or directory
tar (child): ~/momobobo_backup/07-02-2013-18-34-12.tgz: Cannot open: No such file or directory
tar (child): Error is not recoverable: exiting now
tar: Child returned status 2
tar: Error is not recoverable: exiting now
tar -cvpzf ~/momobobo_backup/07-02-2013-18-34-12.tgz ~/momobobo
Notice the "echo tar ...". When I copy and paste the output and run it in my terminal there is no problem taring the file. I'm currently running Xubuntu and I already did an update.
~ doesn't expand to your home directory in double quotes.
Just remove the double quotes:
backup_source=~/momobobo
backup_dest=~/momobobo_backup/
In cases where you have things you would want to quote, you can use ~/"momobobo"

bash variable to store directory names with spaces

I'm writing a bash script to collect some directories (where conditions are met) and rsync those to a remote location. Overall the script looks like this;
sources=""
for d in /somewhere/* ; do
if $d meets condition; then
sources="$sources $(printf %q "$d")"
fi
done
if [ ! -z $sources ] ; then
rsync -vrz $sources /remote/target/
fi
Note that I'm using printf %q to escape spaces in directory names.
However when there are spaces in directory names, for example when "/somewhere/dir name" met the condition, the rsync thinks that as two directories and fails to run;
(at /home/u/) $ bash script.sh
sending incremental file list
rsync: link_stat "/somewhere/dir\" failed: No such file or directory (2)
rsync: link_stat "/home/u/name" failed: No such file or directory (2)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1196) [sender=3.1.2]
If I just print the rsync command by changing the last line to
echo rsync -vrz $sources /remote/target/
it looks just fine.
(at /home/u/) $ bash script.sh
rsync -vrz /somewhere/dirname /somewhere/dir\ name /remote/target
But using set -x shows something wacky going on.
(at /home/u/) $ bash script.sh
+ rsync -vrz /somewhere/dirname '/somewhere/dir\' name /remote/target
sending incremental file list
rsync: link_stat "/somewhere/dir\" failed: No such file or directory (2)
rsync: link_stat "/home/u/name" failed: No such file or directory (2)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1196) [sender=3.1.2]
I also tried to use double quoted directory names instead of printf %q but it didn't work either, with a slightly different reason.
(at /home/u/) $ bash script.sh
+ rsync -vrz '"/somewhere/dirname"' '"/somewhere/dir' 'name"' /remote/target
sending incremental file list
rsync: change_dir "/home/u//"/somewhere" failed: No such file or directory (2)
rsync: change_dir "/home/u//"/somewhere" failed: No such file or directory (2)
rsync: link_stat "/home/u/name"" failed: No such file or directory (2)
sent 20 bytes received 12 bytes 64.00 bytes/sec
total size is 0 speedup is 0.00
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1196) [sender=3.1.2]
Where are those single quotes around some arguments coming from and what is the best way to collect directories with spaces in a single-lined variable for using as sources in cp, mv, or rsync?
Use an array instead.
sources=()
for d in /somewhere/* ; do
if $d meets condition; then
sources+=("$d")
fi
done
if [ "${sources[*]}" ]; then
rsync -vrz "${sources[#]}" /remote/target/
fi
The single quotes output with set -x are just for disambiguation, so you can see exactly where actual literal spaces go (as opposed to syntactic spaces which are argument separators).

File exists but showing no such file or directory

I am trying to perform a set of terminal operations using bash shell script. Below is my code
#!/bin/bash
FILE_DATE=`date '+%Y%m%d'`
ARCHIVE_DIR="/home/tanmay/backup/"
TAR_GZ=".tar.gz"
PATH=( "/home/tanmay/Downloads/apache-tomcat-7.0.69/logs" "/home/tanmay/Downloads/apache-tomcat-7.0.69/webapps" )
FOLDER=("logs" "webapps" )
for number in {0..1..1}
do
echo ${PATH[number]}
echo ${FOLDER[number]}
rsync -vrzh ${PATH[number]} ${ARCHIVE_DIR}
tar -zcvf ${ARCHIVE_DIR}/${FOLDER[number]}${TAR_GZ} ${ARCHIVE_DIR}/${FOLDER[number]}
rm -rf ${ARCHIVE_DIR}/${FOLDER[number]}
if [ -f ${ARCHIVE_DIR}/${FOLDER[number]}${TAR_GZ} ]
then
mv ${ARCHIVE_DIR}${FOLDER[number]}${TAR_GZ} ${ARCHIVE_DIR}${FOLDER[number]}_${FILE_DATE}${TAR_GZ}
fi
done
When I run this script, both the echo is showing the correct values. But operations (rsync,tar..) are returning file not found. Below is the output
/home/tanmay/Downloads/apache-tomcat-7.0.69/logs
logs
./server_data_backup_updated.sh: line 11: rsync: No such file or directory
./server_data_backup_updated.sh: line 12: tar: No such file or directory
./server_data_backup_updated.sh: line 13: rm: No such file or directory
/home/tanmay/Downloads/apache-tomcat-7.0.69/webapps
webapps
./server_data_backup_updated.sh: line 11: rsync: No such file or directory
./server_data_backup_updated.sh: line 12: tar: No such file or directory
./server_data_backup_updated.sh: line 13: rm: No such file or directory
UPDATE 1
Using one array instead on two. It is working now.
#!/bin/bash
FILE_DATE=`date '+%Y%m%d'`
ARCHIVE_DIR="/home/tanmay/backup/"
TAR_GZ=".tar.gz"
array=( "/home/tanmay/Downloads/apache-tomcat-7.0.69/logs"
"logs"
"/home/tanmay/Downloads/apache-tomcat-7.0.69/webapps"
"webapps")
for number in {0..2..2}
do
rsync -vrzh ${array[number]} ${ARCHIVE_DIR}
tar -zcvf ${ARCHIVE_DIR}/${array[number+1]}${TAR_GZ} ${ARCHIVE_DIR}/${array[number+1]}
rm -rf ${ARCHIVE_DIR}/${array[number+1]}
if [ -f ${ARCHIVE_DIR}/${array[number+1]}${TAR_GZ} ]
then
mv ${ARCHIVE_DIR}${array[number+1]}${TAR_GZ} ${ARCHIVE_DIR}${array[number+1]}_${FILE_DATE}${TAR_GZ}
fi
done
When you reset PATH, the shell can no longer find the executable rsync. When the shell reads the word rsync, it looks through the variable named PATH (which it expects to be a colon separated list of directories, not an array) for a file named rsync. Similarly for tar and rm. The error messages you see are simply telling you that those commands are not found in your PATH.

bash script to automate wget tar cd using word designators and word modifiers

How can I automate the following with a bash shell script using word designators and word modifiers or something similar?
root#server:/tmp# wget -q http://download.zeromq.org/zeromq-2.2.0.tar.gz
root#server:/tmp# tar -xzf !$:t
tar -xzf zeromq-2.2.0.tar.gz
root#server:/tmp# cd !$:r:r
cd zeromq-2.2.0
root#server:/tmp/zeromq-2.2.0#
When I try something like the below I get errors because word designators and word modifiers don't appear to work the same way in bash scripts as they do in a shell:
Bash Shell Script Example 1:
#!/usr/bin/env bash
wget -q http://download.zeromq.org/zeromq-2.2.0.tar.gz && tar -xzf !$:t && cd !$:r:r
root#server:/tmp# ./install.sh
tar (child): Cannot connect to !$: resolve failed
gzip: stdin: unexpected end of file
tar: Child returned status 128
tar: Error is not recoverable: exiting now
Bash Shell Script Example 2:
#!/usr/bin/env bash
wget -q http://download.zeromq.org/zeromq-2.2.0.tar.gz
tar -xzf !$:t
cd !$:r:r
root#server:/tmp# ./install.sh
tar (child): Cannot connect to !$: resolve failed
gzip: stdin: unexpected end of file
tar: Child returned status 128
tar: Error is not recoverable: exiting now
./install.sh: line 11: cd: !$:r:r: No such file or directory
History substitution works at the command line. In a script, you can use parameter expansion.
#!/usr/bin/env bash
url=http://download.zeromq.org/zeromq-2.2.0.tar.gz
wget -q "$url"
tarfile=${url##*/} # strip off the part before the last slash
tar -xzf "$tarfile"
dir=${tarfile%.tar.gz} # strip off ".tar.gz"
cd "$dir"
If the example provided is the only issue you are trying to resolve perhaps the following can help:
version="2.2.0"
wget -q http://download.zeromq.org/zeromq-${version}.tar.gz
tar -xzf zeromq-${version}.tar.gz
cd zeromq-${version}
In a bash script version could be the first option passed to the script:
version=$1
This does not contain error handling and so on but should get you started.

Grouping files in tarballs

I need your help so as to create some tarballs, so as to group some files by year. I am using the following script but I get the error message:
tar: 2067_*.inp: Cannot stat: No such file or directory
tar: Error exit delayed from previous errors
Code:
for i in `seq 1960 2100` ; do
tar cvf ${i}_74_1.tar ${i}_*.inp
done
Where the *.inp files have the following structure: 1960_smt.inp, 1960_smt1.inp, etc.
I understand that my error is the * symbol that can't "understand" that I want to take any character. Could someone please help me fix it?
2067_*.inp: Cannot stat: No such file
or directory tar
Sounds more like you don't actually have any files named 2067_XXXX.inp for tar to archive
You'll likely want to check for a matching file to the pattern before you attempt to tar it up:
#!/bin/bash
shopt -u nullglob
for i in {1960..2100}; do
[ -f ${i}_*.inp ] && tar cvf ${i}_74_1.tar ${i}_*.inp
done
P.S.
Does anybody know why replacing [ with [[ ]] as in [[ -f ${i}_*.inp ]] breaks the pattern matching?

Resources