How do I use a variable in an FTP shell script? - shell

Using a handy script that I found for FTP-ing, I modified it to my own use, and it works, but too well, or too literally.
#!/bin/sh
HOST='10.0.1.110'
USER='myName'
PASSWD='myPass'
FILE='*.sql' # WILDCARD NOT WORKING - Takes literal string of '*.sql'
# Stripped unrelated code
ftp -n $HOST <<END_SCRIPT
quote USER $USER
quote PASS $PASSWD
prompt
binary
cd Desktop/SweepToDiskBK
mput /home/myAcct/SQLbackups/"$FILE" "$FILE"
quit
END_SCRIPT
exit
That is, the file(s) that gets 'put', is named *.sql, and replaces any previous versions of it, instead of file1.sql, file2.sql, etc. In the original script, they were doing a put, instead of an mput, and with a single file names text.txt. I've also tried changing the single quotes after FILE, to double quotes, and got the same result. Can someone let me in on the 'trick' to using variables for CLI FTP-ing?
Thanks in advance,
LO

I'd try this:
FILE=*.sql
without any quotes enabling wildcard expansion
and:
mput /home/myAcct/SQLbackups/"$FILE"
with just one $FILE

But i think you can just do mput /home/myAcct/SQLbackups/$FILE to mput *.sql? Or if you need to put several files with put, then you need to do it one by one with some sort of a loop.
To check what the script does, change ftp -n $HOST to cat. Try these very commands in the plain ftp session. Do they work?

Related

Variable not interprate inside loop shell script

