shell script help - checking for file exists - unix

I'm not sure why this code isn't working. Its not going to the copy command.
I successfully run this manually on the command line (without the check)
I don't think i'm performing a correct file check? Is there a better, cleaner way to write this?
I just want to make sure the file exists, if so, copy it over. Thanks.
#!/bin/bash
if [ $# != 1 ]; then
echo "Usage: getcnf.sh <remote-host>" 2>&1
exit 1
fi
#Declare variables
HOURDATE=`date '+%Y%m%d%H%M'`
STAMP=`date '+%Y%m%d-%H:%M'`
REMOTE_MYCNF=/var/log/mysoft/mysoft.log
BACKUP_DIR=/home/mysql/dev/logs/
export REMOTE_MYCNF HOURDATE STAMP
#Copy file over
echo "Checking for mysoft.log file $REMOTE_MYCNF $STAMP" 2>&1
if [ -f $REMOTE_MYCNF ]; then
echo "File exists lets bring a copy over...." 2>&1
/usr/bin/scp $1:$REMOTE_MYCNF $BACKUP_DIR$1.mysoft.log
echo "END CP" 2>&1
exit 0
else
echo "Unable to get file" 2>&1
exit 0
fi

your checking existing file on remote computer seems like:
you should do:
ssh $host "test -f $file"
if [ $? = 0 ]; then

use sh -x script.sh to see what is happening.

You are testing for the existence of a remote file
$1:$REMOTE_MYCNF
using the local name $REMOTE_MYCNF. The if test is never satisfied.

You don't check that $1 is set.
Your file check runs on the local machine - not on the remote.

Change your if to:
if[! -f $REMOTE_MYCNF -o ! -d $REMOTE_MYCNF];

Related

In Unix, WHILE command not reading file from a different directory

In Unix, WHILE command, I am trying to read a file, which is in another directory. But somehow not working, not even throwing any error.
while read line
do
echo $line
done < /tmp/myfile.txt
The file is present in /tmp folder, has all the permissions.
It is not clear why your while loop is not working. Normally loops, if condition syntax are different for different shell. Hence at the beginning of a shell script file we always define the shell where exactly this script should run and that first line is start with a #. Now do the following and check that might help you.
create a file $vi test.sh
put the below line in it
#!/usr/bin/ksh
filename="/tmp/myfile.txt"
while [ 1 ]
do
read -r line
if [ ${line:-1} -eq 1 ]; then
break
else
echo $line
fi
done < "$filename"
or
#!/usr/bin/ksh
filename="/tmp/myfile.txt"
while read -r line
do
echo $line
done < "$filename"
save the file and set the permission like below
$chmod 777 test.sh
now run the file
$./test.sh

How to keep polling file in a directory till it arrives in Unix

I want to keep polling file till it arrives at the location for 1 hour.
My dir : /home/stage
File Name (which I am looking for): abc.txt
I want to keep polling directory /home/stage for 1 hour but within the 1 hour if abc.txt file arrives then it should stop polling and should display the message file arrived otherwise after 1 hour it should display that file has not arrived.
Is there any way to achieve this in Unix?
Another bash method, not relying on trap handlers and signals, in case your larger scope already uses them for other things:
#!/bin/bash
interval=60
((end_time=${SECONDS}+3600))
directory=${HOME}
file=abc.txt
while ((${SECONDS} < ${end_time}))
do
if [[ -r ${directory}/${file} ]]
then
echo "File has arrived."
exit 0
fi
sleep ${interval}
done
echo "File did not arrive."
exit 1
The following script should work for you. It would poll for the file every minute for an hour.
#!/bin/bash
duration=3600
interval=60
pid=$$
file="/home/stage/abc.txt"
( sleep ${duration}; { ps -p $pid 1>/dev/null && kill -HUP $pid; } ) &
trap "echo \"file has not arrived\"; kill $pid" SIGHUP
while true;
do
[ -f ${file} ] && { echo "file arrived"; exit; }
sleep ${interval}
done
Here's an inotify script to check for abc.txt:
#!/bin/sh
timeout 1h \
inotifywait \
--quiet \
--event create \
--format '%f' \
--monitor /home/stage |
while read FILE; do \
[ "$FILE" = 'abc.txt' ] && echo "File $FILE arrived." && kill $$
done
exit 0
The timeout command quits the process after one hour. In case the file arrives, the process kills itself.
You can use inotify to monitor the directory for modifications and then check to see if the file is abc.txt. The inotifywait(1) command lets you do this directly from the command line in a shell script. Check the man page for details. This is notification based.
A poll based thing would be a loop that checks to see if the file exists and if not, sleep for a period of time before checking again. That's a trivial shell script too.
Here some answer with retry:
cur_poll_c=0
echo "current poll count= $cur_poll_c"
while (($cur_poll_c < $maxpol_count)) && (($SECONDS < $end_time))
do
if [[ -f $s_dir/$input_file ]]
then
echo "File has arrived...
do some operation...
sleep 5
exit 0
fi
sleep $interval
echo "Retring for $cur_poll_c time .."
cur_poll_c=`expr $cur_poll_c+1`;
done

sh script: no output when run in mounted filesystem

Need some help to understand what's wrong.
In short: I've written a bourne shell script, which creates links to contents of source directory in the target directory.
It worked fine on the host system but when targeted on directories on mounted fs (both from chroot and native system) it doesn't work and provides no output at all.
Details:
mounted fs: ext3, rw
host system: 3.2.0-48-generic #74-Ubuntu SMP GNU/Linux
To narrow the question, "/usr" was taken as an example.
permissions for "/usr" in the host system: drwxr-xr-x
permissions for "/usr" on mounted partition: drwxr-xr-x
Tried to use both bash and dash from host system. Same result - works for native file systems, does not work for the mounted.
script (cord.sh; run from root in my cases):
# !/bin/sh
SRCFOLDER=$2 # folder with package installation
DESTFOLDER=$3 # destination folder to install symlinks to ('/' - for base sys; '/usr' - userland)
TARGETS=$(ls $SRCFOLDER) # targets to handle
SRCFOLDER=${SRCFOLDER%/} # stripping slashes from the end, if they are present
DESTFOLDER=${DESTFOLDER%/} #
##
## LINKING
##
if [ "$1" = "-c" ];
then printf %s "$TARGETS" | while IFS= read -r line
do
current_target=$(file $SRCFOLDER/$line) # had an issue with different output in different systems
if [ "${current_target% }" = "$SRCFOLDER/$line: directory" ]; # stripping space helped
then
mkdir -v $DESTFOLDER/$line # if other package created it - it'll fail
/usr/local/bin/cord.sh -c $SRCFOLDER/$line $DESTFOLDER/$line # RECURSION
else
ln -sv $SRCFOLDER/$line $DESTFOLDER/$line # will fail, if exists
fi;
done
##
## REMOVING LINKS
##
elif [ "$1" = "-d" ];
then printf %s "$TARGETS" | while IFS= read -r line
do
current_target=$(file $SRCFOLDER/$line)
if [ "${current_target% }" = "$SRCFOLDER/$line: directory" ];
then
/usr/local/bin/cord.sh -d $SRCFOLDER/$line $DESTFOLDER/$line # RECURSION
else
rm -v $DESTFOLDER/$line
fi;
done
elif [ "$1" = "-h" ];
then
echo "Usage:"
echo "cord -c /path/to/pkgdir /path/to/linkdir - create simlinks for package contents"
echo "cord -d /path/to/pkgdir /path/to/linkdir - delete links for package"
echo "cord -h - displays this help note"
else
echo "Usage:"
echo "cord -c /path/to/pkgdir /path/to/linkdir - create simlinks for package contents"
echo "cord -d /path/to/pkgdir /path/to/linkdir - delete links for package"
echo "cord -h - displays this help note"
fi;
The most obvious thing to suggest, was some issue with permissions. Yet everything looks sane. Maybe I've missed something?
I don't know what your main problem might be (permissions or something else - you should include an example of how you run the script and how you prepare for it with the mounts and everything). But this script can be cleaned up.
First, if you want to test whether something is a directory, use
if [ -d "$something ]
That'll get rid of the clumsy file usage.
Second, don't go through the redundant steps of converting your $TARGETS array to a series of lines and then reading the lines with a loop. Just loop over the array directly.
for line in $TARGETS
Also, instead of using ls to populate an array of filenames, I'd use a glob. But instead of either of those, I'd use find so it can take care of recursion and eliminate the tree of processes you're creating by recursing with a call to the same script. And instead of writing a symlink-tree-maker script I'd use something like lndir which already exists for that purpose...

logging unix "cp" (copy) command response

I am coping some file,So, the result can be either way.
eg:
>cp -R bin/*.ksh ../backup/
>cp bin/file.sh ../backup/bin/
When I execute above commands, its getting copied. No response from the system, if it copied successful. If not, prints the error or response in terminal itself cp: file.sh: No such file or directory.
Now, I want to log the error message, or if it successful I want to log my custom message to a file. How can I do?
Any help indeed.
Thanks
try writing this in a shell script:
#these three lines are to check if script is already running.
#got this from some site don't remember :(
ME=`basename "$0"`;
LCK="./${ME}.LCK";
exec 8>$LCK;
LOGFILE=~/mycp.log
if flock -n -x 8; then
# 2>&1 will redirect any error or other output to $LOGFILE
cp -R bin/*.ksh ../backup/ >> $LOGFILE 2>&1
# $? is shell variable that contains outcome of last ran command
# cp will return 0 if there was no error
if [$? -eq 0]; then
echo 'copied succesfully' >> $LOGFILE
fi
fi

how to translate the hostname solaris?

can any one translate or explain the following unix script for me please, when i actually run the script in the solaris server, it gives me the server name, but not really sure how this script work, can any one explain it in simple baby language ? Thanks
TEXTDOMAIN=SUNW_OST_OSCMD export TEXTDOMAIN
if [ $# -eq 0 ]; then
/bin/uname -n
elif [ $# -eq 1 ]; then
/bin/uname -S $1
else
echo `/bin/gettext "Usage: hostname [name]"`
exit 1
fi
$# reads command line arguments
if there are none call uname -n
if there is one call uname -S $1 (which is the command line argument.)
See man uname to discover the differences in these calls.
If the script is executed with 0 arguments
it will just run uname manpage printing you system name
if script is executed with 1 argument
it will change your system name ( you have to be superuser)
else prints usage

Resources