BASH - look for file in for loop issue - bash

So the issue is the following:
I have a folder with 4 .zip's and .md5's for all of them with the same base filename.
I have a FOR loop:
for S in *.zip;
do
{
check_md5
}
done
check_md5 ()
{
if md5sum -c ${S:0:-4}.md5;
then
unzip_file
else
echo "MD5 failed"
fi
}
The problem: the script for the first zip runs fine, but when the unzip_file process ends it doesn't update the S variable to the next zip's filename.
During the unzip_file process it moves out of the original folder and at the end of it moves both the current 'S' .zip and .md5 to a archive folder.
Is it possible that the bug happens, because the unzip_file script moves out of the original folder or because it moves the first .zip and .md5 out of the original folder before it jumps to the next cycle?
Any other ideas?
Thanks in advance.

The problem is at the end of the first iteration you end up in a different directory. Following is one possible fix.
CWD="$PWD" # remember current working directory path
for S in *.zip; do
check_md5
cd "$CWD" # come back to the initial working directory at the end of each iteration
done
Though not related to the question, I would prefer passing the file name to the function instead of accessing a variable set somewhere else. I find it hard to troubleshoot and more error prone.
unzip_file()
{
echo "unzipping $1"
# ...
}
check_md5()
{
if md5sum -c "${1:0:-4}.md5"; then
unzip_file "$1" # pass the argument forward
else
echo "MD5 failed"
fi
}
CWD="$PWD" # remember current working directory path
for S in *.zip; do
check_md5 "$S" # pass file name as an argument
cd "$CWD" # come back to the initial working directory
done
As another note, your function naming/modularization doe not look good. e.g. check_md5 does a lot more than just checking md5 sum.

Related

Bash check for file

I have this piece of code to check if a file exists in a directory, but it exits saying the file doesn't exist -
# in another file in the same directory
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
source "${SCRIPT_DIR}/common.sh" # calling the code below
BACKUP_VARS_FILE=${BACKUP_VARS_FILE:-"${SCRIPT_DIR}"/bitbucket.diy-backup.vars.sh}
if [ -f "${BACKUP_VARS_FILE}" ]; then
source "${BACKUP_VARS_FILE}"
echo "Using vars file: '${BACKUP_VARS_FILE}'"
else
error "'${BACKUP_VARS_FILE}' not found"
bail "You should create it using '${SCRIPT_DIR}/bitbucket.diy-backup.vars.sh.example' as a template"
fi
But the file does exist in the same folder as common.sh where the code is.
Output - it doesn't even go in the if/else block
[![enter image description here][2]][2]
Any help please?
edit -
Variable output, reading the file (with less) works -
[![enter image description here][3]][3]
Since the output is "/bitbucket...", without anything before the slash, I think your ${SCRIPT_DIR} is empty, which makes it looking for the file laying under root directory /.
Your current directory is /home/ubuntu/backup, where can find bitbucket.diy-backup.vars.sh, but your script may looking for /bitbucket.diy-backup.vars.sh, not /home/ubuntu/backup/bitbucket.diy-backup.vars.sh. Check ${SCRIPT_DIR} variable first.

Listing Running Processes and Sending Them to a File

my function is supposed to list all running processes and store them to process.id and if process.id exists, it should rename it to the current date with .id at the end of it, and then move it to the /logs directory. i think i have the mv and rename part working but it doesnt seem to save all of the processes to the file. do i have a syntax error on that part?
function processsaver()
{
if [ -r "process.id" ]; then
mv "process.id" logs/$(date +%d-%m-%y).id
ps -e > /process.id
fi
}
process.id and /process.id are not the same path. You probably wanted process.id or ./process.id in both places, since this kind of information really should not be in the filesystem root.

Entering a directory whose name matches a substring