I tried to made a save inside a SSH connection from files inside a folder with a script, I don't understand why but
expect \"ssh>\"
send \"for ENTRY in "pathtomyfolder"/*; do cp /DOMP/appli/bin/$(basename $ENTRY) /pathtofolder/$(basename $ENTRY).somedate; done \r\"
But it seems that my variable isn't interprate inside my script, it's empty. If I launched the loop from the SSH connection it works fine it's juste inside the script that it doesn't work. If you could help me thank you.
Edit : Thank for you replies sorry for my lack of informations, I've made a minimal reproductible example :
#!/bin/sh
HORODATAGE=`date "+%Y%m%d%H%M%S"`
for entry in "folder"/*
do
cp "\$entry" "\$entry.$HORODATAGE"
done
I've tried to escape my variable but it doesn't work too...
By escaping the variables, you basically told the shell "please do not expand it". Hence, you should have written it as
#!/bin/sh
HORODATAGE=`date "+%Y%m%d%H%M%S"`
for entry in "folder"/*
do
cp "$entry" "$entry.$HORODATAGE"
done
BTW, I would write the assignment of the date as
HORODATAGE=$(date "+%Y%m%d%H%M%S")
but of course, your approach is not wrong either.

bash script check if file exist and sent an information email

I worte a simple script to check if there are some files exist (endded with .txt) in the dirctoey older than 6 hours, after the check to send an email.
The scripte isnt working well and as expected, I ask you if there's some simpler and more powerful way to do it? Basically it just needs to check if file eneded with .txt exists and older than 6hours, if yes an email should be sent.
This is my script
#!/bin/bash
DATE=`date +%Y.%m.%d-%H.%M`
HOSTNAME='host'
BASEDIR=`/usr/local/se/work/jobs/`
LOGFILE=`/usr/local/se/work/jobs/logs/jobs.log`
VERTEILER="anyemail"
# Functions
#
# function check if the jobs are exists
'find ${BASEDIR} -name "*.txt" -nmin +354' 2>$1 >>$LOGFILE
#function mail
cat << EOF | mailx -s "Example ${HOSTNAME} jobs `date +%Y.%m.%d-%H.%M`" -a ${LOGFILE} ${VERTEILER}
Hi,
Please check the Jobs.
Details :
`ls -ltr /usr/local/se/work/jobs/`
------------ END ----------------------------------------
.
Thank you
To redirect STDERR to STDOUT use 2>&1, you are doing it wrong with 2>$1
Also, the correct parameter for find is -mmin not -nmin like you have in your code.
Further more you have syntax errors like here:
BASEDIR=`/usr/local/se/work/jobs/`
LOGFILE=`/usr/local/se/work/jobs/logs/jobs.log`
What you mean to type is:
BASEDIR='/usr/local/se/work/jobs/'
LOGFILE='/usr/local/se/work/jobs/logs/jobs.log'
When you use backticks bash tries to execute COMMAND, you are using it the right way here:
DATE=`date +%Y.%m.%d-%H.%M`
You are also not closing the heredoc <<EOF, you need EOF on the last line of the script.
And lose the '' surrounding the find command.
You should pay attention to what bash says, it should prompt lots of errors, try to run the script manually to see them if you are using this via cron.
Did you even try to run this script?
The grave accent (`) in BASEDIR and LOGFILE means the shell will try to evaluate them as commands which fails. You don't generally need quotes around strings in shell scripts, although it may be considered good practice to use double quotes (").
HOSTNAME=host
BASEDIR=/usr/local/se/work/jobs
LOGFILE=${LOGFILE}/logs/jobs.log
VERTEILER=anyemail
The switch to search files by minutes in called mmin and not nmin -- again that should have given you an error. And the math is wrong, if you want 6 hours then it's 6 * 60 = 360 minutes.
find ${BASEDIR} -name *.txt -mmin +360
You are redirecting stderr to the first input parameter. (2>$1) Are you expecting error output from this command, could you explain what is going on here?
And then you append that to LOGFILE which is in a directory that may not exist. mkdir -p is a good choice for creating folders in scripts because it creates parent directories when needed and won't complain if the folder already exists. So do something along the lines of
mkdir -p /usr/local/se/work/jobs/logs

Wildcard in bash script

I have a bash script to retrieve files from ftp.
Now the files have one part a date string in the filename, but also undefined numbers that changes on every file. I want to download the files based on the date.
This is my code. I only need to do the wildcard trick, the ftp script is allready work.
filename=$(echo $TIMESTAMP'0***vel.radar.h5')
The stars are 3 digits with different numbers that i can't estimate, so i would use the wildcard for them.
Thank you
It sounds like you want to handle multiple files, but your script can only handle one file at a time. Furthermore, because you specified FTP, it sounds like the files are on the FTP server, in which case local filename expansion will not help.
You probably want to use the ftp client's mget command to download multiple files matching a pattern on the remote side. You also want to include $TIMESTAMP as part of the pattern. I'd suggest something like this:
ftp remote-hostname <<EOF
cd path/to/log/files
prompt
mget ${TIMESTAMP}0???vel.radar.h5
bye
EOF
This uses a here-document (<<EOF to EOF on a line by itself) to supply input text to the ftp commmand. It will expand the variable $TIMESTAMP so it becomes part of the mget command, e.g. if $TIMESTAMP was 12345, the ftp command will be told mget 123450???vel.radar.h5.
With the ? characters you include not only numbers, but any character. So if you want to include only numbers, you can replace the ??? characters with [0-9][0-9][0-9].
Example:
If you have the following files:
$ ls
0123vel.h5 0333vel.h5 033vel.h5 0pecvel.h5
with this ls you show the correct files:
$ ls 0[0-9][0-9][0-9]vel.radar.h5
0123vel.h5 0333vel.h5

Shell Script Not Finding File

Hello I am trying to write a simple shell script to use in a cronjob to copy a backup archive of website files to a remote server via FTP.
The script below works when I type the file name in by hand manually, but with the date and filename specified as a variable it returns that it can't find ".tar.gz" as if it is ignoring the first part of the filename.
I would be grateful if someone could tell me where I am going wrong.
#!/bin/sh
NOW=$(date +"%F")
FILE="$NOW_website_files.tar.gz"
# set the local backup dir
cd "/home/localserver/backup_files/"
# login to remote server
ftp -n "**HOST HIDDEN**" <<END
user "**USER HIDDEN**" "**PASSWORD HIDDEN**"
cd "/backup_files"
put $FILE
quit
END
This is because it is looking for a variable name NOW_website_files which does not exist, and thus the resulting file name evaluates to .tar.gz.
To solve it, do:
#!/bin/sh
NOW=$(date +"%F")
FILE="${NOW}_website_files.tar.gz"
^ ^
instead of
FILE="$NOW_website_files.tar.gz"
This way it will concatenate the variable $NEW to the _website_files.tar.gz text.
You could do this:
FILE=$(date +"%F_website_files.tar.gz")
instead of this:
NOW=$(date +"%F")
FILE="$NOW_website_files.tar.gz"
IMPORTANT
By the way, consider adding "bi" to your FTP script as you are clealy PUTting a binary file and you don't want CR/LF translation to occur in binary files...

Using a filename with spaces with scp and chmod in bash

Periodically, I like to put files in the /tmp directory of my webserver to share out. What is annoying is that I must set the permissions whenever I scp the files. Following the advice from another question I've written a script which copies the file over, sets the permissions and then prints the URL:
#!/bin/bash
scp "$1" SERVER:"/var/www/tmp/$1"
ssh SERVER chmod 644 "/var/www/tmp/$1"
echo "URL is: http://SERVER/tmp/$1"
When I replace SERVER with my actual host, everything works as expected...until I execute the script with an argument including spaces. Although I suspect the solution might be to use $# I've not yet figured out how to get a spaced filename to work.
It turns out that what is needed is to escape the path which will be sent to the remote server. Bash thinks the quotes in SERVER:"/var/www/tmp/$1" are related to the $1 and removes them from the final output. If I try to run:
tmp-scp.sh Screen\ shot\ 2010-02-18\ at\ 9.38.35\ AM.png
Echoing we see it is trying to execute:
scp SERVER:/var/www/tmp/Screen shot 2010-02-18 at 9.38.35 AM.png
If instead the quotes are escaped literals then the scp command looks more like you'd expect:
scp SERVER:"/var/www/tmp/Screen shot 2010-02-18 at 9.38.35 AM.png"
With the addition of some code to truncate the path the final script becomes:
#!/bin/bash
# strip path
filename=${1##*/}
fullpath="$1"
scp "$fullpath" SERVER:\"/var/www/tmp/"$filename"\"
echo SERVER:\"/var/www/tmp/"$filename"\"
ssh SERVER chmod 644 \"/var/www/tmp/"$filename"\"
echo "URL is: http://SERVER/tmp/$filename"
The script looks right. My guess is that you need to quote the filename when you pass it into your script:
scp-chmod.sh "filename with spaces"
Or escape the spaces:
scp-chmod.sh filename\ with\ spaces
the easier way without worrying about spaces in file names, (besides quoting) is to rename your files to get rid of spaces before transferring. Or when you create the files, don't use spaces. You can make this your "best practice" whenever you name your files.

Resources