makefile change working directory, python - makefile

that runs multiple python scripts but I have a slight problem. my python one of my scripts creates/writes to a sql database that is in the scripts directory. but when I use make file a database is created in the makefiles's directory and not the python script's directory. so how can I change the makefile's working directory?
this is a map of my file:
+ ProjectFile
|---+ make file
|---+ database (unwanted)
|---+ PythonScript1
|---+ main.py python script
|---+ (where a database should be))
|---+ PythonScript2
|---+ main.py python script
|---+ (where a database should be))
|---+ PythonScript3
|---+ main.py python script
|---+ (where a database should be)
this is my makefile:
PYTHON = python3
TERMINAL = gnome-terminal
TFLAG = --
FOLDERS = server
LIST = a b c d e
run:
for dir in $(FOLDERS); do \
cd $${dir} \
${TERMINAL} ${TFLAG} ${PYTHON} main.py ; \
done
I had an idea of changing directories in my for loop but then I read that it isnt necessary. So how can I change the working directory?

No doubt the comment you read was talking about a different situation than yours.
You don't, in general, want to change make's working directory. Instead you should change the working directory of the command you invoke (if it needs to be run from a specific directory).
The makefile recipe you've posted is very confusing: you have variables assigned to names that are different than what you show in your example, and some are not used at all. The recipe you use is almost correct, but it contains a shell error so I'm sure it doesn't run. You can do this as:
run:
for dir in $(FOLDERS); do \
cd $${dir} ; \
${TERMINAL} ${TFLAG} ${PYTHON} main.py ; \
done
Note the semicolon after the cd command. You can also change this to && to be a little safer (so that it doesn't run the command if the cd fails).
In general, this is not a very make-like makefile. You might as well just use a shell script here since you're not taking advantage of any of make's actual features.
Also, it's highly unusual to start a graphical terminal from a makefile to run commands in. Why are you doing that?
I would write this something like:
FOLDERS := PythonScript1 PythonScript2 PythonScript3
run: $(FOLDERS)
$(FOLDERS):
cd $# && $(PYTHON) main.py
.PHONY: run $(FOLDERS)

Related

How to change path in the commands of Makefile

Question
If there is a command that has to run at a given path, how can I change the path in makefile?
Sample Description
For example, the structure of my project folder(D:\proj) is shown below
--proj
----Makefile
----src
------test.py
The content of test.py is below
import sys
cur_path = sys.path[0]
print("Current path:%s" %cur_path)
The content of Makefile is below
chdir:
cd .\src
python test.py
The command make chdir cannot run and it throws error "cannot find file". Obviously, cd command not work.
How can I realize cd command in Makefile?
Assume that we cannot change the command python test.py to python .\src\test.py
My expectation
The command make chdir runs normally without changing the command python test.py
Change the content of Makefile into
chdir:
cd ./src &&\
python test.py
Each line of command has no context relation, unless you use && to connect them.

how can i make my bash script (.sh) to run locally as a bash command? [duplicate]

If I have a basic Python script, with it's hashbang and what-not in place, so that from the terminal on Linux I can run
/path/to/file/MyScript [args]
without executing through the interpreter or any file extensions, and it will execute the program.
So would I install this script so that I can type simply
MyScript [args]
anywhere in the system and it will run? Can this be implemented for all users on the system, or must it be redone for each one? Do I simply place the script in a specific directory, or are other things necessary?
The best place to put things like this is /usr/local/bin.
This is the normal place to put custom installed binaries, and should be early in your PATH.
Simply copy the script there (probably using sudo), and it should work for any user.
Walkthrough of making a python script available anywhere:
Make a python script:
cd /home/el/bin
touch stuff.py
chmod +x stuff.py
Find out where your python is:
which python
/usr/bin/python
Put this code in there:
#!/usr/bin/python
print "hi"
Run in it the same directory:
python stuff.py
Go up a directory and it's not available:
cd ..
stuff.py
-bash: stuff.py: command not found
Not found! It's as we expect, add the file path of the python file to the $PATH
vi ~/.bashrc
Add the file:
export PATH=$PATH:/home/el/bin
Save it out, re apply the .bashrc, and retry
source ~/.bashrc
Try again:
cd /home/el
stuff.py
Prints:
hi
The trick is that the bash shell knows the language of the file via the shebang.
you can also use setuptools (https://pypi.org/project/setuptools/)
your script will be:
def hi():
print("hi")
(suppose the file name is hello.py)
also add __init__.py file next to your script (with nothing in it).
add setup.py script, with the content:
#!/usr/bin/env python3
import setuptools
install_requires = [
'WHATEVER PACKAGES YOU NEED GOES HERE'
]
setuptools.setup(
name="some_utils",
version="1.1",
packages=setuptools.find_packages(),
install_requires=install_requires,
entry_points={
'console_scripts': [
'cool_script = hello:hi',
],
},
include_package_data=True,
)
you can now run python setup.py develop in this folder
then from anywhere, run cool_script and your script will run.
Just create ~/bin and put export PATH=$PATH:$HOME/bin in your bashrc/profile. Don't mess with the system, it will bite you back, trust me.
Few more things (relevant to the question but not part of the answer):
The other way export PATH=$HOME/bin:$PATH is NOT safe, for bash will will look into your ~/bin folder for executables, and if their name matches with other executables in your original $PATH you will be surprised by unexpected/non working command execution.
Don't forget to chmod+x when you save your script in ~/bin.
Be aware of what you are putting in your ~/bin folder, if you are just testing something or working on unfinished script, its always better to use ./$SCRIPT_NAME from your CWD to execute the script than putting it under ~/bin.
The quick answer is to symlink your script to any directory included in your system $PATH.
The long answer is described below with a walk through example, (this is what I normally do):
a) Create the script e.g. $HOME/Desktop/myscript.py:
#!/usr/bin/python
print("Hello Pythonista!")
b) Change the permission of the script file to make it executable:
$ chmod +x myscript.py
c) Add a customized directory to the $PATH (see why in the notes below) to use it for the user's scripts:
$ export PATH="$PATH:$HOME/bin"
d) Create a symbolic link to the script as follows:
$ ln -s $HOME/Desktop/myscript.py $HOME/bin/hello
Notice that hello (can be anything) is the name of the command that you will use to invoke your script.
Note:
i) The reason to use $HOME/bin instead of the /usr/local/bin is to separate the local scripts from those of other users (if you wish to) and other installed stuff.
ii) To create a symlink you should use the complete correct path, i.e.
$HOME/bin GOOD ~/bin NO GOOD!
Here is a complete example:
$ pwd
~/Desktop
$ cat > myscript.py << EOF
> #!/usr/bin/python
> print("Hello Pythonista!")
> EOF
$ export PATH="$PATH:$HOME/bin"
$ ln -s $HOME/Desktop/myscript.py $HOME/bin/hello
$ chmod +x myscript.py
$ hello
Hello Pythonista!
Just create symbolic link to your script in /usr/local/bin/:
sudo ln -s /path/to/your/script.py /usr/local/bin/script
Putting the script somewhere in the PATH (like /usr/local/bin) is a good solution, but this forces all the users of your system to use/see your script.
Adding an alias in /etc/profile could be a way to do what you want allowing the users of your system to undo this using the unalias command. The line to be added would be:
alias MyScript=/path/to/file/MyScript
i find a simple alias in my ~/.bash_profile or ~/.zshrc is the easiest:
alias myscript="python path/to/my/script.py"
Type echo $PATH in a shell. Those are the directories searched when you type command, so put it in one of those.
Edit: Apparently don't use /usr/bin, use /usr/local/bin
Acording to FHS, the /usr/local/bin/ is the good place for custom scripts.
I prefer to make them 755 root:root, after copying them there.

