How to check if a shell command executed properly or not? - linux

#!/bin/sh
tar=$1
if [ -f $tar ]
then
tar xvf $tar
else
exit 1
fi
... <more code>
I need a conformation that the tar actually happened successfully, otherwise abort the execution of the script.
The tar file extract might not go through because
some problems with tar command
access issues with $tar
Do Linux utilities have some return values? How should I use them here?

Check the $? variable after executing a command. If everything is OK, it should be 0, positive otherwise.
tar xvf $tar
[ $? -ne 0 ] && exit 1
More information here.

This
tar xvf "$tar" || exit 1
or this (if you want to check if file exists yourself)
[ -f "$tar" ] && tar xvf "$tar" || exit 1

Related

How to check if file is tar file in Bash shell?

My question is about Bash, Shell. I am writing a script and I have the following problem:
I have a case when user declares that he or she will extract a file into a dir. But I have to test if the existence and if exist a need to check if that file is a *.tar file. I searched for similar like when checking if the file is executable:
if [ -x "file" ]; then
echo "file is executable"
else
echo "file is not executable"
# will this if test work?
case $1
"--extract")
if [ -e $2 ] && [ tar -tzf $2 >/dev/null ]; then
echo "file exists and is tar archive"
else
echo "file either does not exists or it is not .tar arcive"
fi
;;
esac
Code from above doesn't work it is totally ignored. Any ideas?
file command can determine file type:
file my.tar
if it is a tar file it will output:
my.tar: POSIX tar archive (GNU)
Then you can use grep to check the output (whether or not contains tar archive):
file my.tar | grep -q 'tar archive; && echo "I'm tar" || echo "I'm not tar"
In case the file does not exis, file output will be (with exit code 0):
do-not-exist.txt: cannot open `do-not-exist.txt' (No such file or directory).
You could use a case statement to handle several types of files.
I would just see if tar can list the file:
if ! { tar ztf "$file" || tar tf "$file"; } >/dev/null 2>&1; then
echo "$file is not a tar file"
fi
I usually use a construct like this based off of the file command.
gzipped tarballs
$ file somefile1.tar.gz | grep -q 'gzip compressed data' && echo yes || echo no
yes
$ file somefile2.tar.gz | grep -q 'gzip compressed data' && echo yes || echo no
no
tarballs
The above handles gzipped tarball files, for uncompressed change out the string that grep detects:
$ file somefile1.tar | grep -q 'POSIX tar archive' && echo yes || echo no
yes
$ file somefile2.tar | grep -q 'POSIX tar archive' && echo yes || echo no
no
OK, I found the answer. I know that this is not most optimal, however, it works as I intended.
I put case $1 from user into a variable and create another variable equal to *.tar.gz then in if statement I compare var1 (string from user input) with var2 equal to *tar.gz and it works.

tar command does not produce the .tar.gz file

I am trying to iterate in a loop, tar a couple of directories with each iteration and then compare the md5 sums of both of them. I notice that my first tar statement produces the tar files one level above the actual path of the directory. i.e. the statement:
tar -czvf ${folder_name}.tar.gz /tmp/psk1/hadoop_validation$ENV/${folder_name}
produces the ${folder_name}.tar.gz in /tmp/psk1/ rather than /tmp/psk1/hadoop_validation$ENV/
and the second tar statement:
tar -czvf ${folder_name}.tar.gz ${edge_base_dir}/wlossf$ENV/app/${folder_name}
doesn't produce the tar file at all. I can't find it even on one level above the actual path.
hdfs dfs -ls /haas/wlf/wlossf$ENV/app | while read rec; do
echo $rec
folder_path=`echo ${rec} | awk -F ' ' '{print $8}'`
folder_name=`echo ${folder_path} | awk -F '/' '{print $6}'`
if [ ! -z ${folder_name} ] && [ ! -z ${folder_path} ]; then
hdfs dfs -get ${folder_path} /tmp/psk1/hadoop_validation$ENV/
if [ $? -eq 0 ]; then
echo "Hadoop to local copy job Successful"
else
echo "Hadoop to local copy job Failed"
fi
tar -czvf ${folder_name}.tar.gz /tmp/psk1/hadoop_validation$ENV/${folder_name}
hadoop_md5=$(md5sum /tmp/psk1/hadoop_validation$ENV/${folder_name}.tar.gz)
tar -czvf ${folder_name}.tar.gz ${edge_base_dir}/wlossf$ENV/app/${folder_name}
edge_md5=$(md5sum ${edge_base_dir}/wlossf$ENV/app/${folder_name}.tar.gz)
if [ ${hadoop_md5} == ${edge_md5} ]; then
echo "${folder_name} is good"
else
echo "${folder_name} is bad"
fi
fi
echo ${folder_name}
echo ${folder_path}
done
What am I missing here? Any help would be appreciated.
Thank you.
As mouviciel said in the comments, tar by default creates the file in the current working directory.
Simply prefix the tar.gz file with the folder and it will create it where you want it:
tar -czvf /tmp/psk1/hadoop_validation$ENV/${folder_name}.tar.gz /tmp/psk1/hadoop_validation$ENV/${folder_name}
Note that as you will be creating the tar inside the same folder that you are archiving, you'll get a file changed as we read it warning as part of the output. Nothing to worry about.

Check if rsync command ran successful

The following bash-script is doing a rsync of a folder every hour:
#!/bin/bash
rsync -r -z -c /home/pi/queue root#server.mine.com:/home/foobar
rm -rf rm /home/pi/queue/*
echo "Done"
But I found out that my Pi disconnected from the internet, so the rsync failed. So it did the following command, deleting the folder.
How to determine if a rsync-command was successful, if it was, then it may remove the folder.
Usually, any Unix command shall return 0 if it ran successfully, and non-0 in other cases.
Look at man rsync for exit codes that may be relevant to your situation, but I'd do that this way :
#!/bin/bash
rsync -r -z -c /home/pi/queue root#server.mine.com:/home/foobar && rm -rf rm /home/pi/queue/* && echo "Done"
Which will rm and echo done only if everything went fine.
Other way to do it would be by using $? variable which is always the return code of the previous command :
#!/bin/bash
rsync -r -z -c /home/pi/queue root#server.mine.com:/home/foobar
if [ "$?" -eq "0" ]
then
rm -rf rm /home/pi/queue/*
echo "Done"
else
echo "Error while running rsync"
fi
see man rsync, section EXIT VALUES
Old question but I am surprised nobody has given the simple answer:
Use the --remove-source-files rsync option.
I think it is exactly what you need.
From the man page:
--remove-source-files sender removes synchronized files (non-dir)
Only files that rsync has fully successfully transferred are removed.
When unfamiliar with rsync it is easy to be confused about the --delete options and the --remove-source-files option. The --delete options remove files on the destination side. More info here:
https://superuser.com/questions/156664/what-are-the-differences-between-the-rsync-delete-options
you need to check the exit value of rsync
#!/bin/bash
rsync -r -z -c /home/pi/queue root#server.mine.com:/home/foobar
if [[ $? -gt 0 ]]
then
# take failure action here
else
rm -rf rm /home/pi/queue/*
echo "Done"
fi
Set of result codes here:
http://linux.die.net/man/1/rsync

How to install eclipse in Ubuntu

I am facing problem while installing tar zxf eclipse-cpp-helios-linux-gtk.tar.gz
this eclipse file in Ubuntu. Please tell me how to unzip this file.
To unzip I used following commands
1. $ gunzip file.gz
2. $ gunzip < file.tar.gz | tar xvf -
3. $ gunzip < file.tgz | tar xvf -
tar -xzf tar-file-name.tar.gz /path/to/location
or use 7Zip tool. right click and extract.
try the following
#!/bin/sh
ECLIPSE=/usr/lib/eclipse/eclipse
inject_update_site(){
if [ ! -e "$1" ] ; then
echo "W: Cannot find $1" 2>&1
return 1
fi
cat - >>"$1" <<eof>
repositories/http\:__download.eclipse.org_releases_indigo/enabled=true
repositories/http\:__download.eclipse.org_releases_indigo/isSystem=false
repositories/http\:__download.eclipse.org_releases_indigo/nickname=Indigo Update Site
repositories/http\:__download.eclipse.org_releases_indigo/uri=http\://download.eclipse.org/releases/indigo/
EOF
}
if [ ! -d ~/.eclipse/ ] ; then
$ECLIPSE -clean -initialize || exit $?
artifact=$(find ~/.eclipse \
-regex .*/profileRegistry/.*/org.eclipse.equinox.p2.artifact.repository.prefs)
metadata=$(find ~/.eclipse \
-regex .*/profileRegistry/.*/org.eclipse.equinox.p2.metadata.repository.prefs)
if [ -z "$artifact" ] || [ -z "$metadata" ]; then
echo "W: Cannot inject update-sites, cannot find the correct config." 2>&1
else
( inject_update_site "$artifact" && \
inject_update_site "$metadata" && \
echo "I: Injected update sites" ) || echo "W: Could not inject update sites." 2>&1
fi
fi
exec $ECLIPSE "$#"
reference to
How to install the latest version of Eclipse Classic on Ubuntu 12.04 using the terminal?
tar xzf xxxx.tar.gz
tar xjf xxxx.tar.bz2

what does this shell script codes means

i need some help to understand the following few lines of a given shell script.
here $_filecount variable hold the number of file to be archived
here i want to know what $TARC means, searched on this command but got no result for TARC and TARU commands. could anybody explain me what these commands are
_archive=${ARCHIVE_PATH}/${_name}_$(hostname)_${_today}.tar
if [ $_filecount -ne 0 ]; then
if ! [ -f ${_archive} ]; then
touch ${ARCHIVE_PATH}/${_today}
$TARC ${_archive} -C ${ARCHIVE_PATH} ${_today}
rm -f ${ARCHIVE_PATH}/${_today}
fi
for i in ${_filelist}; do
$TARU ${_archive} -C ${_path} $i
[ $? -eq 0 ] && rm -f ${_path}/$i
done
fi
when this code is run using cygwin at line $TARC ${_archive} -c ${ARCHIVE_PATH} ${_today} returns following error
tar: invalid option -- 'E'
Try `tar --help' or `tar --usage' for more information.
thanks in advance for any help
$TARC and $TARU are variables (if they aren't defined in your script somewhere, then they must be environment variables)
Try echo $TARC to see what they are set to.
Looks TARC is the tar command to archive and TARU is the tar command to unarchive.
TARC and TARU must be set somewhere or else you would get a different error - the error you are seeing is tar specific.

Resources