If any of the above mentioned file exists in a server, then print nothing ie. do nothing.
But, if the file does not exist, then print something like 'file_abc.conf does not exist on server 10.87.16.178'
Courtesy of MadeInGermany from another thread, I came up with a basic WHILE loop like below (in code snippet)
On a Linux jump server, I will place all servernames (or IPs) in a file named hostlist and pass it to a WHILE loop like below.
It is work in progress and untested.
I have two questions:
It has one IF..ELSE statement for each file I am checking for existence. Or can all files be checked for existence in one IF..ELSE statement ?
What is logic to do nothing inside a IF statement in bash shell ?
The basic WIP WHILE loop, I have created
while read -r server junk <&3
do
echo -e "Currently executing commands on $server ....\n\n"
ssh -n "oracle@$server" "
FILE1=/opt/appfin/base/admin/file_abc.conf
FILE2=/opt/appfin/base/admin/file_qrs.conf
FILE3=/opt/appfin/base/admin/file_xyz.conf
if [ -f "$FILE1" ]; then
<logic to do nothing in bash shell>
else
echo -e "file_abc.conf does not exist on $server......"
fi
if [ -f "$FILE2" ]; then
<logic to do nothing in bash shell>
else
echo -e "file_qrs.conf does not exist on $server......"
fi
if [ -f "$FILE3" ]; then
<logic to do nothing in bash shell>
else
echo -e "file_xyz.conf does not exist on $server......"
fi
"
done 3< hostlist
@james79 , one potential (there's any number of ways ...)
FILES[1]=file_abc.conf
FILES[2]=file_qrs.conf
FILES[3]=file_xyz.conf
for idx in "${!FILES[@]}"
do
[ ! -e "${FILES[idx]}" ] && echo "${FILES[idx]} does not exist"
done
as always, test and go with what works for you ...
The following seems to have worked. I had add in an extra check for the existence of /opt/appfin/product/version5 directory.
The files need to checked for existence only if /opt/appfin/product/version5 directory exists in that server.
while read -r server junk <&3
do
echo -e "Currently executing commands on $server ....\n\n"
ssh -n "oracle@$server" "
if [ -d /opt/appfin/product/version5 ]
then
if [ ! -f "/opt/appfin/base/admin/file_abc.conf" ]; then
echo -e "file_abc.conf does not exist on $server......"
fi
if [ ! -f "/opt/appfin/base/admin/file_qrs.conf" ]; then
echo -e "file_qrs.conf does not exist on $server......"
fi
if [ ! -f "/opt/appfin/base/admin/file_xyz.conf" ]; then
echo -e "file_xyz.conf does not exist on $server......"
fi
else
echo "Skipping...........EBFin is not installed on this server: $server ........."
fi
"
done 3< hostlist
why not simply embed the for ... within the test for /opt/appfin/product/version5
if [ -d /opt/appfin/product/version5 ]
then
FILES[1]=/opt/appfin/base/admin/file_abc.conf
FILES[2]=/opt/appfin/base/admin/file_qrs.conf
FILES[3]=/opt/appfin/base/admin/file_xyz.conf
for idx in "${!FILES[@]}"
do
[ ! -e "${FILES[idx]}" ] && echo "${FILES[idx]} does not exist"
done
else
A remote script in " " ??
I'd go for the safe method: remote script as a quoted here document.
while read -r server junk <&3
do
echo -e "Currently executing commands on $server ....\n\n"
ssh "oracle@$server" /bin/bash -s "$server" << "_EORS_"
#!/bin/bash
# Positional parameters
server=$1
# Other variables
FILE1=/opt/appfin/base/admin/file_abc.conf
FILE2=/opt/appfin/base/admin/file_qrs.conf
FILE3=/opt/appfin/base/admin/file_xyz.conf
if [ ! -d /opt/appfin/product/version5 ]
then
echo "Skipping...........EBFin is not installed on this server: $server ........."
exit
fi
for fn in "$FILE1" "$FILE2" "$FILE3"
do
if [ -f "$fn" ]; then
: ok, do nothing
else
echo -e "$fn does not exist on $server......"
fi
done
# EndOfRemoteScript
_EORS_
done 3< hostlist
ssh without -n because the embedded script is passed through ssh to the remote /bin/bash
The issue is that quotes do not nest. If your commands list does not include any quotes at all, it should (possibly) work.
However, in you original post, about the 9th line, the "$FILE1" is not quotes within quotes. The first " pairs with the last quote on the ssh line, and the last " resumes the quoting. That has two effects:
(a) The outer shell uses up all the quotes in the script sent to the server. This will probably fail, or have side effects, for expansions that result in spaces in the text.
(b) All the shell expansions in the script sent to the server are made in the scope of the local shell, not the remote one.
It is possible to alternate single and double quotes in the ssh part of the script to control the treatment of quoting and variable scope, but it can get very messy, HereDocs essentially have a third way of quoting which bypasses the quotes quandary.
Another wild feature of unquoted(!) HereDocs is that you can insert bash snippets inside them. This is a small section from a 100-line HereDoc which creates a macro list which later expands into a complete schema for a major project. This particular snippet expands into ten years worth of schema for monthly tables named like LA_RESULTS_202403, and a View over them all.
#.. LA_RESULTS
#.. For a view, the keys_list is an RE matching the tables composing the view.
_table la_results ${LOCN} 100 view ^la_results_20[0-9][0-9][0-9][0-9]$
#.. LA_RESULTS_YYYYMM
$( for LA_YM in ${LA_RESULTS_YYYYMM}; do
echo "_table ${LA_YM} ${LOCN} 500000000 btree ymdhh, plant_reference, plant_type"
echo "_cols ymdhh i4 plant_reference c11 plant_type c4 kw f4 kvar f4 quality f4"
done )