Using environment variables in a makefile - makefile

I'm using XP command line.
I have a makefile and a .bat that runs the makefile. I also have an environment variable that I would like to use within the makefile. I have found some documentation but I am having a hard time seeing how to use it in my case. I think it is easy but I'm just missing something.
In my case I want to make the below more general. I want to specify the location of the borlandc (i.e. BorlandDir) folder externally to the makefile.
I type "mk" to run the make.
Here is my case:
MK.BAT
------
echo off
ver | findstr /i "5\.1\." > nul
IF %ERRORLEVEL% EQU 0 goto ver_XP
echo The OS must be XP to run Borland C
PAUSE
goto:eof
:ver_XP
if '%BorlandDir%' == '' call setpath
%BorlandDir%\bin\make -s >this2
rem echo if you get "Bad command or file name" or it does not create emul.exe, run 'setpath'
echo if you get "Unable to execute command 'tlink.exe'", copy borlandc\bin\tlink.exe here
echo To make this debuggable, add -v
echo e.g., bcc -M -v -l3 -I%BorlandDir%\include -L%BorlandDir%\lib 1830.obj emul.obj iostuff.obj panel.obj
rem make -s
find /i /v "borland" <this2 >this1
find /i /v "available memory" <this1 >this
more <this
del ..\1830.exe 2> nul
move 1830.exe ..
SETPATH.BAT
-----------
set BorlandDir=..\borlandc
path=%path%;%BorlandDir%\bin
MAKEFILE
--------
COMPILE=bcc -a -3 -Od -v -c -ms -Oi -Iborlandc\include
ASSEMBLE=borlandc\bin\tasm -zi -ml -t -la
1830.exe: 1830.obj emul.obj iostuff.obj panel.obj
echo link 1830.exe
bcc -M -v -l3 -Lborlandc\lib 1830.obj emul.obj iostuff.obj panel.obj
1830.obj: 1830.c \
panel.h \
iostuff.h
$(COMPILE) 1830.c
iostuff.obj: iostuff.c \
panel.h \
api.h \
iostuff.h
$(COMPILE) iostuff.c
panel.obj: panel.c \
panel.h \
iostuff.h
$(COMPILE) panel.c
emul.obj: emul.asm
echo emul.asm:
$(ASSEMBLE) emul.asm

Related

Forfiles Escaping with regular expression