I want to enter several directories in a for loop. I do not have the complete name of the directories, only a part of it.
I would like to do something like what you would write on the terminal, something like cd *IncompleteDirName*
This is a MVE of the loop: IncompleteDirName's are obtained from the file IncompleteDirNames.
cont=1
sum=1
while read anotherFILE; do
IncompleteDirName=$(sed "${cont}q;d" IncompleteDirNames)
cd *"${IncompleteDirName}"*
# Do stuff
cd ..
cont=$((cont + sum))
done <anotherFILE
This is not working, I don't know if this has to do with wildcard not expanding or with variable not working properly.
It is throwing me this error message:
*: No such file or directory
I suppose this means asterisk is not working as intended. It is not entering the directories, and there is a directory that matches every pattern. Anyway, no directory is being entered.
This is how IncompleteDirNames file looks like:
Alicante
Almeria
Andalucia
Avila
It is a column of names.
These are the directory names corresponding to the IncompleteDirNames above:
aa4fas_Alicante_com
mun_Almeria
comunidadde_Andalucia
ciuAvila
Try this code -
cont=1
sum=1
while read FILE; do
IncompleteDirName=$(sed "${cont}q;d" FILE)
cd *"${IncompleteDirName}"*
# Do stuff
cd ..
cont=$((cont + sum))
done <IncompleteDirNames
You can do the following:
#!/bin/bash
while read -r line; do
cd /absolute/path/to/*$line*
# do stuff
done < filename
This will enter each directory whose name partially matches a line in filename, and "does stuff".

Adding a status (file integrity)check to a cbr cbz converting bash script

First post, so Hi! Let me start by saying I'm a total noob regarding programming. I understand very basic stuff, but when it comes to checking exit codes or what the adequate term is, I'm at a loss. Apparently my searchfoo is really weak in this area, I guess it's a question of terminology.
Thanks in advance for taking your time to reading this/answering my question!
Description: I found a script that converts/repack .cbr files to .cbz files. These files are basically your average rar and zip files, however renamed to another extension as they are used for (comic)book applications such as comicrack, qcomicbook and what not. Surprisingly enough there no cbr -> cbz converters out there. The advantages of .cbz is besides escaping the proprietary rar file format, that one can store the metadata from Comic Vine with e. g comictagger.
Issue: Sometimes the repackaging of the files doesn't end well and would hopefully be alleviated by a integrity check & another go. I modified said script slightly to use p7zip as it can both pack/unpack 7z, zip-files and some others, i. e great for options. p7zip can test the archive by:
7z t comicfile.cbz tmpworkingdir
I guess it's a matter of using if & else here(?) to check the integrity and then give it another go, if there are any error.
Question/tl;dr: What would be the "best"/adequate approach to add a integrity file check to the script below?
#!/bin/bash
#Source: http://comicrack.cyolito.com/forum/13-scripts/30013-cbr3cbz-rar-to-zip-conversion-for-linux
echo "Converting CBRs to CBZs"
# Set the "field separator" to something other than spaces/newlines" so that spaces
# in the file names don't mess things up. I'm using the pipe symbol ("|") as it is very
# unlikely to appear in a file name.
IFS="|"
# Set working directory where to create the temp dir. The user you are using must have permission
# to write into this directory.
# For performance reasons I'm using ram disk (/dev/shm/) in Ubuntu server.
WORKDIR="/dev/shm/"
# Set name for the temp dir. This directory will be created under WORDDIR
TEMPDIR="cbr2cbz"
# The script should be invoked as "cbr2cbz {directory}", where "{directory}" is the
# top-level directory to be searched. Just to be paranoid, if no directory is specified,
# then default to the current working directory ("."). Let's put the name of the
# directory into a shell variable called SOURCEDIR.
# Note: "$1" = "The first command line argument"
if test -z "$1"; then
SOURCEDIR=`pwd`
else
SOURCEDIR="$1"
fi
echo "Working from directory $SOURCEDIR"
# We need an empty directory to work in, so we'll create a temp directory here
cd "$WORKDIR"
mkdir "$TEMPDIR"
# and step into it
cd "$TEMPDIR"
# Now, execute a loop, based on a "find" command in the specified directory. The
# "-printf "$p|" will cause the file names to be separated by the pipe symbol, rather than
# the default newline. Note the backtics ("`") (the key above the tab key on US
# keyboards).
for CBRFILE in `find "$SOURCEDIR" -name "*.cbr" -printf "%p|while read line; do
# Now for the actual work. First, extract the base file name (without the extension)
# using the "basename" command. Warning: more backtics.
BASENAME=`basename $CBRFILE ".cbr"`
# And the directory path for that file, so we know where to put the finished ".cbz"
# file.
DIRNAME=`dirname $CBRFILE`
# Now, build the "new" file name,
NEWNAME="$BASENAME.cbz"
# We use RAR file's name to create folder for unpacked files
echo "Processing $CBRFILE"
mkdir "$BASENAME"
# and unpack the rar file into it
7z x "$CBRFILE" -O"$BASENAME"
cd "$BASENAME"
# Lets ensure the permissions allow us to pack everything
sudo chmod 777 -R ./*
# Put all the extracted files into new ".cbz" file
7z a -tzip -mx=9 "$NEWNAME" *
# And move it to the directory where we found the original ".cbr" file
mv "$NEWNAME" $DIRNAME/"$NEWNAME"
# Finally, "cd" back to the original working directory, and delete the temp directory
# created earlier.
cd ..
rm -r "$BASENAME"
# Delete the RAR file also
rm "$CBRFILE"
done
# At the end we cleanup by removing the temp folder from ram disk
cd ..
echo "Conversion Done"
rm -r "$TEMPDIR"
Oh the humanity, not posting more than two links before 10 reputation and I linked the crap out of OP.. [edit]ah.. mh-mmm.. there we go..
[edit 2] I removed unrar as an dependency and use p7zip instead, as it can extract rar-files.
You will need two checks:
7z t will test the integrity of the archive
You should also test the integrity of all the image files in the archive. You can use at tools like ImageMagick for this.
A simple test would be identify file but that might read only the header. I'd use convert file -resize 5x5 png:- > /dev/null
This scales the image down to 5x5 pixels, converts it to PNG and then pipes the result to /dev/null (discarding it). For the scaling, the whole image has to be read. If this command fails with an error, something is wrong with the image file.

Look for a file in parent dir if it is not in current dir

I'm trying to make a shell function that looks for a file existence in the current dir. If the file doesn't exists if the current dir, it should try the parent dir, and go up to the root of the filesystem (going up to ~ should be more than enough).
What I'm trying to achieve is display the current ruby on rails version used for a project on my prompt. The easy way is to call bundle show rails and parse the string, but it is quite slow; so I want to parse the file that contains the versions informations, Gemfile.lock. What I have currently only works when I'm in the root of the project (where the Gemfile.lock lives).
This could also be used to parse a git config file, though git config is pretty fast.
Thanks for your time
like this?
#!/bin/zsh
# the function
findfile_parent() {
FILE=$1
while [ ! -e "${FILE}" ]; do
if [ "$(pwd)" = "/" ]; then
return
fi
cd ..
done
echo "$(pwd)/${FILE}"
}
# usage example
SEARCHFILE=foo.pyl
UPFILE=$(findfile_parent ${SEARCHFILE})
if [ "x${UPFILE}" != "x" ]; then
echo "found file ${SEARCHFILE} as ${UPFILE}"
else
echo "couldn't find file ${SEARCHFILE}"
fi
Refer the below two helpful links to find out your solution.
Get parent directory of current directory in Ruby
How to check for file existence
):

Resources