Need Shell functions replacement for conditions - shell

I am very new to shell scripting and i need to write a script, the conditions are pretty straight fwd:
i have 2 dir location
First Dir:
$ABC_123/cert
which contains 3 files:
file1.pem
file2.pem
file3.pem
Second Dir:
$ABC_123/private
which contains 2 files:
file4.pem
file5.pem
these files needs to be replaced/appended with files from a user input dir location depending on below conditions
if file3 is present in the user input dir location then take back of all files under the above two dir and then replace file1,file2,file4,file5 and append file3
if file3 is not present in the user input dir location then take back up and replace only file 1,file2,file4,file5 only
i want to write a shell function for back up and replace/append conditions.
Below is the shell i wrote:
#!/bin/sh
$ABC_123=/ABC/123/XCOM
export ABC_123
# input the change number
printf 'Enter the NUMBER number\n'
read NUMBER
file1="$ABC_123/certs/fil2cert.pem"
file2="$ABC_123/certs/fil2cert.pem"
file3="$ABC_123/certs/fil3cert.pem"
file4="$ABC_123/private/fil4key.pem"
file5="$ABC_123/private/fil5key.pem"
file6="$ABC_123/private/fil6key.pem"
file7="/tmp/$NUMBER/fil3cert.pem"
# Begining of the implementation
if [ -f $file1 ] && [ -f $file2 ] && [ -f $file3 ] && [ -f $file4 ] && [ -f $file5 ] && [ ! -f $file6 ] && [ -f $file7 ]
then
#
#BACKUP
#
cp -p $file1 $file1.$(date +%Y-%m-%d).bkp
cp -p $file2 $file2.$(date +%Y-%m-%d).bkp
cp -p $file3 $file3.$(date +%Y-%m-%d).bkp
cp -p $file4 $file4.$(date +%Y-%m-%d).bkp
cp -p $file5 $file5.$(date +%Y-%m-%d).bkp
#
#REPLACE
#
cp /tmp/$NUMBER/*key.pem $ABC_123/private/
cp /tmp/$NUMBER/*cert.pem $ABC_123/certs/
cat /tmp/$NUMBER/fil3cert.pem >> $ABC_123/certs/fil3cert.pem
#
#CHANGE PERMISSIONS
#
chmod 644 $ABC_123/private/*key.pem
chmod 644 $ABC_123/certs/*cert.pem
chmod 644 $ABC_123/certs/fil3cert.pem
chown root:root $ABC_123/private/*key.pem
chown root:root $ABC_123/certs/*cert.pem
chown root:root $ABC_123/certs/fil3cert.pem
elif [ -f $file1 ] && [ -f $file2 ] && [ -f $file3 ] && [ -f $file4 ] && [ -f $file5 ] && [ ! -f $file6 ] && [ ! -f $file7 ]
then
#
#BACKUP
#
cp -p $file1 $file1.$(date +%Y-%m-%d).bkp
cp -p $file2 $file2.$(date +%Y-%m-%d).bkp
cp -p $file3 $file3.$(date +%Y-%m-%d).bkp
cp -p $file4 $file4.$(date +%Y-%m-%d).bkp
#
#REPLACE
#
cp /tmp/$NUMBER/*key.pem $ABC_123/private/
cp /tmp/$NUMBER/*cert.pem $ABC_123/certs/
#
#CHANGE PERMISSIONS
#
chmod 644 $ABC_123/private/*key.pem
chmod 644 $ABC_123/certs/*cert.pem
chown root:root $ABC_123/private/*key.pem
chown root:root $ABC_123/certs/*cert.pem
elif [ ! -f $file1 ] && [ ! -f $file2 ] && [ ! -f $file3 ] && [ ! -f $file4 ] && [ ! -f $file5 ] && [ ! -f $file6 ]
then
#
#REPLACE
#
cp /tmp/$NUMBER/*key.pem $ABC_123/private/
cp /tmp/$NUMBER/*cert.pem $ABC_123/certs/
cp /tmp/$NUMBER/fil3cert.pem $ABC_123/certs/
#
#CHANGE PERMISSIONS
#
chmod 644 $ABC_123/private/*key.pem
chmod 644 $ABC_123/certs/*cert.pem
chmod 644 $ABC_123/certs/fil3cert.pem
chown root:root $ABC_123/private/*key.pem
chown root:root $ABC_123/certs/*cert.pem
chown root:root $ABC_123/certs/fil3cert.pem
elif [ -f $file6 ]
then
#
# BACKUP
#
find $ABC_123/certs/* -type f -exec mv {} {}.$(date +%Y-%m-%d).bkp \;
find $ABC_123/private/* -type f -exec mv {} {}.$(date +%Y-%m-%d).bkp \;
#
# REPLACE
#
cp /tmp/$NUMBER/*key.pem $ABC_123/private/
cp /tmp/$NUMBER/*cert.pem $ABC_123/certs/
cp /tmp/$NUMBER/fil3cert.pem $ABC_123/certs/
#
# CHANGE PERMISSIONS
#
chmod 644 $ABC_123/private/*key.pem
chmod 644 $ABC_123/certs/*cert.pem
chmod 644 $ABC_123/certs/fil3cert.pem
chown root:root $ABC_123/private/*key.pem
chown root:root $ABC_123/certs/*cert.pem
chown root:root $ABC_123/certs/fil3cert.pem
elif [ ! -f "$file1" ] || [ ! -f "$file2" ] || [ ! -f "$file3" ] || [ ! -f "$file4" ] || [ ! -f "$file5" ] && [ ! -f "$file6" ] ; then
# At least one file is missing, writing the list of missing file(s):
echo -n "Missing file(s): "
for i in "$file1" "$file2" "$file3" "$file4" "$file5" ; do
if [ ! -f "$i" ] ; then
echo -n "$i "
fi
done
echo
fi
i want to use shell function instead of repeating the BACKUP,REPLACEMENT and CHANGE PERMISSION command again and again

Your shell function could be something like
all_present() {
for file
do
[ -f $file ] || return 1
done
return 0
}
and it would be used like this:
if ! all_present "$file1" "$file2" "$file3" "$file4" "$file5" "$file6"
then
echo at least one is missing
...
BTW: In case you can switch from shell to bash or zsh or ksh, you can hold all files in an array and the whole expression would be simpler.

Related

Bash script that remove duplicates

This works incorrectly. The script should delete only copies, but this script deletes all files.
#!/bin/bash
DIR=$1
if [[ -z "$DIR" ]]; then
echo "Error: files dir is undefined"
fi
files="$( find ${DIR} -type f )"
for file1 in $files; do
for file2 in $files; do
if cmp -s "$file1" "$file2"; then
rm $file2
fi
done
done
Found this on superuser:
#!/bin/bash
declare -A arr
shopt -s globstar
for file in **; do
[[ -f "$file" ]] || continue
read cksm _ < <(md5sum "$file")
if ((arr[$cksm]++)); then
echo "rm $file"
fi
done
I find answer:
#!/bin/bash
DIR=$1
if [[ -z "$DIR" ]]; then
echo "Error: files dir is undefined"
fi
files="$( find ${DIR} -type f )"
for file1 in $files; do
for file2 in $files; do
if cmp -s "$file1" "$file2"; then
rm $file2
fi
done
done

Counting directories and files in bash

Simple counting dirs and files does not work. I am checking each file by -f and -d flag.
Where is a problem?
LOCATION=$1
for FILE in $(ls $LOCATION | egrep '^.{0,3}$');
do
echo "$FILE"
if [ -f $FILE ]
then
echo "its a file"
fi
if [ -d $FILE ]
then
echo "its a dir"
fi
done
shopt -s dotglob # count hidden files
for file in "$LOCATION/"*; do
[[ -f $file ]] && ((f++))
[[ -d $file ]] && ((d++))
done
echo "${d:-0} dirs"
echo "${f:-0} files"
without involving external utilities

Unix Bash - Copy files from a source folder recursively to destination/*file_extension*(ex. “txt”) folder

This is my code, something in the rec_copy() function isn't working properly, probably this line:
cp $1/$f $HOME/$2/$dest
The extension named folders are created in the destination folder but the files are not copied there. Can you help me?
#!/bin/bash
if [ $# -ne 2 ]
then
echo "Usage: $0 <source> <destination>"
exit
fi
if [ ! -d $1 ]
then
echo "Source folder does not exist"
exit
fi
if [ -d $2 ]
then
rm -r $2
mkdir $2
else
mkdir $2
fi
extension=`ls -l $1 | grep -v "^d" | awk '{ print $10; }' | sed 's/^.*\.//g'`
for f in $extension
do
if [ ! -d $1/$f ]
then
mkdir $2/$f
fi
done
rec_copy(){
folder=`ls $1`
for f in $folder
do
dest=`echo "$f" | sed 's/.*\.//g'`
if [ -f $1/$f ]
then
cp $1/$f $HOME/$2/$dest
elif [ -d $1/$f ]
then
rec_copy $1/$f
fi
done
}
rec_copy $1
Here is the answer in case someone ever needs it:
#!/bin/bash
if [ $# -ne 2 ]
then
echo "Usage: $0 <izvor> <destinacija>"
exit
fi
if [ ! -d "$1" ]
then
echo "Izvorniot folder ne postoi"
exit
fi
if [ -d "$2" ]
then
rm -r "$2"
mkdir "$2"
else
mkdir "$2"
fi
extension=`ls -l "$1" | grep -v "^d" | awk '{ print $10; }' | sed 's/^.*\.//g' | sort -u`
for f in $extension
do
if [ ! -d "$1/$f" ]
then
mkdir "$2/$f"
fi
done
rec_copy(){
folder=`ls "$1"`
for f in $folder
do
dest=`echo "$f" | sed 's/.*\.//g'`
to=`cp "$1/$f" "$2/$dest"`
if [ -f "$1/$f" ]
then
echo "$to"
elif [ -d "$1/$f" ]
then
rec_copy "$1/$f" "$2"
fi
done
}
rec_copy "./$1" "./$2"

Directory exist if [-d "$/root/folder" ]; is not working

I need to create a directory in root directory of Linux if it's not already present in it.So i am using the if [-d "$/root/folder" ]; but it's going to else part even if directory exist. Please help with this. Below is the code-
#! /bin/sh
if [ -d "$/root/folder" ];then
echo "folder file already exist"
else
echo "Settings in progress" \
&& mkdir folder \
&& chmod 7777 folder \
&& cd folder \
&& mkdir FolderConnector \
&& chmod 7777 FolderConnector \
&& cd FolderConnector \
&& mkdir ClientInput \
&& mkdir ClientOutput \
&& chmod 7777 ClientInput \
&& chmod 7777 ClientOutput \
&& cat /home/data/RTV/file2 >>/etc/exports \
&& exportfs -r \
&& exportfs \
&& echo "Settings completed successfully."
fi
What I would do :
#! /bin/sh
set -e
if [ -d "/root/folder" ]; then
echo "folder file already exist"
else
echo "Settings in progress"
mkdir folder
chmod 7777 folde
cd folder
mkdir FolderConnector
chmod 7777 FolderConnector
cd FolderConnector
mkdir ClientInput
mkdir ClientOutput
chmod 7777 ClientInput
chmod 7777 ClientOutput
cat /home/data/RTV/file2 >>/etc/exports
exportfs -r
exportfs
echo "Settings completed successfully."
fi
set -e stop the script on the first error
you had a $ character in your test

Rewriting a for-loop to use it with "parallel"

I am trying to rewrite a for-loop (that works great) and run it as parallel but i having all sorts of problems. Here is my for loop
function no_sam {
filename=$(basename "$file")
extension="${file##*.}"
if [ $extension = "sam" ];
then
filename="${filename%.*}"
feat_out=$filename.out
htseq-count -f $types -r "$pos" -m "$mode" -i "$attribute" -s "$strand" -t "$feature" -a "$qual" "$file" "$input_gff" > "$feat_out"
grep -v "_" "$feat_out" > temp && mv temp "$feat_out"
mv "$feat_out" "$counts_folder"
elif [ $extension = "bam" ];
then
filename="${filename%.*}"
feat_out=$filename.out
htseq-count -f $types -r "$pos" -m "$mode" -i "$attribute" -s "$strand" -t "$feature" -a "$qual" "$file" "$input_gff" > "$feat_out"
grep -v "_" "$feat_out" > temp && mv temp "$feat_out"
mv "$feat_out" "$counts_folder"
fi
}
for file in "${multi[#]}"; do
no_sam
done
And when i replaced the for loop with GNU parallel, i am getting error
"${multi[#]}" no_sam | parallel
testfile.sam: command not found
Try this (based on https://www.gnu.org/software/parallel/man.html#EXAMPLE:-Using-shell-variables and https://www.gnu.org/software/parallel/man.html#EXAMPLE:-Calling-Bash-functions):
function no_sam {
file="$1"
filename=$(basename "$file")
extension="${file##*.}"
if [ $extension = "sam" ];
then
filename="${filename%.*}"
feat_out=$filename.out
htseq-count -f $types -r "$pos" -m "$mode" -i "$attribute" -s "$strand" -t "$feature" -a "$qual" "$file" "$input_gff" > "$feat_out"
grep -v "_" "$feat_out" > temp && mv temp "$feat_out"
mv "$feat_out" "$counts_folder"
elif [ $extension = "bam" ];
then
filename="${filename%.*}"
feat_out=$filename.out
htseq-count -f $types -r "$pos" -m "$mode" -i "$attribute" -s "$strand" -t "$feature" -a "$qual" "$file" "$input_gff" > "$feat_out"
grep -v "_" "$feat_out" > temp && mv temp "$feat_out"
mv "$feat_out" "$counts_folder"
fi
}
export -f no_sam
parallel no_sam ::: "${multi[#]}"
From the way you try to use GNU Parallel I think you will benefit from spending an hour walking through man parallel_tutorial.
Your command line will love you for it.

Resources