I want a batch file to ftp to a server, read out a text file, and disconnect. The server requires a user and password. I tried
#echo off
pause
#ftp example.com
username
password
pause
but it never logged on. How can I get this to work?
The answer by 0x90h helped a lot...
I saved this file as u.ftp:
open 10.155.8.215
user
password
lcd /D "G:\Subfolder\"
cd folder/
binary
mget file.csv
disconnect
quit
I then ran this command:
ftp -i -s:u.ftp
And it worked!!!
Thanks a lot man :)
Using the Windows FTP client you would want to use the -s:filename option to specify a script for the FTP client to run. The documentation specifically points out that you should not try to pipe input into the FTP client with a < character.
Execution of the script will start immediately, so it does work for username/password.
However, the security of this setup is questionable since you now have a username and password for the FTP server visible to anyone who decides to look at your batch file.
Either way, you can generate the script file on the fly from the batch file and then pass it to the FTP client like so:
#echo off
REM Generate the script. Will overwrite any existing temp.txt
echo open servername> temp.txt
echo username>> temp.txt
echo password>> temp.txt
echo get %1>> temp.txt
echo quit>> temp.txt
REM Launch FTP and pass it the script
ftp -s:temp.txt
REM Clean up.
del temp.txt
Replace servername, username, and password with your details and the batch file will generate the script as temp.txt launch ftp with the script and then delete the script.
If you are always getting the same file you can replace the %1 with the file name. If not you just launch the batchfile and provide the name of the file to get as an argument.
This is an old post however, one alternative is to use the command options:
ftp -n -s:ftpcmd.txt
the -n will suppress the initial login and then the file contents would be: (replace the 127.0.0.1 with your FTP site url)
open 127.0.0.1
user myFTPuser myftppassword
other commands here...
This avoids the user/password on separate lines
You need to write the ftp commands in a text file and give it as a parameter for the ftp command like this:
ftp -s:filename
More info here: http://www.nsftools.com/tips/MSFTP.htm
I am not sure though if it would work with username and password prompt.
Each line of a batch file will get executed; but only after the previous line has completed. In your case, as soon as it hits the ftp line the ftp program will start and take over user input. When it is closed then the remaining lines will execute. Meaning the username/password are never sent to the FTP program and instead will be fed to the command prompt itself once the ftp program is closed.
Instead you need to pass everything you need on the ftp command line. Something like:
#echo off
echo user MyUserName> ftpcmd.dat
echo MyPassword>> ftpcmd.dat
echo bin>> ftpcmd.dat
echo put %1>> ftpcmd.dat
echo quit>> ftpcmd.dat
ftp -n -s:ftpcmd.dat SERVERNAME.COM
del ftpcmd.dat
Use
ftp -s:FileName
as decribed in Windows XP Professional Product Documentation.
The file name that you have to specify in place of FileName must contain FTP commands that you want to send to the server. Among theses commands are
open Computer [Port] to connect to an FTP server,
user UserName [Password] [Account] to authenticate with the FTP server,
get RemoteFile [LocalFile] to retrieve a file,
quit to end the FTP session and terminate the ftp program.
More commands can be found under Ftp subcommands.
Here's what I use. In my case, certain ftp servers (pure-ftpd for one) will always prompt for the username even with the -i parameter, and catch the "user username" command as the interactive password. What I do it enter a few NOOP (no operation) commands until the ftp server times out, and then login:
open ftp.example.com
noop
noop
noop
noop
noop
noop
noop
noop
user username password
...
quit
You can use PowerShell as well; this is what I did. As I needed to download a file based on a pattern I dynamically created a command file and then let ftp do the rest.
I used basic PowerShell commands. I did not need to download any additional components. I first checked if the requisite number of files existed. If they I invoked the FTP the second time with an Mget.
I run this from a Windows Server 2008 connecting to a Windows XP remote server.
function make_ftp_command_file($p_file_pattern,$mget_flag)
{
# This function dynamically prepares the FTP file.
# The file needs to be prepared daily because the
# pattern changes daily.
# PowerShell default encoding is Unicode.
# Unicode command files are not compatible with FTP so
# we need to make sure we create an ASCII file.
write-output "USER" | out-file -filepath C:\fc.txt -encoding ASCII
write-output "ftpusername" | out-file -filepath C:\fc.txt -encoding ASCII -Append
write-output "password" | out-file -filepath C:\fc.txt -encoding ASCII -Append
write-output "ASCII" | out-file -filepath C:\fc.txt -encoding ASCII -Append
If ($mget_flag -eq "Y")
{
write-output "prompt" | out-file -filepath C:\fc.txt -encoding ASCII -Append
write-output "mget $p_file_pattern" | out-file -filepath C:\fc.txt -encoding ASCII -Append
}
else
{
write-output "ls $p_file_pattern" | out-file -filepath C:\fc.txt -encoding ASCII -Append
}
write-output quit | out-file -filepath C:\fc.txt -encoding ASCII -Append
}
########################### Init Section ###############################
$yesterday = (get-date).AddDays(-1)
$yesterday_fmt = date $yesterday -format "yyyyMMdd"
$file_pattern = "BRAE_GE_*" + $yesterday_fmt + "*.csv"
$file_log = $yesterday_fmt + ".log"
echo $file_pattern
echo $file_log
############################## Main Section ############################
# Change location to folder where the files need to be downloaded
cd c:\remotefiles
# Dynamically create the FTP Command to get a list of files from
# the remote servers
echo "Call function that creates a FTP Command "
make_ftp_command_file $file_pattern N
#echo "Connect to remote site via FTP"
# Connect to Remote Server and get file listing
ftp -n -v -s:C:\Clover\scripts\fc.txt 10.129.120.31 > C:\logs\$file_log
$matches=select-string -pattern "BRAE_GE_[A-Z][A-Z]*" C:\logs\$file_log
# Check if the required number of Files available for download
if ($matches.count -eq 36)
{
# Create the FTP command file
# This time the command file has an mget rather than an ls
make_ftp_command_file $file_pattern Y
# Change directory if not done so
cd c:\remotefiles
# Invoke ftp with newly created command file
ftp -n -v -s:C:\Clover\scripts\fc.txt 10.129.120.31 > C:\logs\$file_log
}
else
{
echo "The full set of files is not available"
}
I have written a script as *.sh file
#!/bin/sh
set -x
FTPHOST='host-address'
FTPUSER='ftp-username'
FTPPASSWD='yourPass'
ftp -n -v $FTPHOST << EOT
ascii
user $FTPUSER $FTPPASSWD
prompt
##Your commands
bye
EOT
Works fine for me
If you need to pass variables to the txt file you can create in on the fly and remove after.
This is example is a batch script running as administrator. It creates a zip file using some date & time variables. Then it creates a ftp text file on the fly with some variables. Then it deletes the zip, folder and ftp text file.
set YYYY=%DATE:~10,4%
set MM=%DATE:~4,2%
set DD=%DATE:~7,2%
set HH=%TIME: =0%
set HH=%HH:~0,2%
set MI=%TIME:~3,2%
set SS=%TIME:~6,2%
set FF=%TIME:~9,2%
set dirName=%YYYY%%MM%%DD%
set fileName=%YYYY%%MM%%DD%_%HH%%MI%%SS%.zip
echo %fileName%
"C:\Program Files\7-Zip\7z.exe" a -tzip C:\%dirName%\%fileName% -r "C:\tozip\*.*" -mx5
(
echo open 198.123.456.789
echo user#somedomain.com
echo yourpassword
echo lcd "C:/%dirName%"
echo cd theremotedir
echo binary
echo mput *.zip
echo disconnect
echo bye
) > C:\ftp.details.txt
cd C:\
FTP -v -i -s:"ftp.details.txt"
del C:\ftp.details.txt /f
I programmed a Java app. For complex reasons I cannot export it as an executable (due to CVS and environment promoting practices) to Linux. I also cannot add the main class path to the MANIFEST.MF via 'jar -cvmf' command because it is not installed in the Linux environment the app is running in (I have no control over what gets installed). The only other option I found was to create the following shell script:
#!/bin/bash
#check that parameters were passed
if [ $# -lt 2 ]; then
echo ""
echo "Not enough arguments provided. You must have at least 2 arguments with ISO SQL time stamps."
echo " After that you can have unlimited number of parameters for tools."
echo ""
exit 1
fi
echo "Recovering events that occurred between $#"
ROOT_DIR=_spool_generator
JAR_DIR=jar
mkdir $ROOT_DIR
mkdir $ROOT_DIR/$JAR_DIR
FULL_DIR=$ROOT_DIR/$JAR_DIR
cp /home/wma/jar/SpoolGenerator.jar ./$FULL_DIR/
echo $#
START=$1
END=$2
java -cp "./$FULL_DIR/SpoolGenerator.jar" com.btv.main.Driver $# # --> does not work
#java -cp "./$FULL_DIR/SpoolGenerator.jar" com.btv.main.Driver "2001-02-12 18:15:00.0" "2001-02-12 19:15:00.0" --> works
#java -cp "./$FULL_DIR/SpoolGenerator.jar" com.btv.main.Driver "$START" "$END" --> works
echo "Execution is complete..."
exit
The key issue here is that I have an unlimited number of parameters the application uses. This works great when deploying the java app directly as an executable in Windows, works fine if I specify the positional arguments the Shell script takes, but how do I pass these same arguments to the java app from within the Linux script. I have to pass the parameters to the script surrounded in quotes due to the timstamp's special characters, this seems to cause some aberrant parsing when the parameters are passed to the jar. I appreciate any help.
I have a salt SLS file, test.sls as follows,
test:
cmd.run:
- name : |
java -jar test.jar
Here test.jar runs a command which is to launch eclipse and run a specified configuration(which runs forever). Since this runs forever(unless I stop) when I run the following command,
sudo salt 'ubuntu' state.sls test
This will not return to the master from minion. What will happen in this case? will the job automatically stopped after certain time out? In general how to run jobs that never end using salt?
I found the solution!
If you redirect the stdout/stderr to /dev/null, it is possible to run the process in background and prevent salt from waiting for the process.
Here is an example:
run-my-cmd:
cmd.run:
- name: ./run-your-script >/dev/null 2>&1 &
If your script has some stdout, you should ensure:
Many state functions in this module now also accept a stateful
argument. If stateful is specified to be true then it is assumed that
the command or script will determine its own state and communicate it
back by following a simple protocol
And your end of the output should be:
# writing the state line
echo # an empty line here so the next line will be the last.
echo "changed=yes comment='something has changed' whatever=123"
Check salt.states.cmd.
Did you try using:
test:
cmd.run:
- name : |
sh -c "java -jar test.jar >/dev/null 2>&1 &"
I din't try it but it should put the process you want in background while the main sh command quits.
I would like to know if we can create files from a html page in browser to the linux server folder? I have a shell script which creates txt files.. But when i trigger this script from browser using ajax it doesn't create any files.. I gave all permissions to the parent directory but still i dont see file creations nor any error.
test.sh
echo "first sh"
java HelloWorld
echo "t1 test" > t1s
if [ ! -f t1s ]
then
echo "Shell File is not created .."
else
echo "Shell file is created.. "
fi
------
first.php
<?php
$output=shell_exec('sh test.sh');
echo "Hello Php \r\n";
echo $output;
echo "done \r\n";
?>
-----------
This is the output from command line:
Hello Php
hello first sh Shell file is created..
done
----------------
This is the output from broswer:
Hello Php hello first sh Shell File is not created .. done
When executing scripts via your web server, it helps to note that the environment used by your webserver is rarely identical to the environment that you see as a CLI user. For example, the command
sh test.sh
makes two assumptions: sh is in your $PATH, and test.sh is in the current working directory. It is very likely that neither of these are true when your webserver tries to run the command.
For better results, try including full paths to both the command and the file. For example:
shell_exec('/bin/sh /var/www/html/scripts/test.sh');
Finally, check the executable permissions on test.sh to be sure that the web user (httpd, or apache, or whatever) has permission to execute that script.
There are two things to note right off the bat....
The shell script runs fine manually
A simple shell script (echo hello) that I wrote runs fine through java
So I have a shell script that I'm attempting to run through a Java process.
File sqlF = new File("path to deploy script");
Process proc = rt.exec(sqlF + "/deploy.sh");
proc.waitFor();
System.out.println(proc.exitValue());
When I run this code I get an ambiguous return value of "1".
Here's the shell script (because I imagine the issue may stem from here):
#!/bin/bash
mysql -u XXXX -h XXXXX < XXXXX.sql
mysql -u XXXX -h XXXXX database < DEPLOY-HELPER.sql
Any ideas as to why this would not execute properly from Java?
If you want to run a shell script you must explicitly invoke the shell and pass it the name of the script as an argument, as in
bash /path/to/script/deploy.sh
Neither Runtime.exec() nor ProcessBuilder know how to execute shell scripts themselves, they only know how to execute binary executables.