Create a spawn shell in Makefile - linux

I want to create a makefile target in Ubuntun to spawn a poetry shell. Here are the things I want to do if I were in the command shell:
type poetry shell, which is going to spawn a shell within the virtual environment.
do something in the poetry shell, such as executing a python script using command python ...
To facilitate the process, I want to create a makefile looking something like below
# if I can set SHELL in a specific way
# SHELL = ?????
foo:
poetry shell
echo "Success"
# many lines to be executed in the poetry shell, here is an example
python <a_python_file>
The problem as I found is that the execution will be hanging after poetry shell and will not execute echo "Success"
I know this could be a general question on spawning a shell from command shell, and it is not limited to poetry. Any comments/suggestions would be appreciated.
As a comment pointed out, what I really want is python ... instead of poetry run python .... I edited it.
As a comment pointed out, I added some pseudo code in the makefile.

I think there's some misunderstanding. I'd never heard of poetry before but a quick look at its manual makes clear how it works.
If you run poetry shell then you get an interactive shell which you are expected to type commands into from your keyboard. The reason it "hangs" is that it started a poetry shell and is now waiting for you to enter commands. It's not hung, it's waiting for some input.
You don't want to run an interactive set of poetry commands, you have a predefined set of poetry commands you want to run. For that, you would use poetry run as mentioned in the comments above:
foo:
poetry run python <first command>
poetry run python <second command>
...
echo "Success"
If you want to run all the commands within a single instance of poetry, you have to combine them all into a single invocation, maybe something like this (I didn't try this so the quoting might be wrong):
foo:
poetry run 'python <first command> && python <second command> ...'
echo "Success"
You could do this:
foo:
poetry run $(MAKE) in-poetry
echo "Success"
in-poetry:
python <command1>
python <command2>
Now if you run make foo all the commands in the in-poetry target are run within the poetry environment, because poetry run runs a make program in its environment, and that make program runs a bunch of python.
But if someone ran make in-poetry directory (not via the foo target) then those python operations would not be run inside a poetry environment (unless the user set it up before they ran make).

Related

Is there anyway to make export path work on Shell

I wrote a shell script called gola to install golang, and put it on folder /usr/local/bin
#!/usr/bin/env bash
curl -LO https://golang.org/dl/go1.16.3.linux-amd64.tar.gz
sudo tar -C /usr/local -zxf go1.16.3.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
echo -e "Installed" && exit 1
I run sudo gola, and installed golang successfully, but when I run go version, the command go can't be found, export PATH=$PATH:/usr/local/go/bin doesn't work. I think it might be because the script is running in a subshell and it doesn’t work on its parent. I can add export PATH=$PATH:/usr/local/go/bin to bash profile, it will works. Besides, is there any other way if I just want it to take effect by running sudo gola?
There's no way to do this when running the script with sudo, because the sudo program itself runs as a subprocess of your shell (and the shell running the script runs as a subprocess of sudo), and subprocesses cannot affect parent processes' environments. (Note: export makes a variable export down to subprocesses, not up to parent processes.)
But since you're already running the tar command itself with sudo inside the script, why do you need to run the entire script with sudo? If you run it with source (or . if your shell doesn't support that), it'll run in the current shell, and the change to PATH will apply to the current shell.
But even that might not be what you really want, because it'll affect only the current shell. Next time you open a new one, you won't be able to use go until you change the PATH for the new shell instance. If you want future shells to be able to use go, you must add it to someplace like ~/.bash_profile.

Can substring expansion be used in dash shell or bourne shell?

I'm converting an app to a new image, and the existing commands use substring expansion to set the artifact version like so: mvn clean versions:set -DnewVersion="0.1.$VCSINFO.I${INFO:0:6}.M$OTHER_INFO". I'm using a ubuntu image that defaults to /bin/sh, and I am unable to figure out how to either do something equivalent in bourne shell, or switch shells to run the command. I know bash is installed because I can see it in /etc/shells.
I tried using RUN ['/bin/bash', '-c', '...'] but I can see it is just running that command like so The command '/bin/sh -c ['/bin/bash', '-c',.... What is the best way to convert this functionality over to this new image?
You can run a bash command in two ways, even from sh: Either by passing the string '/bin/bash path/to/your/cmd' to the -c option of sh, or by setting the x-bit in cmd and having as the first line in cmd a #!/bin/bash.
Hence in your setting I would try either a RUN ['/bin/bash /path/to/your/cmd'] or just do a RUN ['/path/to/your/cmd'] and ensure that cmd has the #! line mentioned above, or complicated but fail safe - write a sh wrapper script, which then invokes the bash script in turn. Hence, if this wrappe script is called /path/to/your/cmdwrapper.sh, its content would be
:
/bin/bash /path/to/your/cmd

python3: How can I run a python script when python starts?

I have a shortcut which runs python3 in a terminal window. I would like to add some import commands to a python script which is to be run when python starts.
How can I do this?
eg; I have xfce4-terminal -e python3 which starts a graphical terminal session with python3 running. I want to add something to this to make python3 execute a script, however I do not want python to exit at the end of the script, which is the default behaviour if a filename is given immediatly following the python3 command.
See python --help. It mentions an environment variable called PYTHONSTARTUP which looks like it could help you get where you want.

Anaconda activate

I am using anaconda python. So every time, in my mac terminal, I input the terminal command:
source /Users/mylaptop/anaconda/bin/activate /Users/mylaptop/anaconda
And then I activated the anaconda python environment. But I don't want to write this command line every time, so I tried a bash script like this:
#! /bin/bash
source /Users/mylaptop/anaconda/bin/activate /Users/mylaptop/anaconda
and I put this file in the directory /usr/local/bin. But unfortunately, I cannot log into anaconda environment in this way. There is no error message showed up in the terminal. So I do not know what is happening here.
Could anyone help me out?
The easiest fix is to just put /Users/mylaptop/anaconda in your PATH, by adding something like
export PATH="/Users/mylaptop/anaconda:$PATH"
to your bash profile (~/.profile).
You can't put the activate script in a script because it has to be "sourced" to work. source causes the script to be run in your current shell (as opposed to a subshell, which is how the bash script you wrote is run). This is necessary because it modifies your PATH environment variable, and environment variables from your current shell cannot be modified by subshells.

Cron & Virtualenv : Cron does not run a python script that requires a virtualenv

EDIT 2 27/06/2013: The problem was a silly mistake unrelated to venv and cron.
Running venv from cron with the same user that created the venv works great using the activate desscribed below.
EDIT 25/06/2013: Since nohup.out is unchanged after the cron runs, I suspect the problem is in the use of virtualenv.
The cron is set with the same user than the one running the script from the command line.
I have written a script to activate venv then run a python script. It runs perfectly from the command line, when I do
nohup /home/heyheyhey/run.sh &
However, for some black magic reasons, the python part does not run from cron:
0 4 * * * /home/heyheyhey/run.sh &
Content of run.sh:
#! /bin/bash
cd /home/heyheyhey
. /home/heyheyhey/.pythonbrew/venvs/Python-2.7.2/venvname/bin/activate 2> error.log
python /home/heyheyhey/top.py 2> error.log
bzip2 -c "Exporter.csv" > "extraction.csv.bz2"
The run.sh executes since the output compressed file is created.
However the python script does not work since the Exporter.csv is not updated and I do not see activity into the log file.
Thanks for your help!
The environment of a cron job is often different from the environment you see
when you're logged into an interactive shell. In particular, you might want to
check whether the python interpreter is on the $PATH for the cron job. If your
python program reads any environment variables, you should check those too, to
ensure they're set as expected under cron.

Resources