Bash writing an if statement [duplicate] - bash

This question already has answers here:
How to check file exists via Bash script?
(2 answers)
Closed 7 years ago.
I am new to bash and I need to write an if statement within my code however I am unsure how to write is so that if $someVar is found then run this else do that. In this case $someVar is a file and I am not wanting to output text just run another line of code in this case creating the file.
Code:
rm /var/path/to/folder/$someVar
for i in `seq 3 253`
do
echo $ALLOCATION.$i >> /var/path/to/folder/$someVar

To check for the existence of /var/path/to/folder/"$someVar", then you can use:
#!/bin/bash
if [[ -f /var/path/to/folder/$someVar ]]; then
rm /var/path/to/folder/"$someVar"
fi
for i in `seq 3 253`; do
echo $ALLOCATION.$i >> /var/path/to/folder/"$someVar"
done
You can also use a simple compound-command:
#!/bin/bash
[[ -f /var/path/to/folder/$someVar ]] && rm /var/path/to/folder/"$someVar"
for i in `seq 3 253`; do
echo $ALLOCATION.$i >> /var/path/to/folder/"$someVar"
done
Note: within [[ ... ]] you do not have to quote your variable to protect against spaces in the variable. In all other cases you should (as a rule of thumb).
Also, note to check whether the file is writeable (i.e. you have permission to remove it), you can use [[ -w /var/path/to/folder/$someVar ]]

Related

Checking for multiple files with bash script

I have a bash file where I am currently using an if statement to check for two files existing before continuing with the rest.
if [[ -e $flchck ]] && [[ -e $flchck2 ]]; then
--do stuff here
else
--sends me an email telling me the files were not found.
My question is, is this the most efficient way to do this? If I need it to check more files, would I just keep adding && to include more.
What if I want it to tell me which file(s) was missing when it did this check.
Any guidance/direction on how to handle this would be greatly appreciated.
Typically one would use an array for this purpose. Assuming that your error-report-mailing code is encapsulated in a command named send_error_email, this may look like:
#!/usr/bin/env bash
files=( /path/to/file1 /path/to/file2 /path/to/file3 )
for file in "${files[#]}"; do
if ! [[ -e $file ]]; then
send_error_email "$file does not exist"
exit 1
fi
done
# do stuff here

Bash script that checks for parts of current folderpath

