Shell Script Not Finding File - bash

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...

Related

How do I call rename successfully from a bash script on Ubuntu?

I have a bash script #!/usr/bin/env bash that is called part of a make process. This script creates a directory with the files pertinent to a realise and then tars them up. I would like to take a copy of the directory and rename some of the files to replace the version identifier with the word "latest". This will make it simple to script the acquisition of the latest file from a web-server. When I run my script, the call to rename seems to do nothing, why is that?
#!/usr/bin/env bash
DATE_NOW="$(date +'%Y%m%d')"
product_id_base="$1"
firmware_dir="${product_id_base}-full-${DATE_NOW}"
# ...rest of file ommitted to protest the innocent
# It creates and fills the ${firmware_dir} with some files that end in
# -$DATE_NOW.<extention> and I would like to rename the copies of them so that they end in
# -latest.<extention>
cp -a "./${firmware_dir}" "./${product_id_base}-full-latest"
# see what there is in pwd
cd "./${product_id_base}-full-latest"
list_output=`ls`
echo $list_output
# Things go OK until this point.
replacment="'s/${DATE_NOW}/latest/'"
rename_path=$(which rename)
echo $replacment
perl $rename_path -v $replacment *
echo $cmd
pwd
$cmd
echo "'s/-${DATE_NOW}/-latest/g'" "${product_id_base}-*"
echo $a
# check what has happened
list_output=`ls`
echo $list_output
I call the above with ./rename.sh product-id and get the expected output from ls that indicates the present working directory is the one full of files that I want renamed.
$ ./rename.sh product-id ET-PIC-v1.1.dat ET-PIC-v1.1.hex
product-id-20160321.bin product-id-20160321.dat
product-id-20160321.elf product-id-20160321.gz 's/20160321/latest/'
/home/thomasthorne/work/product-id/build/product-id-full-latest
's/-20160321/-latest/g' product-id-*
ET-PIC-v1.1.dat ET-PIC-v1.1.hex product-id-20160321.bin
product-id-20160321.dat product-id-20160321.elf product-id-20160321.gz
What I hopped to see was some renamed files. When I directly call the rename function from a terminal emulator I see the rename occur.
~/work/product-id/build/product-id-full-latest$ rename -vn
's/-20160321/-latest/g' * product-id-20160321.bin renamed as
product-id-latest.bin product-id-20160321.dat renamed as
product-id-latest.dat product-id-20160321.elf renamed as
product-id-latest.elf ...
I have tried a few variations on escaping the strings, using ` or $(), removing all the substitutions from the command line. So far nothing has worked so I must be missing something fundamental.
I have read that #!/usr/bin/env bash behaves much like #!/bin/bash so I don't think that is at play. I know that Ubuntu and Debian have different versions of the rename script to some other distributions and I am running on Ubuntu. That lead me to try calling perl /usr/bin/rename ... instead of just rename but that seems to have made no perceivable difference.
This string:
replacment="'s/${DATE_NOW}/latest/'"
will be kept exactly the same because you put it between single quotes.
Have you tried with:
replacment="s/${DATE_NOW}/latest/"
This one worked on my Ubuntu, without perl:
$ ./test_script
filename_20160321 renamed as filename_latest
filename2_20160321 renamed as filename2_latest
filename3_20160321 renamed as filename3_latest
test_script content being:
#!/bin/bash
DATE_NOW="$(date +'%Y%m%d')"
replacment="s/${DATE_NOW}/latest/"
rename -v $replacment *

Create directory while creating file

I'm brand new to Unix and I'm learning how powerful it can be to run scripts on automating file duplication, etc. I've had help creating the initial script (credit where credit's due: https://apple.stackexchange.com/questions/101436/automate-duplicating-and-renaming-images/101437) but now I'm wondering how to generate a specific directory name while duplicating the files. Here's the original script:
#!/bin/bash
file=$1
prefixes=$2
filename=`basename "$file"`
while read line
do
cp $file "$line-$filename"
done < $prefixes
I basically call the script and then have the prefixes from a text file that's in the same directory append a string to the beginning of the new file that's made. What I would like to do is also create a directory with the original file name so I can then have all the duplicate automatically placed in the new folder. I had tried something like this:
#!/bin/bash
file=$1
prefixes=$2
filename=`basename "$file"`
while read line
do
mkdir $filename
cp $file "$filename/$line-$filename"
done < $prefixes
But that doesn't seem to work. You'll see my intentions though. I would like a directory with the same name as the original file and then have all new images copied into that directory. The command I use in Terminal on Mac OSX is ./copier.sh myimage.jpeg prefixes.txt.
I've gotten the script to create a directory if I just use something like mkdir test but that won't do any good since I'll have to go in and change the directory name every time I run the script.
Let me know if you have any questions. I'm sorry if I'm making some major errors, I'm just having trouble finding the solution to this. Thanks for your help!
If $filename is in the same directory you won't be able to create the directory since a file already exists. You could consider using a different name like the filename without an extension.
#!/bin/bash
file=$1
prefixes=$2
filename=${file##*/} ## Better than using an external binary like basename.
dir=${filename%%.*} ## Remove extension.
mkdir -p "$dir" || exit 1 ## Only need to create it once so place it outside the loop. And `$dir` might already have been made so use `-p`. This would also make the code exit if `mkdir` fails.
while read -r line ## Use -r to read lines in raw form
do
cp "$file" "$dir/$line-$filename"
done < "$prefixes"
Consider quoting your variables properly around "" as well .

How to save a string from a file into a variable in bash

I am trying to make a script that will ask you for a path to several files when you set it up and when you run the actual script, it reads the path from a file that you created earlier. I can make the file, I just need to know how to take that path and use it in the current script.
ex.
Settings
/home/user/launcher
Launcher
cat Settings
read PathToLaunchers
cd \$PathToLaunchers
read pathToFiles
for f in $pathToFiles
do
cat $f
done
I am just printing the contexts of each file entered in pathToFiles. You can replace cat command with the command you are interested.
If pathToFiles has only one line (i.e. only one filename), then you dnt need the for loop and just use cat $pathToFiles

variable in scp filename not working?

I'm trying to scp a backup tgz file from one server to another every night. The backup script uses the following $date var just fine but when I modify it slightly for scp it breaks:
#!/bin/sh
date=`date +%Y-%m-%d`
rbfile=`/backups/$date_00h00.tgz`
scp $rbfile user#myserverip:
But the script dies with the error:
/backups/.tgz: No such file or directory
On a side note, I really should switch to rsync for better remote backups - the tgz files are at 3.5GB now. Any recommended tutorials?
when using $date_00h00 you tell bash to use the variable named date_00h00, because letters, numbers and _ characters are allowed as variables names.
Enclose the variable name in {} and it will correct the problem :
rbfile=`/backups/${date}_00h00.tgz`

Shell script not picking up password file...

Running the below shell script seems to ignore the password file I'm feeding it. I'm continually prompted for it. If I enter it, the rest of the script goes without a hitch, but as I'm running it via cron, I really need to get it to read from the file... Any suggestions?
#!/bin/sh
p=$(<password.txt)
set -- $p
pass_phrase=$1
destination="/var/www/d"
cd /var/sl/
for FILE in *.pgp;
do
FILENAME=${FILE%.pgp}
gpg --passphrase "$pass_phrase" --output "$destination/$FILENAME" --decrypt "$FILE"
rm -f $FILE
done
Your problem lies in line 2:
p=$(<password.txt)
What you are doing here is to run an "empty command" in a subshell, storing its output in the variable p. What you rather want to do though, is to run a command that outputs the contents of the password file to stdout. So:
p=$(cat <password.txt)
This will do the trick.
You probably need to specify a full path to the file. Or in your cron job, first cd to the directory containing that file.
Does --passphrase really exist? According to the manpage it doesn't, but the versions might be different.
Where is the password file? cron has a different PATH, which can cause scripts to behave differently when you run them yourself.
Possible solution one, put
cd `dirname $0`
at the top of the script, which would cd into the script's directory when it runs.
Possible solution two, try specifying the file directly with an absolute path:
gpg --passphrase-file /some/path/password.txt -o "$destination/$FILENAME" -d "$FILE"

Resources