Change the SHELL used in TI Code Composer Studio's auto-generated Makefiles on Windows 10

I need the makefile generated by TI Code Composer Studio 10 to use SHELL = sh.exe instead of SHELL = cmd.exe. The insertion of the SHELL line seems to be specific to TI and not Eclipse. I can't figure out how to do this. I've tried setting environment variables at the system level and in the project build settings. I've tried running TI CCS from a bash shell hoping it might pick up its own environment. I've also looked through the Eclipse sources for generating the makefile.
Example:
Everything from SHELL to just before the -include line is TI specific.
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
SHELL = cmd.exe
CG_TOOL_ROOT := C:/ti/ccs1040/ccs/tools/compiler/ti-cgt-msp430_20.2.5.LTS
GEN_OPTS__FLAG :=
GEN_CMDS__FLAG :=
ORDERED_OBJS += \
"./msp430fr60x7_1.obj" \
"../lnk_msp430fr6047.cmd" \
$(GEN_CMDS__FLAG) \
-llibmpu_init.a \
-llibmath.a \
-llibc.a \
-include ../makefile.init
Reason: gmake creates batch files for commands like echo and our computers have security software that block randomly created batch files from running. If run from bash/sh, gmake doesn't use intermediate batch files.
Update: I may have a workaround by telling the project to invoke gmake like this: sh.exe -c gmake.exe args. That isn't working fully though as the args do not get passed.
After confirming with TI that the SHELL is hardcoded, this workaround is the solution.
You'll need to:
Create a make.sh shell script to run the real gmake.exe
Create a makefile.defs to fix some SHELL and RM variables inside the TI generated makefile
Install another sh.exe. I used the one installed with Git for Windows. The cygwin sh.exe that comes with the TI compiler doesn't work. This is a shame, because it would be nice to have a solution not requiring another tool.
First, modify your project build settings to run the make script. In TI Code Composer Studio:
Project Menu -> Show Build Settings -> CCS Build -> Builder
[ ] Uncheck "Use default build command"
Build Command: C:/Progra~1/Git/bin/sh.exe ${PROJECT_ROOT}/make.sh ${CCS_UTILS_DIR}/bin/gmake -k -j 8
Note: You have to use the MS-DOS short path for "Program Files," because it's 2021, and Eclipse can't handle spaces in a path.
Create make.sh in the PROJECT_ROOT directory:
#!C:/Progra~1/Git/bin/sh.exe
# The cygwin provided shell from TI doesn't work with make. Use the one from Git instead or even SourceTree's embedded Git shell.
# In TI CCS, Project -> Show Build Settings -> CCS Build -> Builder -> Build Command (Uncheck Use default build command)
# Build Command: C:/Progra~1/Git/bin/sh.exe ${PROJECT_ROOT}/make.sh ${CCS_UTILS_DIR}/bin/gmake -k -j 8
echo "$#"
# debugging
#echo $#
#env | sort
if [ $# -eq 0 ]; then
echo Nothing to do. >&2
exit
fi
export MAKESHELL="$SHELL"
# echo MAKESHELL is \'$MAKESHELL\' inside the script, but will be translated to the DOS path inside make.
"$#"
Create makefile.defs in the PROJECT_ROOT directory. The Eclipse generated makefile includes this file at the very end allowing it to override any settings set by TI.
# The invoking shell sets MAKESHELL so we can grab it here.
SHELL = $(MAKESHELL)
RM = rm -f
$(info "MAKEFLAGS is $(MAKEFLAGS)")
$(info "MAKECMDGOALS is $(MAKECMDGOALS)")
# $(info "SHELL is $(SHELL)")
# $(info "CWD is $(CWD)")
# $(info "PATH is ${PATH}")

How can I execute a python script directly (without prefixing by the python command) from bash?

I am just starting to use terminal for my programming needs. In a lot of Django tutorials I see people say, for example, I should type this in terminal:
manage.py runserver
However when I do this it says:
bash: manage.py: command not found
I get it to work when I do: python manage.py runserver, however I would like to understand why this works and the other method doesn't. I guess these are some very basic things but I thought I'd ask here.
It is because your manage.py is not an executable script.
First put this line at the top of manage.py (assuming your python is in /usr/bin/python):
#!/usr/bin/python
Then make your script executable:
chmod +x manage.py
Then try to execute your script ./manage.py runserver.
Read this link for more info: http://effbot.org/pyfaq/how-do-i-make-a-python-script-executable-on-unix.htm
bash(1) will search your PATH environment variable to find programs to execute. PATH does not normally contain your "current working directory" (.) because that opens people up to trivial security problems:
cd /home/unsavory_character/
ls
If unsavory_character places an executable in /home/unsavory_character/ls that adds his or her ssh(1) key to your ~/.ssh/authorized_keys file, you'd be in for a surprise -- he or she could log in as you without a password.
So systems these days don't add the current working directory to the PATH, because it is too unsafe.
The workaround:
./manage.py runserver
Of course, that assumes your current working directory is whichever directory contains the manage.py script. That might be a safe assumption. If you'd like to be able to execute it from anywhere in the filesystem, you can add the directory to your PATH by editing your ~/.profile or ~/.bash_profile or ~/.bashrc file. (If one of them already exists, pick that one. I seem to recall others with PATH problems on OS X found one or the the other file worked well, and the other one never got executed.)
(In my case, I have a bunch of self-written utilities in ~/bin/, but yours might be elsewhere. Change the paths as appropriate.)
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi
manage.py needs to be executable. Try: chmod +x manage.py
I've cooked together a small "script" to automate this: (just copy whole text, and paste inside your active terminal.)
tee -a ~/.profile <<EOF
if [ -d "/Library/Python/2.6/site-packages/django/bin" ] ; then
PATH=/Library/Python/2.6/site-packages/django/bin:$PATH
fi
EOF
Doesn't django-admin.py do the same? I think so, because I can find manage.py inside my ../bin folder. And stated at the official documentation, they do the same. So I believe ;)
Also, have you obtained Django via easy_install? My script expect that you are using Snow Leopard with the system version (Python 2.6).

How do I execute a bash script in Terminal?

I have a bash script like:
#!/bin/bash
echo Hello world!
How do I execute this in Terminal?
Yet another way to execute it (this time without setting execute permissions):
bash /path/to/scriptname
$prompt: /path/to/script and hit enter. Note you need to make sure the script has execute permissions.
cd to the directory that contains the script, or put it in a bin folder that is in your $PATH
then type
./scriptname.sh
if in the same directory or
scriptname.sh
if it's in the bin folder.
You could do:
sh scriptname.sh
This is an old thread, but I happened across it and I'm surprised nobody has put up a complete answer yet. So here goes...
The Executing a Command Line Script Tutorial!
Q: How do I execute this in Terminal?
The answer is below, but first ... if you are asking this question, here are a few other tidbits to help you on your way:
Confusions and Conflicts:
The Path
Understanding The Path (added by tripleee for completeness) is important. The "path" sounds like a Zen-like hacker koan or something, but it is simply a list of directories (folders) that are searched automatically when an unknown command is typed in at the command prompt. Some commands, like ls may be built-in's, but most commands are actually separate small programs. (This is where the "Zen of Unix" comes in ... "(i) Make each program do one thing well.")
Extensions
Unlike the old DOS command prompts that a lot of people remember, you do not need an 'extension' (like .sh or .py or anything else), but it helps to keep track of things. It is really only there for humans to use as a reference and most command lines and programs will not care in the least. It won't hurt. If the script name contains an extension, however, you must use it. It is part of the filename.
Changing directories
You do not need to be in any certain directory at all for any reason. But if the directory is not on the path (type echo $PATH to see), then you must include it. If you want to run a script from the current directory, use ./ before it. This ./ thing means 'here in the current directory.'
Typing the program name
You do not need to type out the name of the program that runs the file (BASH or Python or whatever) unless you want to. It won't hurt, but there are a few times when you may get slightly different results.
SUDO
You do not need sudo to do any of this. This command is reserved for running commands as another user or a 'root' (administrator) user. Running scripts with sudo allows much greater danger of screwing things up. So if you don't know the exact reason for using sudo, don't use it. Great post here.
Script location ...
A good place to put your scripts is in your ~/bin folder.
You can get there by typing
# A good place to put your scripts is in your ~/bin folder.
> cd ~/bin # or cd $HOME/bin
> ls -l
You will see a listing with owners and permissions. You will notice that you 'own' all of the files in this directory. You have full control over this directory and nobody else can easily modify it.
If it does not exist, you can create one:
> mkdir -p ~/bin && cd ~/bin
> pwd
/Users/Userxxxx/bin
A: To "execute this script" from the terminal on a Unix/Linux type system, you have to do three things:
1. Tell the system the location of the script. (pick one)
# type the name of the script with the full path
> /path/to/script.sh
# execute the script from the directory it is in
> ./script.sh
# place the script in a directory that is on the PATH
> script.sh
# ... to see the list of directories in the path, use:
> echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# ... or for a list that is easier to read:
> echo -e ${PATH//:/\\n}
# or
> printf "%b" "${PATH//:/\\n}"
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
2. Tell the system that the script has permission to execute. (pick one)
# set the 'execute' permissions on the script
> chmod +x /path/to/script.sh
# using specific permissions instead
# FYI, this makes these scripts inaccessible by ANYONE but an administrator
> chmod 700 /path/to/script.sh
# set all files in your script directory to execute permissions
> chmod +x ~/bin/*
There is a great discussion of permissions with a cool chart here.
3. Tell the system the type of script. (pick one)
Type the name of the program before the script. (Note: when using this method, the execute(chmod thing above) is not required
> bash /path/to/script.sh
...
> php /path/to/script.php
...
> python3 /path/to/script.py
...
Use a shebang, which I see you have (#!/bin/bash) in your example. If you have that as the first line of your script, the system will use that program to execute the script. No need for typing programs or using extensions.
Use a "portable" shebang. You can also have the system choose the version of the program that is first in the PATH by using #!/usr/bin/env followed by the program name (e.g. #!/usr/bin/env bash or #!/usr/bin/env python3). There are pros and cons as thoroughly discussed here.
Note: This "portable" shebang may not be as portable as it seems. As with anything over 50 years old and steeped in numerous options that never work out quite the way you expect them ... there is a heated debate. The most recent one I saw that is actually quite different from most ideas is the "portable" perl-bang:
#!/bin/sh
exec perl -x "$0" "$#"
#!perl
Firstly you have to make it executable using: chmod +x name_of_your_file_script.
After you made it executable, you can run it using ./same_name_of_your_file_script
Change your directory to where script is located by using cd command
Then type
bash program-name.sh
And yet one more way
. /path/to/script
What is the meaning of the dot?
If you are in a directory or folder where the script file is available then simply change the file permission in executable mode by doing
chmod +x your_filename.sh
After that you will run the script by using the following command.
$ sudo ./your_filename.sh
Above the "." represent the current directory.
Note!
If you are not in the directory where the bash script file is present then you change the directory where the file is located by using
cd Directory_name/write the complete path
command. Otherwise your script can not run.

Resources