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
Related
I'm trying to implement a bash script who supposed to search for a word in a Python script terminal output.
The Python script doesn't stop so "&" in the end of the command is needed but the "if [ $? == 0 ] ; then" condition doesn't work.
How it can be solved?
Thanks, Gal.
#!/bin/bash
#Check if Pixhawk is connected
PORT=/dev/ttyPixhawk
end=$((SECONDS+3))
not_exists=f
/usr/local/bin/mavproxy.py --daemon --non-interactive --master=$PORT | grep 'Failed' &> /dev/null &
while [ $SECONDS -lt $end ] ; do
if [ $? == 0 ] ; then
not_exists=t
fi
sleep 1
done
if [ $not_exists=t ] ; then
echo "Not Exists"
else
echo "Exists"
fi
kill $(pgrep -f '/usr/local/bin/mavproxy.py')
Bash doesn't know anything about the output of background commands. Check for yourself with [ 5444 -lt 3 ] & echo $?.
your if statement wouldn't work in any case because $? checks for the return value of the most recent previous command, which in this case is your while loop.
You have a few different options. If you're waiting for some output, and you know how long it is in the output until whatever target you're looking for occurs, you can have the python write to a file and keep checking on the file size with a timeout for failure.
You can also continue with a simple timed approach as you have where you just check the output after a few seconds and decide success or failure based on that.
You can make your python script actually end, or provide more error messages, or write only the relevant parts to file that way.
Furthermore, you really should run your script through shellcheck.net to notice more problems.
You'll need to define your goal and use case more clearly to get real help; all we can really say is "your approach will not work, but there are definitely approaches which will work"
You are checking the status of grep command output inside while loop using $?. This can be done if $? is the next command to be fired after grep and if grep is not a back-group process . But in your script, $? will return the status of while [$SECONDS -lt $end ]. You can try to re-direct the output to a temp file and check it's status
/usr/local/bin/mavproxy.py --daemon --non-interactive --master=$PORT | grep 'Failed' &> tmp.txt &
sleep 3
# If file exists and it's size is greater than 0, [ -s File] will return true
if [ -s tmp.txt ]; then
echo 'pattern exists'
else
echo 'pattern not exists'
fi
I'm having issues with a script I'm writing in bash with regards to backing up or restoring. What I'm trying to do is check for parameters and then if none are presented, loop until a name is provided or they quit. I can check for parameters and loop to quit but the problem I am having is getting the user input and then using that for the backup file name. Here's my script so far, can someone advise on how to loop for filename/q and how to get said filename input to work with the rest of the script?
#!/bin/bash
# Purpose - Backup world directory
# Author - Angus
# Version - 1.0
FILENAME=$1.tar.gz
SRCDIR=World
DESDIR=backupfolder
if [ $# -eq 0 ]
then
echo "No filename detected. To use this utility a filename is
required. Usage:tarscript filename"
else
echo "The filename to be used will be $filename"
fi
while [ $# -eq 0 ]
do
echo "Please provide a filename or press q to exit."
read response
if [ $response == 'q' ]
then
exit
else [ $response == '$FILENAME' ]
echo -n 'Would you like to backup or restore? (B/R)'
read response
if [ $response == 'B' ]
then
tar cvpzf $DESDIR/$FILENAME $SRCDIR
echo 'Backup completed'
exit
fi
fi
done
I finally managed to get it working in the end. I realised what my mistakes were thanks to Jens and changed things enough that it now responds to input and supplied parameters. Of course the code is nearly twice as big now with all my changes but hey ho.
I have a shell script where I pass (2) parameters, one to pass a dbname, the other to call one of (2) filenames. I want to check if either filename exists, then proceed with calling that script, else exit because the user can enter the wrong string and construct my_foo.sql which I don't want. I don't think I have the condition for setting "or" correctly since putting the correct param still produces error. Is there a better way to write this?
Here is what I have so far.
#/usr/bin/ksh
if [ $# != 2 ]; then
echo "Usage: test.sh <dbname> <test|live>" 2>&1
exit 1
fi
# Check actual file name
CHKSCRIPT1=/tmp/my_test.sql;
CHKSCRIPT2=/tmp/my_live.sql;
if [ -f "CHKSCRIPT1" ] || [ -f "CHKSCRIPT2" ]
then
/bin/sqlplus -s foo/bar #/my_$2.sql
else
echo "Correct sql script does not exist. Enter test or live"
exit 1
fi
Your issue is that you're not referencing your variables correctly:
if [ -f "$CHKSCRIPT1" ] || [ -f "$CHKSCRIPT2" ]
...
fi
edit: Per #chepner, you shouldn't use -o
In addition to the problem you had with expanding the parameters, you should separate what the user types from what files need to exist. If the user enters "live", the only thing that matters is whether or not /tmp/my_live.sql exists. If the user enters "injection_attack", your script should not execute /tmp/my_injection_attack.sql (which presumably was created without your knowledge). The right thing to do is to first verify that a valid command was entered, then check if the appropriate file exists.
if [ $# != 2 ]; then
echo "Usage: test.sh <dbname> <test|live>" 2>&1
exit 1
fi
case $2 in
test|live)
filename="/tmp/my_{$2}.sql"
;;
*) echo "Must enter test or live"
exit 1
;;
esac
if [ -f "$filename" ]; then
/bin/sqlplus -s foo/bar #/my_$2.sql
else
echo "SQL script $filename does not exist."
exit 1
fi
I want a script to run a main.ksh to run both one.ksh and second.ksh only if output of one.ksh matches "1". So if the output is anything other than "1" then second.ksh shouyld not run.
cat one.ksh
#!/usr/bin/ksh
echo "1"
cat second.ksh
#!/usr/bin/ksh
echo "2"
I did this:
#!/usr/bin/ksh
ksh .ksh > one.txt
file="one.txt"
while read line
do
if [ $line -eq 2 ] ;then
ksh second.ksh
else
echo "one.ksh is no good"
fi
done <"$file"
Any better way ro this is good?
Instead of echo 1 to proceed from the first script, you should use exit 0. If it shouldn't proceed, exit 1.
This is the standard way of signaling success and failure in Unix.
Once you do this, you can use any of:
first.ksh && second.ksh
or
if first.ksh
then
second.ksh
fi
or
set -e # Automatically exit script if a command fails
first.ksh
second.ksh
out=`one.ksh`
if [ "x$out" == "x1" ]; then
second.ksh
fi
I'm in the final stages of a project and need to create a script that will run an executable a given number of times with varying input. One of the inputs is a file kept in a separate folder from the executable.
Before doing anything, I want to check whether the file exists. There are two possible file inputs that can be given, so I need to compare them. The possible inputs are
execute cancer 9
execute promoter 9
where cancer and promoters are the datasets to be used in the program and 9 is the number of times the script loop has to execute.
Here's what I've come up with:
#!/bin/bash
#Shell script to execute Proj 4 requirements while leaving the folder
#structure alone separated.
file1= "Data/BC/bc80-train-1"
file2= "Data/Promoters/p80-train-1"
if [ "$1" == "cancer" ] then #execute command on the cancer dataset
echo "Executing on the cancer dataset"
if [ -f "$file1" ] then
echo "$file1 file exists..."
else
echo "$file1 file Missing, cancelling execution"
echo "Dataset must be in ../Data/BC/ and file must be bc80-train-1"
fi
elif [ "$1" == "promoter" ] then #execute on the promoter dataset
echo "Executing on the promoter dataset"
if [ -f "$file2"] then
echo "$file2 file exists..."
else
echo "$file2 file missing, cancelling execution"
echo "Dataset must be in ~/Data/Promoters/ and file must be p80-train-1"
fi
fi
The problem with this is it opens the files and outputs them to terminal, where each line ends in : command not found
I thought the -f and -e flags were used to check whether a file exists. So why is the file content being output to the terminal?
Drop the space to the right of = in:
file1= "Data/BC/bc80-train-1"
file2= "Data/Promoters/p80-train-1"
Also the keyword then should be on a line by itself or if on the same line as if should have a ; before it:
if [ condition ] ; then
...
fi
OR
if [ condition ]
then
...
fi
Your error messages mix ../Data/ and ~/Data/, but your file1 and file2 don't have either .. or ~ in their definitions:
file1= "Data/BC/bc80-train-1"
file2= "Data/Promoters/p80-train-1"
Remove the space after the = in file1= and file2=
Don't repeat yourself, use a function:
#!/bin/bash
checkfile() {
echo "Executing on the $1 dataset"
file="$2/$3"
if [ -f "$file" ] then
echo "$file file exists..."
else
echo "$file file Missing, cancelling execution"
echo "Dataset must be in $2 and file must be $3"
fi
}
case $1 in
cancer)
checkfile $1 Data/BC bc80-train-1
;;
promoter)
checkfile $1 Data/Promoters p80-train-1
;;
*)
echo "Error: unknown dataset. Use 'cancer' or 'promoter'"
;;
esac