How to run multi commands in one sh file? - bash

I have a mac os and
my question is about 'How to run multi commands in one sh file?', like this :
#!/bin/bash
ftp
open domain.com
user
pass
cd /public_html/test_folder
lcd /Users/mac/downloads
mput file
a
This commands for :
open ftp
connect to my website
enter user name
enter password
cd << for open folder in my website
lcd << open folder in my computer
mput << upload file from my computer
a << for question in ftp for file type or something like this
I add && in end each line but no work he start and stop in command line number 2
I'm sorry for my bad language :(

Use lftp, very good in ftp scripting, when you require reconnect+continue file transfer, ssh/scp transfer, etc.
It should be similar to this:
#!/bin/bash
## note: mput: -c (retry+continue); run: lftp -c 'help mput' to see help
lftp -c 'mput -c -O ftp://name:passd#server.com/path/ file1.txt file2.txt'
Alternatively, you can write lftp scripts, example (note: mirror -R = upload):
#!/usr/bin/lftp -f
open ftp://ftp.server.com
user name passwd
cd /remote/path
lcd /local/path
mirror -R folder

Related

FTP files in different folders using shell script

I'm trying for an ftp script, that sends files in different folders within the same connection, but no luck with below script.
#!/bin/bash
HOST_NAME=host.server
username= user_name
passwd= password
remote = /path_to_remote/folder
local = /path_to_local/folder
folder=$1
pwd
ftp -in <<EOF
open $HOST_NAME
user $username $passwd
cd local/
lcd remote/
put a_filename_<timestamp>.txt
mkdir $remote/$folder
cd $remote/$folder
lcd $local/$folder
put b_filename.txt
close
bye
Adding to this, at run-time, is it possible to send only the latest files created in the last 10 minutes?
Try this:
#!/bin/bash
HOST_NAME=host.server
username=user_name
passwd=password
remote=/path_to_remote/folder
local=/path_to_local/folder
folder="$1"
pwd
ftp -in <<EOF
open "$HOST_NAME"
user "$username" "$passwd"
cd local/
lcd remote/
put a_filename_<timestamp>.txt
mkdir "$remote/$folder"
cd "$remote/$folder"
lcd "$local/$folder"
put b_filename.txt
close
bye
EOF
Notes:
The shell doesn't allow spaces next to =.
Quote variables.
OP code lacked closing EOF.
I've left the <timestamp> alone, that'd be a different Q.

Transferring the Contents of a Folder Using smbclient

I have written a Shell script that moves into a directory with some binaries files present.
What I am looking to do is transfer all the files present inside this directory.
cd /home/user/binaries
smbclient //ip.address/directory$ password -W domain -U username << ENDOFMYSMBCOMMANDS
prompt
put *
exit
ENDOFMYSMBCOMMANDS
I tried to use put * to transfer all files - but this is not accepted.
The only other option I know of is to go one folder up, and use the command mput binaries - but this copies everything including the folder.
How can I modify my script to only transfer the contents of the directory?
I'm going to format the self-answer of Dustin a bit differently into a real one-liner. It is also possible to add the prepended "cd" command into the smbclient command, like so:
smbclient //ip.address/directory -W domain -U username \
-c 'prompt OFF; recurse ON; cd remote/target/directory; lcd /local/source/directory; mput *'
I had the answer with me all along!! I was under the impression that mput could only be used to transfer a directory, turns out that using mput * inside a directory will copy all the files located within that directory!
cd /home/user/binaries
smbclient //ip.address/directory$ password -W domain -U username << ENDOFMYSMBCOMMANDS
prompt
put *
exit
ENDOFMYSMBCOMMANDS
Going to leave this here for anyone else who gets stumped on this like me!

ksh script to send .jpg to remote server through ftp script

