unix file test operator with using grep for other test - shell

I would like to check two conditions. I have a file that is created that could have an error string "ORA-" inside it. I want to check first if the file exists and/or was created, then second if the file that exists has that specific error string. If it does, do not proceed with next step. If it doesn't have it, then proceed. I use grep to check the string, however I'm not sure if i'm using the correct file test. What is a good way of checking for this?
TESTFILE=/tmp/usethisfile.sql
CHK_ERR= `grep "ORA-" $TESTFILE`;
if [ -e "$TESTFILE" ] && [ -z "$CHK_ERR" ];
then
#run next step
else
echo "Error found"
exit 1
fi

You can do:
TESTFILE=/tmp/usethisfile.sql
if [ -e "$TESTFILE" ] && grep -q "ORA-" "$TESTFILE"
then
#run next step
else
echo "Error found"
exit 1
fi

Related

Can not locate a file in a bash script?

I am running a shell script which expects a file in a directory but I can not seem to locate it.
This is my shell script
#!/usr/bin/env bash
# expects a file to be present in current directory called INPUT_FILE
# this is the value set in the jenkins config
if [ ! -f INPUT_FILE ] ;then
echo "file ${INPUT_FILE} does not exist"
exit 1
fi
And in windows I am running a shell script from a directory like this
D:\scripts> ./all/script.sh
I tried to put INPUT_FILE.csv in scripts folder and also in all folder but it does not seem to work. Where should this file be present?
Make sure you have the correct filename.
Windows hides the extension of a file, when you look for INPUT_FILE.csv use
if [ ! -f INPUT_FILE.csv ] ;then
echo "file INPUT_FILE.csv does not exist"
exit 1
fi
You tried to use the variable INPUT_FILE. When you want this, try
input_file="INPUT_FILE.csv"
if [ ! -f "${input_file}" ]; then
echo "file ${input_file} does not exist"
exit 1
fi
Also note that bash is case sensitive, so INPUT_FILE.csv is different from input_file.csv.
It's better to list files first to verify the extension and all file names in the directory then check for the existence of the files.
#!/usr/bin/env bash
ALL_FILES=$(ls -I "*.sh") # This will list all file except .sh
echo "Files in current Directory $ALL_FILES"
INPUT_FILE="INPUT_FILE" # or INPUT_FILE="INPUT_FILE.csv"
if [ ! -f $INPUT_FILE ] ;then
echo "file ${INPUT_FILE} does not exist"
exit 1
else
echo "file exist ${INPUT_FILE}"
exit 0
fi
The first advantage, It will list all the file and the second one, If exist you will get the output.

Bash Scripting: I currently am supposed to have 500 files inside a directory, how can I stop a bash script if any files are missing?

I currently have a directory that is supposed to have 500 files. Each file is of the name form List.1.rds, ... List.500.rds. The way I can see which ones are missing is by the following code in bash:
for((i=1; i<=500; i++)); do name="List.${i}.rds"; [[ ! -e "$name" ]] && echo "missing $name"; done
If a file is missing, it returns the missing file name. However, I would like to go one step further and stop the entire script should any file be missing. Is there a way to do this? thanks.
It can be as simple as setting a flag when a file is missing:
miss=0
for ((i=1;i<=500;i++)); do
file=List.$i.rds
if [[ ! -e $file ]]; then
echo "Missing $file"
miss=1
fi
done
# exit if "miss" flag is 1
((miss)) && exit 1

bash test for existence of files on SFTP server

