Goto was unexpected at this time - batch - goto

I am trying to make a batch text-based game. But i encountered a problem just starting to write it what I have never encountered before.
:menu
:: the game menu - opens when the game starts
cls
echo This game is still being made -- expermintal
echo Start Screen:
echo [1] View Changes
echo [2] Start Game
echo enter your choice:
set /p startchoice =
if %startchoice%==1 goto changes
if %startchoice%==2 goto startgame
When i type in either 1 or 2, it shows the error "goto was unexpected at this time" How do I fix it?

Your startchoice isn't being set correctly. Use the alternate syntax for set /p where you supply the prompt there (and remove the space between startchoice and the assignment (=) operator - I think it's actually the cause of the problem, but you can reduce your batch file by a line if you use the set /p <variable>=<Prompt> syntax).
I added two targets for the goto, and echo statements so you could see they were reached:
:menu
:: the game menu - opens when the game starts
cls
echo This game is still being made -- expermintal
echo Start Screen:
echo [1] View Changes
echo [2] Start Game
set /p startchoice=Enter your choice:
if %startchoice%==1 goto changes
if %startchoice%==2 goto startgame
:changes
echo Changes
goto end
:startgame
echo StartGame
:end

You need quotes around the if comparison and it didn't like you using set / p without a prompt. The following works:
:menu
:: the game menu - opens when the game starts
cls
echo This game is still being made -- expermintal
echo Start Screen:
echo [1] View Changes
echo [2] Start Game
set /p startchoice = "enter your choice: "
if "%startchoice%"=="1" goto changes
if "%startchoice%"=="2" goto startgame

Instead of using environment variables, try this:
CHOICE
IF %ERRORLEVEL% EQU 1 goto changes
IF %ERRORLEVEL% EQU 2 goto startgame
Choice is a program that allows you to enter a number or y/n and returns an error code.
%ERRORLEVEL% is a variable that holds the program's last error code.
You can do other comparisons, too.
EQU - equal
NEQ - not equal
LSS - less than
LEQ - less than or equal
GTR - greater than
GEQ - greater than or equal

Another Reason it could be malfuntioning is that you have not included the SET /P M= Variable Correctly... There should not be a space between the m and the equals sign.

Related

Mediainfo CLI: Custom template Output