Hello just created a ksh script to ftp .jpg image to a remote server but the images are showing in bad qulity when I send them with the script is there a line I should fix to not alterate the image a deliver the image to the remote server like the original please help, should I add the bin line?
cp -r /path/dir/*.jpg /path/dir
cp -r /path/dir/*.JPG /path/dirREMOTE
USER='xxx'
PASSWORD=xxx'
source_dir='cd /path/images/'
target_dir='cd /images'
ftp -n xxx.xx.xxx.xx <<_FTP
quote USER $USER
quote PASS $PASSWORD
lcd /xxx/xxx/
cd /xxx
mput *.jpg
bye
_FTP
/home/test_scripts/test_script9.sh
/home/test_scripts/test_script7.sh
exit
enter code here

How to CD inside a SFTP connection where the connection is established using - Shell script

In my script - i create a sftp connection.
I read some directory value from user earlier and once the sftp connection is established, i try to cd to that dir which i got from the user.
But its not working, probably bec the prompt goes inside the server to which the SFTP connection was established.
In this case how to make it work ?
I also faced this problem and was able to find the solution. The solution is right there in the man page of sftp. In the man page, you will find where it is written the format of using sftp like this:
sftp [options] [user#]host[:dir[/]]
Actually, two formats are given there but this is the one I wanted to use and it worked.
So, what do you do? You simply supply the username#host as seen there, then, without any space followed by : and the path you want to change to in the client/remote server in your script and that's all. Here is a practical example:
sftp user#host:/path/
If your script does, as you state somewhere in this page,
sftp $user#$host cd $directory
and then tries to do something else, like:
sftp $user#$host FOO
That command FOO will not be executed in the same directory $directory since you're executing a new command, which will create a new connection to the SFTP server.
What you can do is use the "batchfile" option of sftp, i.e. construct a file which contains all the commands you'd like sftp to do over one connection, for example:
$ cat commands.txt
cd foo/bar
put foo.tgz
lcd /tmp/
get foo.tgz
Then, you will be able to tell sftp to execute those commands in one connection, by executing:
sftp -b commands.txt $user#$host
So, I propose your solution to be:
With user's input, create a temporary text file which contains all the commands to be executed over one SFTP connection, then
Execute sftp using that temporary text file as "batch file"
Your script would do something like:
echo "Directory in which to go:"
read directory
temp=$( mktemp /tmp/FOOXXX )
echo "" > $temp
echo "cd $directory" >> $temp
# other commands
sftp -b $temp $user#$host
rm $temp
If you are trying to change the directory of the machine, try lcd
In what way is it not working? To change directories on the remote server, you use the "cd" command. To change directories on the local server, you use the "lcd" command. Read "man sftp".

How to run the sftp command with a password from Bash script?

I need to transfer a log file to a remote host using sftp from a Linux host. I have been provided credentials for the same from my operations group. However, since I don't have control over other host, I cannot generate and share RSA keys with the other host.
So is there a way to run the sftp command (with the username/password provided) from inside the Bash script through a cron job?
I found a similar Stack Overflow question, Specify password to sftp in a Bash script, but there was no satisfactory answer to my problem.
You have a few options other than using public key authentication:
Use keychain
Use sshpass (less secured but probably that meets your requirement)
Use expect (least secured and more coding needed)
If you decide to give sshpass a chance here is a working script snippet to do so:
export SSHPASS=your-password-here
sshpass -e sftp -oBatchMode=no -b - sftp-user#remote-host << !
cd incoming
put your-log-file.log
bye
!
Another way would be to use lftp:
lftp sftp://user:password#host -e "put local-file.name; bye"
The disadvantage of this method is that other users on the computer can read the password from tools like ps and that the password can become part of your shell history.
A more secure alternative which is available since LFTP 4.5.0 is setting the LFTP_PASSWORD environment variable and executing lftp with --env-password. Here's a full example:
export LFTP_PASSWORD="just_an_example"
lftp --env-password sftp://user#host -e "put local-file.name; bye"
# Destroy password after use
export LFTP_PASSWORD=""
LFTP also includes a cool mirroring feature (can include delete after confirmed transfer --Remove-source-files):
lftp -e 'mirror -R /local/log/path/ /remote/path/' --env-password -u user sftp.foo.com
EXPECT is a great program to use.
On Ubuntu install it with:
sudo apt-get install expect
On a CentOS Machine install it with:
yum install expect
Lets say you want to make a connection to a sftp server and then upload a local file from your local machine to the remote sftp server
#!/usr/bin/expect
spawn sftp username#hostname.com
expect "password:"
send "yourpasswordhere\n"
expect "sftp>"
send "cd logdirectory\n"
expect "sftp>"
send "put /var/log/file.log\n"
expect "sftp>"
send "exit\n"
interact
This opens a sftp connection with your password to the server.
Then it goes to the directory where you want to upload your file, in this case "logdirectory"
This uploads a log file from the local directory found at /var/log/ with the files name being file.log to the "logdirectory" on the remote server
You can use lftp interactively in a shell script so the password not saved in .bash_history or similar by doing the following:
vi test_script.sh
Add the following to your file:
#!/bin/sh
HOST=<yourhostname>
USER=<someusername>
PASSWD=<yourpasswd>
cd <base directory for your put file>
lftp<<END_SCRIPT
open sftp://$HOST
user $USER $PASSWD
put local-file.name
bye
END_SCRIPT
And write/quit the vi editor after you edit the host, user, pass, and directory for your put file typing :wq .Then make your script executable chmod +x test_script.sh and execute it ./test_script.sh.
I was recently asked to switch over from ftp to sftp, in order to secure the file transmission between servers. We are using Tectia SSH package, which has an option --password to pass the password on the command line.
example : sftp --password="password" "userid"#"servername"
Batch example :
(
echo "
ascii
cd pub
lcd dir_name
put filename
close
quit
"
) | sftp --password="password" "userid"#"servername"
I thought I should share this information, since I was looking at various websites, before running the help command (sftp -h), and was i surprised to see the password option.
You can override by enabling Password less authentication. But you should install keys (pub, priv) before going for that.
Execute the following commands at local server.
Local $> ssh-keygen -t rsa
Press ENTER for all options prompted. No values need to be typed.
Local $> cd .ssh
Local $> scp .ssh/id_rsa.pub user#targetmachine:
Prompts for pwd$> ENTERPASSWORD
Connect to remote server using the following command
Local $> ssh user#targetmachine
Prompts for pwd$> ENTERPASSWORD
Execute the following commands at remote server
Remote $> mkdir .ssh
Remote $> chmod 700 .ssh
Remote $> cat id_rsa.pub >> .ssh/authorized_keys
Remote $> chmod 600 .ssh/authorized_keys
Remote $> exit
Execute the following command at local server to test password-less authentication.
It should be connected without password.
$> ssh user#targetmachine
The easiest way I found to accomplish this, without installing any third-party library like Expect, SSHPASS...etc, is by using a combination of CURL, and SFTP. Those two are almost in every Linux machine.
This is the command you should execute, after changing the values.
curl -k "sftp://SERVER_IP:SERVER_PORT/FULL_PATH_OF_THE_FILE" --user "SERVER_USER:SERVER_PASSOWRD" -o "THE_NAME_OF_THE_FILE_AFTER_DOWNLOADING_IT"
Example:
curl -k "sftp://10.10.10.10:77/home/admin/test.txt" --user "admin:123456" -o "test.txt"
Explanation:
We are connecting to the server 10.10.10.10:77 using the username admin and password 123456, to move the file /home/admin/test.txt from that server to the server you are using currently to execute the above command.
Combine sshpass with a locked-down credentials file and, in practice, it's as secure as anything - if you've got root on the box to read the credentials file, all bets are off anyway.
Bash program to wait for sftp to ask for a password then send it along:
#!/bin/bash
expect -c "
spawn sftp username#your_host
expect \"Password\"
send \"your_password_here\r\"
interact "
You may need to install expect, change the wording of 'Password' to lowercase 'p' to match what your prompt receives. The problems here is that it exposes your password in plain text in the file as well as in the command history. Which nearly defeats the purpose of having a password in the first place.
You can use sshpass for it. Below are the steps
Install sshpass For Ubuntu - sudo apt-get install sshpass
Add the Remote IP to your known-host file if it is first time
For Ubuntu -> ssh user#IP -> enter 'yes'
give a combined command of scp and sshpass for it.
Below is a sample code for war coping to remote tomcat
sshpass -p '#Password_For_remote_machine' scp /home/ubuntu/latest_build/abc.war #user##RemoteIP:/var/lib/tomcat7/webapps
You can use a Python script with scp and os library to make a system call.
ssh-keygen -t rsa -b 2048 (local machine)
ssh-copy-id user#remote_server_address
create a Python script like:
import os
cmd = 'scp user#remote_server_address:remote_file_path local_file_path'
os.system(cmd)
create a rule in crontab to automate your script
done
A few people have mentioned sshpass but not many clear coding examples...
This is how we are doing it with bash scripts for rsync backups:
sshpass -p "${RSYNC_PASSWORD}" sftp "${RSYNC_USER}"#"${RSYNC_REMOTE_HOST}"
Keep in mind you will have to sudo apt install sshpass before this works properly.

Resources