I'm using linux program in windows Environment (curl and grep)
This command works fine in dos shell and get result
curl --request POST "https://somesite/access_token" --user user:pass | grep -o -P -e "(?<=\"access_token\":\").+?(?=\")"
but If I try this script in batch to save result in a variable
for /f %%a in ('curl --request POST "https://somesite/access_token" --user user:pass ^| grep -o -P -e "(?<=\"access_token\":\").+?(?=\")"') do set "TOKEN=%%a"
I got this error:
.+?(? was unexpected at this time.
any idea? Thank you in advance

Pass a path to the "." source in a makefile

In a directory I have a config file with my db variables.
This file (db/database.ini) looks like this:
[PostgreSQL]
host=localhost
database=...
user=postgres
password=...
I have another file (db/create_stmts.sql) where I have all my raw create table statements, and i am trying to experiment the use of a Makefile to have a command like this:
make create-db from_file=db/create_stmts.sql
In order not to repeat myself, I thought of tailing the variables of db/database.ini to a file which I would then source, creating shell variables to pass to psql in the make file.
Here's my plan:
make-db:
# from_file: path to .sql file with all create statements to create the database where to insert
# how to run: make create-db from_file={insert path to sql file}
file_path=$(PWD)/file.sh
tail -n4 db/database.ini > file.sh && . $(file_path)
# -U: --user
# -d: --database
# -q: --quiet
# -f: --file
psql -U $(user) -d $(database) -q -f $(from_file) && rm file.sh
Which I run by: make create-db from_file=db/create_stmts.sql
Which gives me this message - from which i kindof understand that the sourcing just did not work.
#from_file: path to .sql file with all create statements to create the database where to insert
# how to run: make create-db from_file={insert path to sql file}
file_path=/home/gabriele/Desktop/TIUK/companies-house/file.sh
tail -n4 db/database.ini > file.sh && .
# -U: --user
# -d: --database
# -q: --quiet
# -f: --file
psql -U -d -q -f db/schema_tables.sql && rm file.sh
psql: FATAL: Peer authentication failed for user "-d"
Makefile:3: recipe for target 'create-db' failed
make: *** [create-db] Error 2
Any help?
Another solution, perhaps simpler to understand:
make-db:
file_path=$$PWD/file.sh; \
tail -n4 db/database.ini > file.sh && . $$file_path; \
psql -U $$user -d $$database -q -f $$from_file && rm file.sh
Note using ; and \ to convince make to run all commands in a single shell, and using $$ to escape the $ and use shell variable references.
The error is in the text, namely
psql -U -d -q -f db/schema_tables.sql && rm file.sh
This happens because the variables $(user) and $(database) aren't set. Every line within a target is executed in a sub shell. There is now way to use source like you would in a regular script.
You could create a file named database.mk in which you define these variables and use include database.mk at the top of your makefile to include them:
Makefile
CONFILE ?= database
include $(CONFILE).mk
test:
#echo $(user)
#echo $(database)
database.mk
user := user
database := data
If you want to parse the ini file you could do that as such
CONFILE := db/database.ini
make-db: _setup_con
echo $(user) $(database)
# your target
_setup_con:
$(eval user=$(shell grep "user=" $(CONFILE) | grep -Eo "[^=]*$$"))
$(eval database=$(shell grep "database=" $(CONFILE) | grep -Eo "[^=]*$$"))
# and so forward
I would make it more Make-way by using feature of automatic Makefile generation. Given that a configuration file is a simple properties file, its syntax is easily parseable by Make, it's sufficient to just get the lines with variables, i.e.:
include database.mk
database.mk: db/database.ini
grep -E '^\w+=\w+$$' $< > $#
.PHONY: create-db
create-db: $(from_file)
psql -U $(user) -d $(database) -q -f $<
Some additional notes:
create-db should be made .PHONY to avoid situation when nothing is done due to somebody creating (accidentally or not) a file named create-db,
by making create-db depending on from_file one can get a clean and readable error from make that a file does not exist instead of possibly cryptic error later.

How to fix Automated Backup script for postgres [Window]?

I have look up a duplicate question PostgreSQL: Automated Backup in Windows and other source https://wiki.postgresql.org/wiki/Automated_Backup_on_Windows. I have try to make a simple batch script for my own [eg. Setup Path , Set up password... etc] in order to do restore database in the future. However, it seems like my batch script for backup database does not work at all. I can't figure out where is my mistaken point.
Here is my batch script for backup postgres database.
#echo off
SET PGPASSWORD=%Ech0-5910&123
set root=C:\Program Files (x86)\pgAdmin 4\v3\runtime\
echo on
cd %root%
echo on
pg_dump.exe -h 192.168.1.161 -p 5432 -U postgres -F c -b -v -f "D:\Backup\DatabaseBackUp\SQL\123456.backup" testdb
Updated Script follow #Gerhard Barnard answer
#echo off
echo 192.168.1.161:5432:_wolfcom:postgres:R0m3o^%%Ech0-5910^&>"%APPDATA%\postgresql\pgpass.conf"
set "root=C:\Program Files (x86)\pgAdmin 4\v3\runtime\"
cd /d "%root%"
pg_dump.exe -h 192.168.1.161 -p 5432 -U postgres -F c -b -v -f "D:\Backup\DatabaseBackUp\SQL\123456.backup" _wolfcom
pause
Your code should wrap all paths in double quotes to eliminate whitespace. Keep in mind cmd interprets each space delimited work as a new command. We need to escape the & as it will become a physical operator in batch, lastly it is prefered to use the /d option when using cd in case you come from another drive letter:
#echo off
SET "PGPASSWORD=%Ech0-5910^&123"
set "root=C:\Program Files (x86)\pgAdmin 4\v3\runtime\"
cd /d "%root%"
pg_dump.exe -h 192.168.1.161 -p 5432 -U postgres -F c -b -v -f "D:\Backup\DatabaseBackUp\SQL\123456.backup" testdb
Also note, you never use the password in your pg_dump command, so you need to consider that as well. Best practice is to edit
%APPDATA%\postgresql\pgpass.conf
and add
*:5432:*:username:password
to automate that part in your script:
#echo off
echo *:5432:*:postgres:%Ech0-5910^&123>""%APPDATA%\postgresql\pgpass.conf"
set "root=C:\Program Files (x86)\pgAdmin 4\v3\runtime\"
cd /d "%root%"
pg_dump.exe -h 192.168.1.161 -p 5432 -U postgres -F c -b -v -f "D:\Backup\DatabaseBackUp\SQL\123456.backup" testdb
If the dir does not exist, create it "%APPDATA%\postgresql"

Merge two Batch Files into one

i have written a small script that is taking infos from an console application and sending it via email to me. I have used Quiet to let the programm run in the background.
start.bat
Quiet script.bat
script.bat
info.exe > "data.txt"
sendEmail -o tls=yes -f myemail#gmail.com -t myemail#gmail.com -s smtp.gmail.com:587 -xu myemail#gmail.com -xp mypasswd -u "XXX" -m "XXX" -a "data.txt"
del "data.txt"
if i run it like this it works fine but when i try to make one file of it like:
script.bat
Quiet script.bat
info.exe > "data.txt"
sendEmail -o tls=yes -f myemail#gmail.com -t myemail#gmail.com -s smtp.gmail.com:587 -xu myemail#gmail.com -xp mypasswd -u "XXX" -m "XXX" -a data.txt"
del "data.txt"
It sends infinte amount of emails. When i make it like this it works but not like i want it to.
script.bat
Quiet script.bat
pause
info.exe > "data.txt"
sendEmail -o tls=yes -f myemail#gmail.com -t myemail#gmail.com -s smtp.gmail.com:587 -xu myemail#gmail.com -xp mypasswd -u "XXX" -m "XXX" -a data.txt"
pause
del "data.txt"
The reason for the infinite mails is that you call the batch file inside the batch file, which causes an infinite loop of running the batch.
The problem is with the logic of what that you are expecting to happen,
you want to click the batch file and expect that it will run by Quiet before it runs in shell.
If you just want to run it in background, you can easily achieve it by running it as "System"(with a service/schedule task and etc.), otherwise I think that you can't resolve this issue(you expect that another executable will run the current batch you are clicking - the first batch will always open a window).
Because you are clicking to start the program, the shortcut can have the launching command in it, changed in the properties.
"c:\folder\Quiet.exe" "c:\batch\folder\script.bat"
and then there is just the one batch file.
UPDATE
Not sure I understood everything.
One way would be in script.bat
Probably echo are needed in front of each command. if it doesn't work, try in one line
#echo off
(
echo info.exe > "data.txt"
echo sendEmail -o tls=yes -f myemail#gmail.com -t myemail#gmail.com -s smtp.gmail.com:587 -xu myemail#gmail.com -xp mypasswd -u "XXX" -m "XXX" -a "data.txt"
echo del "data.txt"
) > output.txt 2>&1 | Quiet.exe
Or in one liner
#echo off
(
echo info.exe > "data.txt" &&^
echo sendEmail -o tls=yes -f myemail#gmail.com -t myemail#gmail.com -s smtp.gmail.com:587 -xu myemail#gmail.com -xp mypasswd -u "XXX" -m "XXX" -a "data.txt" &&^
echo del "data.txt" &&^
) > output.txt 2>&1 | Quiet.exe
In this way, start.bat is not necessary.
Which is equivalent to this:
Quiet.exe info.exe > "data.txt" && sendEmail -o tls=yes -f myemail#gmail.com -t myemail#gmail.com -s smtp.gmail.com:587 -xu myemail#gmail.com -xp mypasswd -u "XXX" -m "XXX" -a "data.txt" && del "data.txt"
EDIT:
#echo off
Quiet start cmd /c "info.exe > 'data.txt' && sendEmail -o tls=yes -f myemail#gmail.com -t myemail#gmail.com -s smtp.gmail.com:587 -xu myemail#gmail.com -xp mypasswd -u "XXX" -m "XXX" -a 'data.txt' && del 'data.txt'"
Pause
In the last example, you have to deal with double quotes, probably not necessary.

Makefile error:127

I compiled the source code with the Makefile, I got Makefile Error:
/bin/sh: line 8: : command not found
make: *** [lib_build] Error 127
My lib_build target is as below:
lib_build:
#echo "--------------------------------------------------------------------";
#echo "VZW Compiling DM Agent 3rd party and native Libraries..." ;
#echo "--------------------------------------------------------------------";
mkdir -p $(VZW_LIB_DIR) ; \
mkdir -p $(VZW_BIN_DIR) ; \
mkdir -p $(VZW_SCR_DIR) ; \
mkdir -p $(VZW_CFG_DIR) ; \
mkdir -p $(VZW_OBJ_DIR) ; \
mkdir -p $(VZW_LOG_DIR) ; \
cd $(VZW_BASE_DIR)/lib/ ; \
make all ; \
cd $(VZW_SYNCML_DIR)/src/bld/linux ; \
make all;
cp -r $(VZW_SYNCML_DIR)/bin/linux/libsml.so $(VZW_LIB_DIR) ;
cp -r $(VZW_SYNCML_DIR)/bin/linux/libxpt.so $(VZW_LIB_DIR) ;
cp -r $(VZW_BASE_DIR)/3rd_party/iksemel-1.4/src/.libs/* $(VZW_LIB_DIR) ;
It was working fine then I try to modify some line in the above source code and later reverted everything. Then something went wrong and I got the error. I am not able to understand what went wrong.
One more thing to add here. Is there any way to know in which line exactly in the Makefile this kind of problem is happening. If there is no way then it is very difficult to spot these kind of problems.
I would suggest restructuring the commands. As the rule is written, it ignores all errors because this is how shell works. At least prepend set -e to this sequence of shell commands.
A lot more mind-tweaking to find if any syntactical mistake is there, I found the solution that there was a space after a line in Makefile ie. after the "/"
cd $(VZW_SYNCML_DIR)/src/bld/linux ; \
This was very difficult to spot though as spaces are not visible.

Resources