Clean and simple: how do I check with bash for certain parts of the folder I'm currently in?
#!/usr/bin/sh
CURRENTFOLDER=$(pwd)
echo "${CURRENTFOLDER}"
CHECKFOLDER="/home/*/domains/*/public_html"
if [ $CURRENTFOLDER ! $CHECKFOLDER ]
then
echo "Current folder is not /home/user/domains/domain.com/public_html"
exit
fi
User and domain are variable, I don't need to know them for this checkup, just the 3 pre-defined folders in the variable CHECKFOLDER
There's a problem with this approach.
For example in bash the following expression evaluates to true:
[[ /www/user/domains/local/public_html == /www/*/public_html ]]
It is more accurate to use a bash regex:
[[ /www/user/domains/local/public_html =~ ^/www/[^/]+/public_html$ ]]
So your code would become:
#!/bin/bash
current_folder=$PWD
check_folder='^/home/[^/]+/domains/[^/]+/public_html$'
if ! [[ $current_folder =~ $check_folder ]]
then
echo "Current folder is not /home/user/domains/domain.com/public_html"
exit
fi
BTW, the shebang needs to be a bash, not sh. And it's kind of dangerous to capitalize your variables.
Try this (almost) Shellcheck-clean code:
#! /usr/bin/sh
curr_phpath=''
for phpath in /home/*/domains/*/public_html/; do
if [ "$phpath" -ef . ]; then
curr_phpath=$phpath
break
fi
done
if [ -z "$curr_phpath" ]; then
echo "Current folder is not /home/user/domains/domain.com/public_html" >&2
exit 1
fi
Because of aliasing mechanisms (e.g. symbolic links, bind mounts) it is very difficult in general to determine if two paths reference the same file or directory by comparing them textually. See How to check if two paths are equal in Bash? for more information. This solution uses a more reliable mechanism to determine if the current directory is one of the valid ones.
Since the shebang line references sh instead of bash, the code avoids Bashisms. It's been tested with both bash and dash (probably the most common non-Bash sh).
See Correct Bash and shell script variable capitalization for an explanation of why the code does not use ALL_UPPERCASE variable names.
The [ "$phpath" -ef . ] test is true if the .../public_html path being checked is the same directory as the current directory. The -ef operator is not in POSIX so it is not guaranteed to be supported by an sh shell, and Shellcheck (correctly) warns about it. However, it is supported in both bash and dash, and sh is usually one of those (on Linux at least).
You can save a step just by changing to the directory instead of checking.
Check your glob matches only one file first.
Then, cd to check it's a dir.
#! /bin/bash
IFS="$(printf '\n\t')"
files=( $(compgen -G '/home/*/domains/*/public_html') )
if [[ "${#files[#]}" != 1 ]]
then
printf 'Multiple matches\n' >&2
exit 1
fi
if ! cd "${files[0]}"
then
printf 'Cannot chdir\n'
exit 1
fi

using two variables in a bash find and replace [duplicate]

This question already has answers here:
How to pass a variable containing slashes to sed
(7 answers)
Closed 11 months ago.
I am trying to automate some patching steps and I have written a script to back up the file and then replace the path in the file in all spots, upon testing backing up the files was ok but the find and replace even though it states successful didn't work, I am trying to use said but I am not married to that so if there is a cleaner way I am not opposed, please see my code example below:
#!/bin/bash
#set -x
nodemanager="/u01/app/oracle/admin/domain/mserver/ADF_INT/nodemanager/"
bindirectory="/u01/app/oracle/admin/domain/mserver/ADF_INT/bin/"
ouilocation="/u01/app/oracle/product/fmw/middleware12c/oui/bin/"
date=$(date +"%d-%m-%y")
echo $date
read -p "Please enter the current jdk path: " oldjdk
read -p "Please enter the new jdk path: " newjdk
echo "Backing up an uploading files to remote server...."
cd $nodemanager || exit
cp nodemanager.properties nodemanager_$date.bkp
if [ $? -ne 0 ]; # Again checking if the last operation was successful if not shall exit the
script
then
echo -e "nodemanager.properties backup failed"
echo -e "Terminating script"
exit 0
fi
sed -i -e 's/${$oldjdk/$newjdk}/g' nodemanager.properties
if [ $? -ne 0 ]; # Again checking if the last operation was successful if not shall exit the
script
then
echo -e "find and replace failed for nodemanager.properties"
echo -e "Terminating script"
exit 0
fi
echo -e "nodemanager.properties operations completed successfully\n"
Thanks
JJ
To save you some trouble on this I figured it out the / is not part of sed it can be any delimiter that is not clashing with the path so I used this:
sed -i "s+$oldjdk+$newjdk+g" file
Thanks
JJ

Bash - Check if file exists when some of the filename is irrelevant [duplicate]

This question already has answers here:
Check if a file exists with a wildcard in a shell script [duplicate]
(21 answers)
Closed 3 years ago.
I want to check if file exists but only checking if some the filename exists
For example in some folder I have these files (Date format: AAAAMMDD):
Rejets_20190112.csv.zip
Rejets_20190312.csv.zip
Rejets_20190314.csv.zip
I want to check if there is a file that begins with Rejet_DAP_201903 exists in that folder. In other word I want to check if Rejet_DAP file with current year and month exist, the day doesn't matter.
Here's what I tried to do in my script:
jour=`date +%d`
mois=`date +%m`
annee=`date +%Y`
FILE="/appli/project/echanges/RTY/receptions/Rejet_${annee}${mois}"_*
if [[ -e $FILE ]]
then
echo "FILE EXISTS"
else
echo "FILE DOES NOT EXIST"
fi
You have the directory path and the file pattern that you are looking for.
The ls command can be used to list files based on patterns.
All commands return an integer value after execution. 0 means the execution finished successfully. Any non-zero value means error.
ls will return a non-zero value if no files match the pattern.
That return code you can use within the if statement.
#!/bin/bash
jour=`date +%d`
mois=`date +%m`
annee=`date +%Y`
/appli/project/echanges
dir="/appli/project/echanges/RTY/receptions"
file_prefix="Rejet_DAP_"
if ls $dir/${file_prefix}${annee}${mois}* > /dev/null 2>&1
then
echo "FILE EXISTS"
else
echo "FILE DOES NOT EXIST"
fi
The #!/bin/bash line is called a shebang line and I highly recommend using it in your scripts.
The > /dev/null 2>&1 is so that you don't get output from the ls command and only have your output displayed.
You can use find for this
$ if [[ `find /appli/project/echanges/RTY/receptions/ -type f |grep -i Rejet_DAP_${annee}${mois}|wc -l` -gt 0 ]] ; then
echo "FILE EXISTS"
else
echo "FILE DOES NOT EXIST"
fi

Checking the input arguments to script to be empty failed in bash script

This a small bash program that is tasked with looking through a directory and counting how many files are in the directory. It's to ignore other directories and only count the files.
Below is my bash code, which seems to fail to count the files specifically in the directory, I say this because if I remove the if statement and just increment the counter the for loop continues to iterate and prints 4 in the counter (this is including directories though). With the if statement it prints this to the console.
folder1 has files
Looking at other questions I think the expression in my if statement is right and I am getting no compilation errors for syntax or another problems.
So I just simply dumbfounded as to why it is not counting the files.
#!/bin/bash
folder=$1
if [ $1 = empty ]; then
folder=empty
counter=0
echo $folder has $counter files
exit
fi
for d in $(ls $folder); do
if [[ -f $d ]]; then
let 'counter++'
fi
done
echo $folder has $counter files
Thank you.
Your entire script could be very well simplified as below with enhancements made. Never use output of ls programmatically. It should be used only in the command-line. The -z construct allows to you assert if the parameter following it is empty or non-empty.
For looping over files, use the default glob expansion provided by the shell. Note the && is a short-hand to do a action when the left-side of the operand returned a true condition, in a way short-hand equivalent of if <condition>; then do <action>; fi
#!/usr/bin/env bash
[ -z "$1" ] && { printf 'invalid argument passed\n' >&2 ; exit 1 ; }
shopt -s nullglob
for file in "$1"/*; do
[ -f "$file" ] && ((count++))
done
printf 'folder %s had %d files\n' "$1" "$count"

Resources