I want to use Mediainfo with a bat file.
It should write the Media Info into a textfile, then rename the file to *.nfo
That works quite good, but I always get the complete "standart" Media Info, not a custom one that I need.
Here is my code so far:
#echo off
set "mediainfo_path=C:\Program Files\mi cli\MediaInfo.exe"
set "output_extension=C:\Program Files\mi cli\custom.txt"
cd %1
echo.
echo Looking for Media Assets on target directory . . .
REM ******** Add media file extensions here ********
dir *.mkv /b /s > filelist.tmp
REM *
REM ******* Loop through temporary file list *******
(for /f "delims=" %%i in (filelist.tmp) do (
echo Extracting %%i metadata information . . .
setlocal enabledelayedexpansion
"!mediainfo_path!" --logfile="!output_extension" "%%i" > %%i.nfo
echo()
endlocal
)
del filelist.tmp
echo.
o matter what "output_extenstion" I choose, the result is always the same, full log.
First, you need to do step by step, so start by trying the MediaInfo command without the batch stuff. You'll see that it does not work.
"--logfile" is for storing the output (similar to your ">%%i.nfo") so you did not say to MediaInfo that you want a custom report.
mediainfo --Output=file://custom.txt a.mkv >a.nfo
or
mediainfo --Output=file://custom.txt a.mkv --LogFile=a.nfo
Would work as you expect (the first version both show and store info, the second version only store info).
So replace the "MediaInfo line" by:
"!mediainfo_path!" "--Output=file://!output_extension!" "%%i" > %%i.nfo
and it works as you expect.
Note: I am aware that there is a lack of documentation, due to lack of time :(.
Jérôme, developer of MediaInfo

zsh function only runs once

I'm fairly new to zsh (oh-my-zsh) and i'm trying to write a custom theme.
I ran into a problem and reduced it to the following testcase
PROMPT='$RANDOM > '
works as expected, it produces a random number on each command.
But when using a function
PROMPT='$(my_random) > '
function my_random(){
echo $RANDOM
}
it always returns the same number, even after source ~/.zshrc still the same number. only when i close the terminal window and open it again, i get a new number which stays the same for the complete session.
only when i do:
PROMPT='$RANDOM $(my_random) > '
function my_random(){
echo $RANDOM
}
i get two random numbers as expected... any explanation for this behaviour?
btw, i'm using kde's konsole on a fresh arch install.
Edit
fwiw i found using /dev/urandom directly works well. I would still like to know whats going on.
function my_random() {
echo $(cat /dev/urandom | tr -dc '0-9' | head -c5)
}
$()-expansion happens in a subshell, and changes to $RANDOM in a subshell don’t affect the parent. From zshparam(1):
The values of RANDOM form an intentionally-repeatable pseudo-random sequence; subshells that reference RANDOM will result in identical pseudo-random values unless the value of RANDOM is referenced or seeded in the parent shell in between subshell invocations.
You don’t need to turn to setting the prompt to reproduce it:
% echo $(echo $RANDOM)
17454
% echo $(echo $RANDOM)
17454
bash doesn’t share zsh’s behaviour here.
The annoying bit is that prompt expansion also happens in a subshell, so you can’t just fix this by referencing $RANDOM in, say, precmd. The best way I can find is to do it in an empty expansion:
PROMPT='${RANDOM##*}$(my_random) > '
As said in a comment by chepner, you can fix this by putting : $RANDOM; in your precmd. This causes the value of $RANDOM to be taken and a new one to be generated.
e.g.
precmd() {
: $RANDOM;
...
}

GNUmakefile handles echo in ifeq

Say I have the following in the GNUmakefile
ifeq ($(MODELS), abc)
#echo PASS <== line 45
endif
How come I keep on getting the following error?
GNUmakefile:45: * missing separator. Stop.
Pls note, the echo works fine if it is NOT in the ifeq clause
ah I know why. You need to make sure there is NO space/TAB before "ifeq", "endif" and NO space before the $echo.For the echo line, it can only be TABs. Why do GNUmakefile is so picky on spaces/tabs, these invisible rules are really not institutive.

How can i use the variable %TIME:~0,2% in a batch file so that times with a leading space do not cause errors?

I am trying to run a batch file, which runs an XSLT transformation against an XML file and writes out a second XML file.
This XML filename is determined by the following line in the batch file:
ICS_%DATE:~-4%_%DATE:~4,2%_%DATE:~7,2%_%TIME:~0,2%_%TIME:~3,2%_DATA.xml
When the time has a leading space (that is, any time before 10:00 am), the variable %TIME:~3,2% returns a result with a leading space, which causes the filename to be truncated. The result file is empty.
If I run the batch after 10:00am, everything works fine. How can I generate a value similar to %TIME:~3,2%that works before 10:00am?
This will solve the space in the name issue, and replace it with a zero so it sorts correctly in a list.
set name=ICS_%DATE:~-4%_%DATE:~4,2%_%DATE:~7,2%_%TIME:~0,2%_%TIME:~3,2%_DATA.xml
set name=%name: =0%
How about this one ?
#ECHO OFF
FOR /F "tokens=1-4 delims=., " %%i IN ('DATE /t') DO SET cpdate=%%k_%%j_%%i
FOR /F "tokens=1-4 delims=:" %%b IN ('TIME /T') DO SET cptime=%%b_%%c
set filename=blabla_%cpdate%_%cptime%_%TIME:~-5,2%.xml
echo %filename%
The locale here is german, so you might have to adjust the order in "set cpdate..." for your needs.
(This is an old question but this answer could be of help for somebody else.)
Using %time: =% gets rid of the spaces in the time variable.
Example:
C:\>echo %time%
04:00:00,00
C:\>echo %time: =%
04:00:00,00
You could save the time variable to another using this method and then work from that one:
set "tim2=%time: =%"
Setting a variable for the hour value as follows solves the problem for me:
FOR /F "tokens=* delims= " %%a IN ("%TIME:~0,2%") DO SET hour=%%a
set time=%time:~0,5%
if "%time:~0,1%" == " " set time=0%time:~1,5%
echo %time:~0,2%%time:~3,2%
my time is: 9:48:27,00
I add a zero if it is missing and
echo %time:~0,2%%time:~3,2% is now 0948
I use a simple trick to do this:
set h=1%TIME:~0,2%
set /a h=%h%-100
REM This .bat script gives you a parameter timetext with a zero instead of a space
#echo off
set timetext=%time:~0,2%%time:~3,2%
echo TIME BEFORE WITH SPACE %timetext%
set digit1=%time:~0,1%
if "%digit1%"==" " set digit1=0
set timetext=%digit1%%time:~1,1%%time:~3,2%
echo TIME AFTER WITH ZERO.. %timetext%
pause
This maybe more helpful in Dos Batch ~~ try this
if "%time:~0,1%" == " " (set dtstamp=0%time:~1,1%) ELSE set dtstamp=%time:~0,2%
echo dtstamp=%date:~6%%date:~3,2%%date:~0,2%_%dtstamp%%time:~3,2%

Why can't I read user input properly inside a UNIX while loop?

I'm using the bourne shell in UNIX, and am running into the following problem:
#!/bin/sh
while read line
do
echo $line
if [ $x = "true" ]
then
echo "something"
read choice
echo $choice
else
echo "something"
fi
done <file.txt
The problem I have here is that UNIX will not wait for user input in the read command - it just plows on through instead of waiting for what the user types in. How can I make unix wait for user input?
It is because you are asking the program to read from the file file.txt:
done <file.txt
Also looks like you have a typo here:
if [ $x = "true" ]
^^
which should be "$line". Also note the ", without them your program will break if the word read from the file has a space in it.
The redirection of standard input by the <file.txt at the end of while ... done <file.txt affects the whole while loop, including the read choice as well as the read line. It's not just failing to stop - it's consuming a line of your input file too.
Here's one way to solve the problem...
You can save the original standard input by using the somewhat obscure (even by shell standards):
exec 3<&0
which opens file descriptor 3 to refer to the original file descriptor 0, which is the original standard input. (File descriptors 0, 1 and 2 are standard input, output and error respectively.) And then you can redirect just the input of read choice to come from file descriptor 3 by doing read choice <&3.
Complete working script (I wasn't sure where x was supposed to come from, so I just bodged it to make it work):
#!/bin/sh
x=true # to make the example work
exec 3<&0
while read line
do
echo $line
if [ $x = "true" ]
then
echo "something"
read choice <&3
else
echo "something"
fi
done <file.txt
I don't do much shell scripting, but i think 'read choice' should be 'read $choice'

Resources