I want to be able to access many of my scripts/projects, from everywhere. So, uploading them to a server is the only solution. Until now, i was using Git repositories. For sure it's the best way to do so, but there is only one problem. I don't want all of my projects to be visible/accessible by others. Make them private, you would say... sure. But then you have to login every time and use two way authentication, all the time, which is safe, but it gets in my nerves, specially if you have to do so, multiple times.
Simple FTP is not the safest way to store things. Use it on your own risk.
The solution for me, is to use an FTP server and create something like Github, but in a more simpler way. If you don't know, there is also FTP Git, that uses FTP server to store repositories, exactly like Github, but because i wanted a simpler solution, i preferred another way...
So, i created fgitish
a BASH script, that uses the Linux ftp program, to upload/download my projects, on a private FTP server, with parameters like Git and some twists. The main principle is to store each project in a .zip file, into a default directory on the ftp server. The directory, except the .zip files, will also contain an index.txt
file, like the old FTP sites, that will store the name of the project and a small one line description, just to keep track, of what is what.
Below is the syntax for the script. When you want to store a project, just from within the directory of the project, you enter fgitish push
. The script will create a .zip file, with the name of the current directory and store it, on the ftp directory, you set up.
If you want to download or clone a project, you can use the clone
, flist
, index
commands to do so. Each one has a twist and its usefulness. To keep track of the files/projects, you can use the index.txt
file. Give fgitish edit
to create or edit the file, to add descriptions to each project.
Usage: fgitish <command> [args]
From Remote to Local
clone <file> Clone file into current directory
get <file> Get specific file (don't extract)
edit Edit the index file
remove Remove remote file
List Projects/Files
list List Files in remote directory
flist Lists files and select one to download
index Show Index file and select file to download
From Local to Remote
push Uploads current dir as an archive to remote server
You can get the script below. Make sure to enter your ftp username, password, host and directory to store your files/projects. You can also store the username/password values in a separate file, if you don't want them to be in the script file. You could also use a method to encrypt/decrypt them on the fly and store them encrypted in that file.
#!/bin/bash
script="${0##*/}"
#script="${script%.*}"
DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
# server settings
HOST='ftp.host.com'
FTPDIR='fgitish'
# user password
if [ -f ~/scripts/ftppassword.asc ]; then
source ~/scripts/ftppassword.asc
else
USER='username'
PASSWD='password'
fi
# other settings
EDITOR="nano"
#yellow start
C14="\e[1;33m"
#blue start
C01="\e[0;34m"
#color end
CE="\e[0m"
#red start
C04="\e[1;31m"
#black start
C00="\e[0;30m"
#dark gray start
C08="\e[1;30m"
#light blue start
C09="\e[1;34m"
#green start
C02="\e[0;32m"
#light green start
C10="\e[1;32m"
#cyan start
C03="\e[0;36m"
#light cyan start
C11="\e[1;36m"
#light red start
C12="\e[0;31m"
#purple start
C05="\e[0;35m"
#light purple start
C13="\e[1;35m"
#brown start
C06="\e[0;33m"
#light gray start
C07="\e[0;37m"
#white
C15="\e[1;37m"
#setting frequent stings
YNYES="("$C14"Y"$CE"/"$C14"n"$CE")("$C14"Enter"$CE"=yes)"
YNNO="("$C14"y"$CE"/"$C14"N"$CE")("$C14"Enter"$CE"=no)"
VERSION=1.0.0
READAK="read -n 1"
function msg() {
ts=$(date +"%Y/%m/%d %H:%M:%S")
echo -e $C03"[$ts] "$C14"$1"$CE
}
function error() {
ts=$(date +"%Y/%m/%d %H:%M:%S")
echo -e $C03"[$ts] "$C04"$1"$CE
}
function presskey() {
echo ""
echo "Press a key to continue..."
read -n 1
}
prompt_confirm_no() {
while true; do
echo -e -n "${1:-Continue?} ${YNNO}: "
read -e -r -n 1 REPLY
case $REPLY in
[yY]) echo ; return 0 ;;
[nN]) echo; echo "Going back..."; sleep 1; return 1 ;;
$'\0A') echo; echo "Going back..."; sleep 1; return 1 ;;
*) printf " \033[31m %s \n\033[0m" "invalid input"
esac
done
}
prompt_confirm_yes() {
while true; do
echo -e -n "${1:-Continue?} $YNYES: "
read -e -r -n 1 REPLY
case $REPLY in
[yY]) echo ; return 0 ;;
[nN]) echo; echo "Going back..."; return 1 ;;
$'\0A') echo; echo "Accepted..."; return 0 ;;
*) printf " \033[31m %s \n\033[0m" "invalid input"
esac
done
}
function fzz() {
#"right,50%,:wrap"
fzf --ansi --bind 'enter:execute(echo {1})+abort' --bind 'end:last' --bind 'home:first' --header $"Listing: $FTPDIR | ENTER: Accept | ESC: Abort"
}
function list(){
msg "Connecting..."
ftp -V -i -n $HOST <<END_SCRIPT
user ${USER} ${PASSWD}
cd ${FTPDIR}
ls
quit
END_SCRIPT
if [ $? -ne 0 ]; then
error "Connection... Failed!"
return 1
fi
msg "Success!"
}
function flist(){
msg "Connecting..."
ftp -V -i -n $HOST <<END_SCRIPT
user ${USER} ${PASSWD}
cd ${FTPDIR}
ls . /tmp/listing.txt
quit
END_SCRIPT
if [ $? -ne 0 ]; then
error "Connection... Failed!"
return 1
fi
fn="$(cat /tmp/listing.txt | awk '{print $9}' | fzz)"
if [ ! -z "$fn" ]; then
get "$fn"
fi
}
function get(){
msg "Connecting..."
fn="$1"
if [ "${fn: -4}" != ".zip" ]; then
fn="$fn".zip
fi
ftp -V -n $HOST <<END_SCRIPT
user ${USER} ${PASSWD}
cd ${FTPDIR}
get "$fn"
quit
END_SCRIPT
if [ $? == 0 ]; then
msg "Success!"
else
error "Failed!"
fi
}
function remove(){
msg "Connecting..."
fn="$1"
if [ "${fn: -4}" != ".zip" ]; then
fn="$fn".zip
fi
ftp -i -V -n $HOST <<END_SCRIPT
user ${USER} ${PASSWD}
cd ${FTPDIR}
mdelete "$fn"
quit
END_SCRIPT
if [ $? == 0 ]; then
msg "File removed!"
else
error "Failed!"
fi
}
function index(){
msg "Connecting..."
ftp -V -n $HOST <<END_SCRIPT
user ${USER} ${PASSWD}
cd ${FTPDIR}
get index.txt
quit
END_SCRIPT
if [ $? == 0 ]; then
msg "Success!"
else
error "Failed!"
fi
sel=$(cat index.txt | fzz | cut -f1 -d' ')
if [ ! -z $sel ]; then
clone $sel
fi
rm index.txt
}
function edit(){
msg "Getting file..."
ftp -V -n $HOST <<END_SCRIPT
user ${USER} ${PASSWD}
cd ${FTPDIR}
get index.txt
quit
END_SCRIPT
if [ -f index.txt ]; then
msg "Edit file..."
$EDITOR index.txt
msg "Uploading file..."
ftp -V -n $HOST <<END_SCRIPT
user ${USER} ${PASSWD}
cd ${FTPDIR}
put index.txt
quit
END_SCRIPT
if [ $? == 0 ]; then
msg "File uploaded successful!"
rm ./index.txt
else
error "Failed to upload file"
fi
else
error "File not found or couldn't be downloaded!"
fi
}
function clone(){
fn="$1"
if [ ! "$fn" == "*.zip" ]; then
fn="$fn".zip
fi
msg "Connecting..."
ftp -V -n $HOST <<END_SCRIPT
user ${USER} ${PASSWD}
cd ${FTPDIR}
get "$fn"
quit
END_SCRIPT
if [ $? -ne 0 ]; then
error "Connection... Failed!"
return 1
fi
msg "Connection... Success!"
dr="${fn%.*}"
msg "Cloning in: $dr"
mkdir $dr
msg "Extracting content..."
unzip "$1" -d ./$dr
rm "$fn"
msg "Done!"
}
function send(){
fn="$(basename "$PWD")".zip
zip -r "/tmp/$fn" .
cd /tmp
msg "Uploading file..."
ftp -V -n $HOST <<END_SCRIPT
user ${USER} ${PASSWD}
cd ${FTPDIR}
put "$fn"
quit
END_SCRIPT
if [ $? == 0 ]; then
msg "Success!"
else
error "Failed!"
fi
rm "$fn"
}
if [ $# -eq 0 ]; then
echo " "
echo "Usage: fgitsh <command> [args]"
echo " "
echo -e $C14" From Remote to Local"$CE
echo -e $C15" clone <file> $C07 Clone file into current directory"$CE
echo -e $C15" get <file> $C07 Get specific file (don't extract)"$CE
echo -e $C15" edit $C07 Edit the index file"$CE
echo -e $C15" remove $C07 Remove remote file"$CE
echo " "
echo -e $C14" List Projects/Files"$CE
echo -e $C15" list $C07 List Files in remote directory"$CE
echo -e $C15" flist $C07 Lists files and select one to download"$CE
echo -e $C15" index $C07 Show Index file and select file to download"$CE
echo " "
echo -e $C14" From Local to Remote"$CE
echo -e $C15" push $C07 Uploads current dir as an archive to remote server"$CE
echo " "
exit 1
fi
case "$1" in
"list") list;;
"push") send;;
"flist") flist;;
"clone") clone "$2";;
"get") get "$2";;
"edit") edit;;
"index") index;;
"remove") remove "$2";;
*) echo "Unknown command!";;
esac