How to use date variables in PuTTY/PSFTP batch-script? - putty

I like to use date variables in a PuTTY/PSFTP batch-script to select files with a certain timestamp in the filename.
But I couldn't find anything in the docs. Is there a command for PuTTY/PSFTP batch-script to use date-variables or is there a way to pass Windows Batch Variables to PSFTP?
The file looks like this: FILENAME_2015-06-25.TXT (based on the current date)
Something like this:
cd /subdir
get FILENAME_%year%-%month%-%day%.TXT
quit
In a Windows Batch File i can easily get the current date by something like this:
SET YEAR=%DATE:~-4%
SET MONTH=%DATE:~-7,2%
SET DAY=%DATE:~-10,2%
ECHO FILENAME_%YEAR%-%MONTH%-%DAY%.TXT

You have to generate the psftp script file dynamically like:
SET YEAR=%DATE:~-4%
SET MONTH=%DATE:~-7,2%
SET DAY=%DATE:~-10,2%
ECHO cd /subdir > script.txt
ECHO get FILENAME_%YEAR%-%MONTH%-%DAY%.TXT >> script.txt
psftp.exe -b script.txt ...
Though note that the %DATE% is not really a reliable approach to retrieving timestamp with a fixed format as its value changes with locale.
You can use this instead:
for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if '.%%i.'=='.LocalDateTime.' set LDT=%%j
ECHO get FILENAME_%LDT:~0,4%-%LDT:~4,2%-%LDT:~6,2%.TXT >> script.txt
For details see:
How to get current datetime on Windows command line, in a suitable format for using in a filename?
Alternatively use WinSCP scripting (that supports timestamps natively) from a batch file (.bat) like:
winscp.com /log=winscp.log /command ^
"open ftp://username:password#host" ^
"cd /subdir" ^
"get FILENAME_%%TIMESTAMP#yyyy-mm-dd%%.TXT" ^
"exit"
For details see:
%TIMESTAMP% syntax
Converting PSFTP script to WinSCP script
(I'm the author of WinSCP)

Related

Backup script - find file by pattern, read it's full name and pass to script

I'm trying to use 7-Zip for backup purposes.
I have already wrote script for full backup:
#echo off
set source="c:\Source"
set destination="C:\Dest"
set dd=%DATE:~0,2%
set mm=%DATE:~3,2%
set yyyy=%DATE:~6,4%
set curdate=%dd%-%mm%-%yyyy%
"C:\Program Files\7-Zip\7z.exe" a -tzip -ssw -mx6 -r0 %destination%\Full_%curdate%.zip %source%
The new script intended for incremental backup is started after the full backup is made. But I don't really get how to make my second script to read files from directory and look for the file staring like full_xx_xx_xxxx.zip and assign its filename to a variable and then pass it to the script for incremental backup.
I tried script below, but it's not working:
#echo off
set source="c:\Source"
set destination="c:\Dest"
set exten="Full_*.zip"
set passwd="NAS"
set dd=%DATE:~0,2%
set mm=%DATE:~3,2%
set yyyy=%DATE:~6,4%
set curdate=%dd%-%mm%-%yyyy%
for %%a in %exten do echo %%a
"C:\Program Files\7-Zip\7z.exe" u -tzip -ssw -r0 %destination%\%%a.zip -u- -up0q3x2z0!"%destination%\diff_%date%.zip" %source%
There are multiple mistakes in both scripts.
I recommend reading first How to set environment variables with spaces? and Why is no string output with 'echo %var%' after using 'set var = text' on command line?. The syntax set variable="value in quotes" is often not good because it assigns the string "value in quotes" with the double quotes and all trailing spaces/tabs which might exist also in batch file to the environment variable with name variable. This syntax is problematic on concatenating the string value of the environment variable with other strings as done in posted code with %destination% because of the " being now somewhere in middle of the final argument string instead of enclosing the entire argument string. Better is the syntax set "variable=value without or with spaces" with " left to variable name because of the double quotes are interpreted now as argument string separators and perhaps existing spaces/tabs on line after second " are ignored by Windows command processor.
The usage of dynamic environment variable DATE makes it possible to quickly get current locale date in a format usable for file/folder names. But it must be taken into account that the date format of value of DATE depends on region/country/locale set for the user account which is used on running the batch file. I suppose that echo %DATE% results in an output of a date in format DD.MM.YYYY and so the command lines using DATE are correct for you with your user account according to the configured country.
The FOR command line is completely wrong and results in an exit of batch file execution with an error message output by cmd.exe interpreting the batch file line by line. This error output can be seen on running the batch file from within a command prompt window instead of double clicking on the batch file. See debugging a batch file for details on how to debug a batch file to find syntax errors like this reported by Windows command processor during execution of a batch file.
So I suggest for the first batch file:
#echo off
set "Source=C:\Source"
set "Destination=C:\Dest"
set "CurrentDate=%DATE:~6,4%-%DATE:~3,2%-%DATE:~0,2%"
"%ProgramFiles%\7-Zip\7z.exe" a -tzip -ssw -mx6 -r0 "%Destination%\Full_%CurrentDate%.zip" "%Source%"
The current locale date is assigned to the environment variable CurrentDate in format YYYY-MM-DD instead of DD-MM-YYYY. The date format YYYY-MM-DD is the international date format according to ISO 8601. It has one big advantage in comparison to all locale date formats in file names: The file names with date in format YYYY-MM-DD sorted alphabetically as usual are at the same time sorted chronological. That makes it much easier for people and scripts finding a specific file in a list of file names with date in file name.
I am not really sure what you want to do with the second batch file. So I can only suppose what you want to do and suggest for the second batch file:
#echo off
set "Source=C:\Source"
set "Destination=C:\Dest"
set "CurrentDate=%DATE:~6,4%-%DATE:~3,2%-%DATE:~0,2%"
set "NamePattern=Full_*.zip"
for /F "skip=1 eol=| delims=" %%I in ('dir "%Destination%\%NamePattern%" /A-D /B /O-N 2^>nul') do (
"%ProgramFiles%\7-Zip\7z.exe" u -tzip -ssw -r0 "%Destination%\%%I" -u- -up0q3x2z0!"%Destination%\Diff_%CurrentDate%.zip" "%Source%"
goto Done
)
:Done
The FOR loop runs command DIR with using a separate command process started in background to get the list of Full_*.zip file names in destination directory sorted reverse by name which means the full backup ZIP file created today before with first batch file is at top on using date format YYYY-MM-DD and the previously created ZIP file from yesterday (or whenever the last but one full ZIP file was created) is output as second line.
FOR skips the first line with ZIP file name with current date and runs 7-Zip with previously created ZIP file (yesterday) to create the difference ZIP file. Then the FOR loop is exited without processing all other full ZIP files with a jump to the label below the FOR loop.
Both batch files together:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "Source=C:\Source"
set "Destination=C:\Dest"
set "CurrentDate=%DATE:~6,4%-%DATE:~3,2%-%DATE:~0,2%"
set "NamePattern=Full_*.zip"
rem Create full ZIP backup.
"%ProgramFiles%\7-Zip\7z.exe" a -tzip -ssw -mx6 -r0 "%Destination%\Full_%CurrentDate%.zip" "%Source%"
rem Create difference ZIP backup with files added/changed in source directory
rem in comparison to the files compressed into last but on full ZIP backup.
for /F "skip=1 eol=| delims=" %%I in ('dir "%Destination%\%NamePattern%" /A-D /B /O-N 2^>nul') do (
"%ProgramFiles%\7-Zip\7z.exe" u -tzip -ssw -r0 "%Destination%\%%I" -u- -up0q3x2z0!"%Destination%\Diff_%CurrentDate%.zip" "%Source%"
goto Done
)
:Done
endlocal
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
dir /?
echo /?
endlocal /?
for /?
rem /?
set /?
setlocal /?

How to do variable interpolation in a windows batch file using the Qt "system" command?

When developing an application with Qt the project file has the file extension "pro". In this pro file one can perform platform-dependent commands by using the "system" directive. Example:
RESPONSE = $$system( cmd /c dir)
I want to use variable interpolation. Windows uses for this the % character. When I create a batch file, called utc.bat that writes its output to the file utc.txt, having as content:
#echo off
REM for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do set %%x
echo %Year%-
and run it from a terminal the content of utc.txt is:
2017-
If I run the same command from within the pro file:
system(utc.bat > utc.txt)
the content of utc.txt is
-
Apparently the variable interpolation %Year% does not work. I hope somebody knows the answer of how to get it working.

Saving and restoring Date in Command Prompt

I run a command script that saves date to text file.
echo %date% > date.txt
Only problem this command saves the day in text file like so
Sun 13/08/2017
When it starts the service, I have a command to change date back
date < date.txt
I get an error
The system cannot accept the date entered.
It needs to show
13/08/2017
For this command to work
date < date.txt
I have someone gave me this command
for /F "tokens=2" %i in ('date /t') do echo %i > date.txt
it removes the day, it runs by itself.
but to run with a script it closes after it executes,
it doesnt seem to run with script.
I have other computers , I use this script and after windows update
It fixes issue; the windows update on other computer removes the day.
This computer had all windows update , but the day still displays
When you type <date> in cmd
The simple solution is using string substitution and write into the text file only the last 10 characters of the region dependent date string of built-in environment variable DATE by using this code:
>date.txt echo %DATE:~-10%
Avoid a space character before redirection operator > on writing a text with echo into a file as this space character is written as trailing space also into the file.
Sometimes it is unsafe to use echo %VariableText%>OutputFile.txt because of the variable text could end with a number in range 1 to 9 which would result in execution of the command line with 1> to 9> which means redirect handle 1 to 9 to the file instead of writing the number 1 to 9 to the file. In such cases it is advisable to specify the redirection to file at beginning of the command line before command echo as done on the command line above.
It would be also possible to use this code to save the date in format DD/MM/YYYY into the ANSI encoded text file date.txt.
#echo off
for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /Value') do set "LocalDateTime=%%I"
>date.txt echo %LocalDateTime:~6,2%/%LocalDateTime:~4,2%/%LocalDateTime:~0,4%
This code has the advantage of being independent on which region is set for the current user because the date and time string output by WMIC has always the same format. Run in a command prompt window wmic OS GET LocalDateTime /Value to see the UTF-16 encoded output of WMIC processed by command FOR line be line. The disadvantage is that this code is slower.
On setting the date back with using command DATE the region dependent date format must be known.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
for /?
set /?
wmic /?
wmic os /?
wmic os get /?
wmic os get localdatetime /?
Read also the Microsoft article about Using Command Redirection Operators.

Can I create a folder with current datetime when I use Windows Command-line FTP

Is there any possibility to create a new directory with current datetime when I use the Windows Command-line FTP?
for more clarification if I have scheduler to run this:
C:\windows\system32\ftp -s:ftpMyFiles.txt
And inside ftpMyFiles.txt I have:
open 127.0.0.1
user
pass
mkdir %DATE%
bye
here is the question Can I create A new directory with a datetime here (mkdir %DATE%)?
You have to generate the ftpMyFiles.txt dynamically like:
(
echo open 127.0.0.1
echo user
echo pass
echo mkdir %DATE%
echo bye
) > ftpMyFiles.txt
C:\windows\system32\ftp -s:ftpMyFiles.txt
Note that the value of %DATE% is locale-specific. So make sure you test your batch file on the same locale you are going to actually run it. Otherwise you may get unexpected results. For example on my (Czech) locale the DATE=po 13. 04. 2015
You can achieve the same easier and more reliably using WinSCP scripting. It supports:
Specifying the commands directly on its command-line
%TIMESTAMP% syntax.
winscp.com /ini=nul /command ^
"open ftp://user:pass#127.0.0.1/" ^
"mkdir %%TIMESTAMP#yyyymmdd%%" ^
"exit"
(I'm the author of WinSCP)
I prefer using ISO 8601 date formats (sometimes minus hyphens), as that makes ordering files by date easier (simply order alphabetically by folder name). Generally, I find ISO 8601 dates with hyphens easier to read than those without, but your requirements may vary.
Also, ISO 8601 avoids the silliness from across the pond where days and months are switched around - this confuses those of us who use international standards no end.
The ISO 8601 format used most often is YYYY-MM-DD or YYYYMMDD (e.g., 2016-02-24 or 20150224 for today's date).
Using wmic os get LocalDateTime, you can get non-locale-specific datetime from the operating system, and then convert it to ISO 8601 format, as demonstrated here:
#echo off
for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if '.%%i.'=='.LocalDateTime.' set ldt=%%j
set ldtime=%ldt:~0,4%-%ldt:~4,2%-%ldt:~6,2% %ldt:~8,2%:%ldt:~10,2%:%ldt:~12,6%
set ldate=%ldt:~0,4%-%ldt:~4,2%-%ldt:~6,2%
set ldatestraight=%ldt:~0,8%
echo Local datetime is [%ldtime%]
echo Local date is [%ldate%]
echo Local date no hyphens is [%ldatestraight%]
echo .
echo Raw datetime is [%ldt%]
pause
So, taking Martin Prikryl's sample code a step further, you could do something like this (for ISO 8601 dates with hyphens):
(
echo open 127.0.0.1
echo user
echo pass
for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if '.%%i.'=='.LocalDateTime.' set ldt=%%j
set ldate=%ldt:~0,4%-%ldt:~4,2%-%ldt:~6,2%
echo mkdir %ldate%
echo bye
) > ftpMyFiles.txt
C:\windows\system32\ftp -s:ftpMyFiles.txt
Kudos to Anerty and Jay for their answer to a similar question that helped me a little while back, here.

Assigning a command BAT file environment variable via a perl script

I have a batch file I'm running under cmd.exe window. I want to look at a web config file and get a value. I have no idea of the right way to do this, but I figure I can cheat by writing a perl script to do this - and returning the value to the batch file.
I'm looking for something that looks like:
set var1=(evaluate perl script)
How does one do such a thing?
#echo off
set var1=
echo var1=%var1%
for /f "usebackq delims=" %%q in (`perl -E"say 'foo'"`) do set var1=%%q
echo var1=%var1%
Use %q instead of %%q outside of a batch file.

Resources