i came across a problem with subversion at my work. I want to create a post-commit-hook (post-commit.bat file) command that creates information about the last transaction.
The code looks like this:
#echo off
set file="D:\mypath\logfile%2.txt"
svn log D:\'my path to repro'\ -r %2 -v > %file%
The %2 corresponds to the last revision number. It creates the file with the correct number and tries to write in it. But then the commit hangs and the file remains open. The curious thing is, if I manually trigger the command with a valid revision number, then the whole thing works. Only with the hook it hangs and it also does not commit the files.
Can anyone help me or have any ideas for my problem?
I found a solution, maybe this might be helpful for some person.
I used the wrong command "log". Instead you have to use "svnlook changed..." on the server to get the latest information about the last commit.
Related
We have a 2 step process that collects all filenames from a folder into a Word document for use elsewhere.
The original process was to run an old DOS batchfile that collected the filenames into a DOS .txt. Then we launched a Word .docx with a macro that imported the .txt and massaged the formatting. After visual inspection we hit ‘Save’ and that was it.
I had the bright idea that a step could be taken out by launching Word directly from the batch, so I inserted the line: start winword filename. This works great except that the default location that Word wants to save in is now my Templates folder. Running it the old way still works perfectly.
The question is: why is the default location changed by launching Word programmatically and how can it be forced back to the correct location?
Thanks
you can use:
start /D C:\path\to\folder "" winword.exe
this program starts winword.exe and save all files to C:\path\to\folder
ill assume that winword.exe is in the current directory.
for help with the start command : http://ss64.com/nt/start.htm
I investigated the start command, but never did figure out why it operated differently. The eventual solution was to include the Save action in the macro. I still don't know why we didn't have to do that before, but it works now so we're declaring success and moving on.
I'm trying to remotely deploy some software and I have a few batch scripts to help this process along. The basics of my process is to have a text list that scriptA goes through, scriptA copies the necessary files to the target PCs (retrieved from the list) and launches ScriptB. The theory would then be that it would move on to the next PC in the list as soon as ScriptB launches and doesn't wait for ScriptB to finish before moving on. The basics of what I have are below:
ScriptA:
Set /P List= Please enter the list name
Set /P Name= Please enter your username
FOR /F %%A IN (%LIST%) DO (
MKDIR \\%%A\C$\Temp\Install
XCOPY "\\share\necessary files" "\\%%A\C$\Temp\Install"
PSEXEC \\%%A -u DOMAIN\%NAME% -e "\\%%A\C$\Temp\Install\scriptB.bat"
)
ScriptB just runs the installer and cleans up after itself.
Like I said, the goal would be that once scriptA has finished copying over files and gets things kicked off, it would move on to the next PC on the list. I've confirmed that everything works as is right now (so please ignore any random things that wouldn't work in the pseudocode above) it just takes forever because it waits for the installation to finish before moving on.
EDIT:
I realized I had the wrong files shown as being copied. What was originally listed as 'install.bat' should have been scriptB. I apologize, it has been very hard to try to get my question across as I'm having a very hard time describing the problem.
Per Request, here is how I was using start:
ScriptA:
START PSECEC \\%%A -u DOMAIN\%NAME% -e "\\%%A\C$\Temp\Install\ScriptB.bat"
It worked to start ScriptB in a new window, but what I'm really trying to have as the final product is:
scriptA gets prompts for the list of PC names
scriptA pulls the first name from the list and copies over the install files from a network share, including scriptB and puts them in \temp\install
scriptA kicks off scriptB on the PC it just copied files to.
While scriptB is running, scriptA moves on and copies the files to the next PC on the list and kicks of the next copy of scriptB
repeat until the whole list of PCs is completed.
I hope this helps to clarify things, and again, I apologize for the confusion. I have all of the steps listed above working as I would hope, the only thing that isn't working is that I can't get scriptA to kick off scriptB without pausing scriptA to wait for scriptB to finish and what I would like to have happen is that it moves on without waiting (so that I could start this script at the end of the day and it would continue installing at night until it finished the list of PCs).
Thanks again for any help!
You can use the START command to launch a command without waiting for it to end before moving on. Note that this will execute the specified command in a newly created command prompt, not in the same command prompt process.
Be aware though that if the path to your executable/batch file contains spaces, you must specify an empty string argument as the first argument. Example:
START "" "C:\Path with spaces\My other script.bat"
This is due to the fact that if the first arguments is surrounded by quotes, it is considered as being the title of the new command prompt that is launched to execute your new process. Specifying an empty argument (or the title you'd like to use for that matter) will work around this situation.
The further we are away from the actual problem, the less able we are to help. The more general the question, the more vague the response.
We're pointlessly mapping from "ScriptB" to "Install.bat" and you've claimed to have added the start command but not shown us where you've used it.
Using your original script, changing
PSEXEC \\%%A -u DOMAIN\%NAME% -e "\\%%A\C$\Temp\Install.bat"
to
start "installing on %%A" PSEXEC \\%%A -u DOMAIN\%NAME% -e "\\%%A\C$\Temp\Install.bat"
should solve the problem - but no guarantees.
I have to maintain a batch script of about 3500 lines littered with GOTO. Seems that the original "developer" hasn't heard of this famous paper and modular programming.
What the script does?
The script deals with the (silent) installation/uninstallation/reinstallation of several programs using different options. It could be split in several files that deal with each program in part. The problem is that if you're trying to take a part in another file that part will still GOTO another section that needs to be in the original script.
Refactoring?
Normally you wouldn't do a refactoring without having automated tests (so you can be sure you didn't break anything), but I don't know how to do it. There's no testing framework for that.
Partial Solution
I have come up with a partial "solution" that is some kind of adaptation of characterization tests (from Working Effectively with Legacy Code by Michael Feathers) and approval tests:
- create another script: test.py that replaces all commands (like copy or msiexec) with echo,
- redirect the output to a text file (good.txt),
- change the original batch script,
- run the test.py script again and save the output to another text file (current.txt),
- diff good.txt and current.txt -> if there are no differences then I didn't break anything, but if they are different I need to check if I broke something.
Problem with partial solution
How can I capture and replace all the commands? I could make a list of commands to replace, but there are also a lot of string concatenations to get the name and path of the program to be installed.
CMD level capture/hook?
Is there any way I can hook into the command line interpreter (CMD.exe) so I can replace on the fly all the calls to installers with echo?
Other suggestions?
Do I approach the problem in the wrong way? Can I do it better somehow? Do you have some advice I could use?
You could replace all COPY, DEL or CALL with %COPY%, %DEL% ,...
So you can use the same file for production and also for the tests.
#echo off
if not defined UNITTEST (
set "COPY=COPY"
set "DEL=DEL"
set "CALL=CALL"
)
%COPY% src dest
%DEL% somefile.txt
%CALL% installer.exe
And from your unittest.bat, you could start it via
#echo off
set "COPY=>>trace.log ECHO COPY"
set "DEL=>>trace.log ECHO DEL"
set "CALL=>>trace.log CALL ECHO "
del trace.log
set "unittest=Active"
call production.bat
fc good.txt trace.log
I'm not an expert in Batch, but I have done my fair share of it. With that said, I can offer a few tips.
Forget trying to do it all at once. Batch is very hard to debug. Echoing out to a log file helps a lot, but it will not capture everything you need if something goes wrong.
Work on breaking out the exe and msiexec calls into self-contained scripts. It is much easier to test the small script for the functionality you desire. Once you have that working, it is simple to call that script from the "Master" script.
Establish a good protocol for passing args to, and return codes from the smaller scripts. If there are common settings needed to be used for all the scripts consider using a central settings file.
GOTOs are not the devil, unless they pass control all over the place. Normally there are two good reasons that I know of to use GOTO’s.
Skip past a block of code that does not need to run.
To SET values into variables. Note there is a bug that can prevent variables from having their value set from within an 'IF' statement block. That little bug caused a big headache for me at one time.
Calls to a label might be better option at times.
Depending on how far back the legacy support is required, consider using Powershell when possible. The power and debugging capabilities of Powershell far out way the benefits of simple scripting of Batch. Which at 3500 lines simplicity has already been lost. You are already looking at Python, so maybe that could be used instead.
If you need a break point, use Pause. ECHO all the settings you need to examine right before the pause. This is as close to a break point I have found for batch.
Echo the command you intend to run to a log file and actually run it.
Write small verification scripts to be used independently or with the “Master” script to confirm you are getting the results you are expecting.
Use the right tool for the job. I like to use EditPadPro, RegexBuddy, and BeyondCompare for batch editing and comparing differences. There free tools that can be used too NotePad++ and Windiff. Making many edits in a file of that size is best handled by a good editor. IE inserting an echo at the beginning of a line that calls a cmd.exe.
Remember it is scripting not programming. While there is a lot of overlap of the two, the same exact approach to a problem may not be viable between the two.
Always make a backup copy of the scripts as a whole before mucking around. A fallback position is greatly appreciated when there is one small bug that you can’t find.
If it ain't broke... well you wouldn't be working on it if everything was working just fine.
Always test changes. And when you are done test it again. After that have someone else test it.
Just my .02. I’m sure someone else can chime in with more advanced advice. My knowledge on Batch has been acquired from the school of hard knocks, supplemented by ss64.com
I have a simple script to move files between directories. Basically, it is:
mv /dir/* /dir/proc/
saved into a shell script "mvproc.sh".
For some reason, when I run the script (sh mvproc.sh) the file indeed gets moved, but it does not retain the filename and instead gets just an empty filename. When I run the same command at the bash prompt, it works fine however.
This script used to work fine on Debian but we had a hard drive failure and I am now migrating everything over to a Ubuntu machine.
Any idea why this is happening? It seems so simple yet I cannot figure it out.
Many thanks.
edit...
I think I found the solution. For some reason it was putting in carriage returns and maybe line breaks or something that I could not see while editing the sh script in either Notepad++ or even gedit. To solve this, when I open the scripts in gedit, I do a Save As, and select Unix/Linux in the drop down menu towards the bottom. This hopefully gets rid of the weird carriage returns even though I could not see them.
Hopefully this helps some poor soul like me in the future pulling their hair out over this!
Thanks!
Try: mv /dir/file /dir/proc/file
You are indeed moving the file, but aren't specifying a destination name. Other usages of mv:
Move and rename: mv /dir/filename /dir/proc/newfilename
Rename: mv /dir/filename /dir/newfilename
I work extensively using the shell. When I continue working on some project one week later, I go to some "folder" and realize that I do not remember what I was doing. Sometimes and before stopping work what I do is:
history > DIRX_HISTORY_20100922
so later I have a look at the commands I used, I can remember much better what I was doing.
I wonder if somehow, some script or something could do this automatically each time I type a command in a directory, so this DIRX_HISTORY_20100922 is created and a new one is modified depending on the date and on the directory name.
Thanks
Have a look at my history logging functions. They save the current directory along with the command that was executed. You can grep for the directory and it will show you the commands that you were using there.
Bash's PROMPT_COMMAND variable can be used to save the last line of your history to a file for every command you enter.
ie.
PROMPT_COMMAND="history 1 >> DIRX_HISTORY"