The issue that I have is with the line: "does not work" - below. The last line does indeed work - but I need to understand why the second to last line does not. I need to check for file existence on the remote server.
Have a need to check for existence for files at the following location:
/home/remoteuser/files/
and when the files are processed, they are moved to:
/home/remoteuser/logs/archive/
Would like to create an alert if the files exist at - in other words, the files were not processed:
/home/remoteuser/logs/
Found the following page and seems to be what I am looking for:
http://www.cyberciti.biz/tips/find-out-if-file-exists-with-conditional-expressions.html
Testing this and I know there are files there, but does not work:
ssh remoteuser#1.2.3.4 [ ! -f /home/remoteuser/logs/archive/*.* ] && echo "File does not exist in the root" >> /home/localuser/files/dirlist.txt
Because we know this works and does indeed list files on the local server:
ssh remoteuser#1.2.3.4 ls -l /home/remoteuser/logs/archive/*.* >> /home/localuser/files/dirlist.txt
Wildcards and test construct in Bash
You cannot use the wildcards in the [ command to test the existence of multiple files. In fact, the wildcards will be expanded and all the files will be passed to the test. Te results is that it would complain that "-f" is given too many arguments.
Try this in any non empty directory to see the output:
[ ! -f *.* ]
The only situation in which the above command does not fail is when there is only one file matching the expression, in your case a non hidden file of the form "*.*" in /home/remoteuser/logs/archive/
Using Find
A possible solution is to use find in combination with grep:
ssh name#server find /path/to/the/files -type f -name "\*.\*" 2>/dev/null | grep -q . && echo "Not Empty" || echo "Empty"
find search for regular files (-type f) whose names are in the form . (-name) and return false if nothing is found, then "grep -q ." return 1 or 0 if something is found or not.
Your goal can be accomplished with only shell builtins -- and without any uses of those builtins which depend on their behavior when passed invalid syntax (as the [ ! -e *.* ] approach does). This removes the dependency on having an accessible, working find command on your remote system.
Consider:
rmtfunc() {
set -- /home/remoteuser/logs/*.* # put contents of directory into $# array
for arg; do # ...for each item in that array...
[ -f "$arg" ] && exit 0 # ...if it's a file that exists, success
done
exit 1 # if nothing matched above, failure
}
# emit text that defines that function into the ssh command, then run same
if ssh remoteuser#host "$(declare -f rmtfunc); rmtfunc"; then
echo "Found remote logfiles"
else
echo "No remote logfiles exist"
fi
ANSWER:
Did find the following about the use of -e for a regular file.
http://www.cyberciti.biz/faq/unix-linux-test-existence-of-file-in-bash/
Even though it says "too many arguments" it does seem to test out OK.
ssh remoteuser#1.2.3.4 [ ! -e /home/remoteuser/logs/archive/*.zip ] && echo "File does not exists in the root" >> /home/localuser/files/dirlist.txt || echo "File does exists in the root" >> /home/localuser/files/dirlist.txt
Your script will work simply using double parenthesis:
ssh remoteuser#1.2.3.4 [[ ! -f /home/remoteuser/logs/archive/*.* ]] && echo "File does not exist in the root" >> /home/localuser/files/dirlist.txt
From man bash
Word splitting and pathname expansion are not performed on the words between the [[ and ]].

Bash script - Nested If Statement for If File Doesn't Exist

I'm trying to compile a script that will read user input, and check if the file after the y/n statement. Then it will make files executable. I think the problem with my script is conditional ordering but check it out yourself:
target=/home/user/bin/
cd $target
read -p "This will make the command executable. Are you sure? (y/n)" CONT
if [ "$CONT" == "y" ];
then
chmod +x $1
echo "File $1 is now executable."
else
if [ "$(ls -A /home/user/bin/)" ];
then
echo "File not found."
else
echo "Terminating..."
fi
fi
As I said, I need the script to scan for the file after the y/n statement is printed. The script works fine how it is but still gives the "file is now executable" even if the argument file doesn't exist (but just gives the standard system "cannot find file" message after the echo'd text).
Your script is mostly correct, you just need to check if the file exists first. Also, it's not the best practice to use cd in shell scripts and not needed here.
So re-writing it
#!/bin/bash
target="/home/user/bin/$1"
if [[ ! -f $target ]]; then
echo "File not found."
else
read -p "This will make the command executable. Are you sure? (y/n) " CONT
if [[ $CONT == "y" ]]; then
chmod +x "$target"
echo "File $1 is now executable."
else
echo "Terminating..."
fi
fi
To get an understanding:
Your script will take one argument (a name of a file).
You ask if you want to make that file executable.
If the answer is 'yes', you make the file executable.
Otherwise, you don't.
You want to verify that the file exists too?
I'm trying to understand your logic. What does this:
if [ "$(ls -A /home/user/bin/)" ];
suppose to do. The [ ... ] syntax is a test. And, it has to be one of the valid tests you see here. For example, There's a test:
-e file: True if file exists.
That mean, I can see if your file is under /home/user/bin:
target="/home/user/bin"
if [ -e "$target/$file" ] # The "-e" test for existence
then
echo "Hey! $file exists in the $target directory. I can make it executable."
else
echo "Sorry, $file is not in the $target directory. Can't touch it."
fi
Your $(ls -A /home/user/bin/) will produce a file listing. It's not a valid test like -e unless it just so happens that the first file in your listing is something like -e or -d.
Try to clarify what you want to do. I think this is something more along the lines you want:
#! /bin/bash
target="/home/user/bin"
if [ -z "$1" ] # Did the user give you a parameter
then
echo "No file name given"
exit 2
fi
# File given, see if it exists in $target directory
if [ ! -e "$target/$1" ]
then
echo "File '$target/$1' does not exist."
exit 2
fi
# File was given and exists in the $target directory
read -p"Do you want $target/$1 to be executable? (y/n)" continue
if [ "y" = "$continue" ]
then
chmod +x "$target/$1"
fi
Note how I'm using the testing, and if the testing fails, I simply exit the program. This way, I don't have to keep embedding if/then statements in if/then statements.

Need some help writing an if statement in UNIX bash scripting

I'm writing a reasonably lengthy script (or what I would consider lengthy - you could probably do it in a few hours). I basically have a file (named .restore.info) which contains files of names. In part of the script, I want to test "If cannot find filename in .restore.info, then says “Error: restored file does not exist”. Apologies if this doesn't make sense for you guys (for me, it does in the grand scheme of things). So if type this in the command line:
sh MYSCRIPT filename
It will search for the string filename in the .restore.info file, and if it cant find anything, it should produce an error message.
Basically, I need the top line of this coded translated into a UNIX bash statement and something that actually makes sense!:
If grep $1 .restore.info returns an exist status of 1; then
echo “Filename does not exist!”
fi
Thanks in advance! Please ask me if you need me to clarify anything more clearly as I know I'm not the best explainer, and I'll get back to you in less than a minute! (+rep and best answer of course will be given!)
You probably only care if grep exits with a non-zero exit status:
if ! grep -q "$1" .restore.info; then
echo "Filename does not exist!"
fi
but if you really do care about a specific exit status (1, in this case):
if ! grep -q "$1" .restore.info && [[ $? -eq 1 ]]; then
echo "Filename does not exist!"
fi
Use grep -q
grep -q "filename" .restore.info && echo "found match"
or
! grep -q "filename" .restore.info && echo "not found"
grep -l 'filename' .restore.info
if [ $? = 0 ];then
echo "found it"
else
echo "not found"
fi

Resources