Error message Standard error Shellscript - shell

i need some help here because i'm not sure if this is right, i have to write a shell script where i zip two text files, and then send a error message to standart error if the file already exists, also it can't overwrite the existing file
I also need some help with the if's, i tried elseif but didn't work
#!/bin/bash
echo " Backup..."
if [ ! -f file_2013.zip ] ; then
if [ -f file1.txt ] && [ -f file2.txt ] ; then
zip -rp file_2013.zip file1.txt file2.txt
else
echo "File not Found"
else
cat file_2013.zip > /dev/stderr

You need to close the if statements with the fi keyword. See for instance this

Related

how to edit this code to show multiple files (it currently works with 1 file)?

I have created a shell script in order to find 2 files. While it works with 1 it does not work with 2 or multiple. Any help?
#!/bin/bash
FILENAME="abc"
if [ -f "${FILENAME}"* ]
then
echo "EXISTS"
else
echo "NOT EXISTS"
fi
Expected: EXISTS
Error:
./test.sh: line 5: [: abc1.sh: binary operator expected
NOT EXISTS
Error is here:
if [ -f "${FILENAME}"* ]
-f option accepts a single file. If there are more files that start
with $FILENAME then * is expanded and more than one file is passed
to -f. It's also reported by shellcheck:
$ ~/.cabal/bin/shellcheck test.sh
In test.sh line 5:
if [ -f "${FILENAME}"* ]
^-- SC2144: -f doesn't work with globs. Use a for loop.
If you want to check if there is at least one file that starts with
$FILENAME without using external tools such as find you need use
for loop like that:
#!/bin/bash
FILENAME="abc"
for file in "${FILENAME}"*
do
if [ -f "$file" ]
then
echo File exists
exit 0
fi
done
echo File does not exist.
exit 1
The simple way is to check if there less then 2 files with same name abc*:
#!/bin/bash
FILENAME="abc"
COUNT_FILES=$(find . -maxdepth 1 -name "$FILENAME*" -type f | wc -l)
if [[ $COUNT_FILES -lt 2 ]]
then
echo "NOT EXISTS"
else
echo "EXISTS"
fi
if ls /path/to/your/files* 1> /dev/null 2>&1
then
echo "files do exist"
else
echo "files do not exist"
fi
This is what I was looking for. What I wanted was a function that looks for single OR multiple files, which the code above performed perfectly. Thanks for the previous answers, much help.

recover files deleted with rm command

Please if I run the command
# CREATE TRASH FOLDER
if ! [ -d "$HOME/deleted" ] ; then
mkdir $HOME/deleted
fi
TRASH=$HOME/deleted
mv $# $TRASH
To move file or directory to the trash created. what is the possible command i can run to recover same file to the original directory
If you create a deleted directory like this, you will probably get some unexpected behavior. For example:
rm_script test.txt
cd ../other_directory
rm_script test.txt
will create a single file test.txt with the content of the one in other_dir. Even more fun when you start rm_scripting/moving directories.
Knowing this, and referring once more to trash-cli (see comment Aserre), you might:
if ! [ -d "$HOME/deleted" ] ; then
echo "What a pity! No deleted directory."
echo "Your file(s) is/are lost forever!"
exit 361
fi
TRASH=$HOME/deleted
for file in $# ; do
if [ -f "$TRASH/$file" ] ; then
cp "$TRASH/$file" .
else
echo "Hmm,.. I cannot find $file."
fi
done
This also may have some unwanted results, like removing the file from one directory and un-deleting it in another.
I just do the reverse of the same command line
function undo () {
echo -n "Do you want to recover $*? "
read ANSWER
if [ "$ANSWER" = "y" ]; then
mv $TRASH/$# $PWD
echo "$# successfully recovered"
else
echo "Oops, request denied"
fi
}

How to syntax check a shell script before sourcing it?

I want to run this command source .env (sourcing a .env file) and if the .env file had some errors while sourcing. I want to show a message before the error output "Hey you got errors in your .env" else if there's no error, I don't want to show anything.
Here's a code sample that needs editing:
#!/bin/zsh
env_auto_sourcing() {
if [[ -f .env ]]; then
OUTPUT="$(source .env &> /dev/null)"
echo "${OUTPUT}"
if [ -n "$OUTPUT" ]; then
echo "Hey you got errors in your .env"
echo "$OUTPUT"
fi
}
You could use bash -n (zsh has has a -n option as well) to syntax check your script before sourcing it:
env_auto_sourcing() {
if [[ -f .env ]]; then
if errs=$(bash -n .env 2>&1);
then source .env;
else
printf '%s\n' "Hey you got errors" "$errs";
fi
fi
}
Storing the syntax check errors in a file is a little cleaner than the subshell approach you have used in your code.
bash -n has a few pitfalls as seen here:
How do I check syntax in bash without running the script?
Why not just use the exit code from the command source ?
You don't have to use bash -n for this because ...
If let's say your .env file contains these 2 invalid lines:
dsadsd
sdss
If you run your current accepted code using the example above:
if errs=$(bash -n .env 2>&1);
the above condition will fail to stop the file from sourcing.
So, you can use source command return code to handle all of this:
#!/bin/bash
# This doesn't actually source it. It just test if source is working
errs=$(source ".env" 2>&1 >/dev/null)
# get the return code
retval=$?
#echo "${retval}"
if [ ${retval} = 0 ]; then
# Do another check for any syntax error
if [ -n "${errs}" ]; then
echo "The source file returns 0 but you got syntax errors: "
echo "Error details:"
printf "%s\n" "${errs}"
exit 1
else
# Success here. we know that this command works without error so we source it
echo "The source file returns 0 and no syntax errors: "
source ".env"
fi
else
echo "The source command returns an error code ${retval}: "
echo "Error details:"
printf "%s\n" "${errs}"
exit 1
fi
The best thing with this approach is, it will check both bash syntax and source syntax as well:
Now you can test this data in your env file:
-
~
#
~<
>

script to check last file modified

SHELL SCRIPT TO GET MAIL IF FILE GET MODIFIED
I am writing script to get mail if file has been modified
recip="mungsesagar#gmail.com"
file="/root/sagar/ldapadd.sh"
#stat $file
last_modified=$(stat --printf=%y $file | cut -d. -f1)
#echo $last_modified
mail -s "File ldapadd.sh has changed" $recip
Now I get mail when I run this script but I want to compare two variables so that I can get mail only if file modified or content changed.
How can I store output in variable to compare
Thanks in advance
Sagar
I'd do it this way:
recip="you#example.com"
file="/root/sagar/ldapadd.sh"
ref="/var/tmp/mytimestamp.dummy"
if [ "$file" -nt "$ref" ]; then
mail -s "File ldapadd.sh has changed" $recip
fi
touch -r "$file" "$ref" # update our dummy file to match
The idea is to store the last seen timestamp of the file of interest by copying it to another file (using touch). Then we always know what the last time was, and can compare it against the current timestamp on the file and email as needed.
If I understand your question correct, the logic can be changed by storing the output of "ls -ltr filename" in a temp1 file and comparing the same with the ls -ltr output
I would use find to see the last modifyed file
#!/bin/bash
file=timestamp.txt
if [ ! -f timestamp.txt ];
then
stat -f %Sm -t %Y%m%d%H%M%S $file > timestamp.txt
else
timestamp=$(stat -f %Sm -t %Y%m%d%H%M%S $file)
filetime=$(cat filetime.txt)
if [ "$filetime" = "$timestamp" ];
then
#Do nothing
else
echo "$file has been modified" >> /tmp/email.txt
mail -s "File has changed" "email#domain.com" < /tmp/email.txt
fi
fi

bash script check existing file before running script

As I am new to bash scripting (vbs is more my stuff), I can't get this to run. Probably very simple for y'all:
I have a bash script on the C-system disk that is starting a NagWin (nagios for windows) plugin, but in that script I want to start off with a line of code that does a file existence checking on the D-drive in a certain folder.
If this file is there, it just can echo a message and exit,
else if this is not there it should continue with the script on the C-drive
The other part of the script runs well only it does not do any checking, probably because something is wrong with the jumping to d drive and c drive or something
Already thanks
if test -f '/path/to/file'; then
#Do your work
else
echo 'File not found, exiting.'
fi
if [ -f D:/file/on/d/drive ]
then C:/script/on/c/drive
else echo "Did not find file D:/file/on/d/drive" 1>&2
fi
You can test the presence of a file in different ways in bash:
1)
if [ -f "/path/to/file" ]; then echo "OK"; else echo "KO"; fi
2)
[ -f "/path/to/file" ] && echo "OK"
3)
[ -f "/path/to/file" ] || echo "KO"
4)
if test -f "/path/to/file"; then echo "OK"; else echo "KO"; fi

Resources