Why run a program in a modified environment in a shell script - shell

How is useful env in this install.sh script:
env git clone --depth=1 https://github.com/robbyrussell/oh-my-zsh.git $ZSH || {
printf "Error: git clone of oh-my-zsh repo failed\n"
exit 1
}
Is it because of the variable $ZSH?

The $ZSH variable is defined a couple of lines above so it is not the purpose here.
The env command can be used to run a command/program in a modified environment, but as there are no additional variables specified here, the command will be run in an unmodified environment.
The main purpose in this case is to get rid of aliases and functions that could shadow the command to be run.

Related

Snakemake change conda activation command to 'conda activate'

I want to use snakemake with fish shell and conda environments in my managed environment (basically I have no root rights and the default shell cannot be changed).
I set up fish as the 'default' shell using this hack inside the .bashrc:
if [ "$REALBASH" != "1" ]; then
case "$-" in
*i*)
export SHELL=/usr/bin/fish
tty > /dev/null && echo "Your ~/.bashrc is switching interactive SHELL to $SHELL"
[ -x $SHELL ] && exec $SHELL "$#"
echo "Apparently $SHELL is not available here. Continuing with bash."
export SHELL=/bin/bash
;;
esac
fi
There is also a command realbash that sets the environment variable REALBASH=1 to bypass this hack.
I managed to get conda to work with fish using this, but it has the disadvantage that within fish the command to activate conda environments is different from bash. In bash, the command is source activate ... and in fish it is conda activate ....
Activating environments works both from bash using source activate ... and from fish using conda activate ....
When I now execute snakemake from fish, I get the following error:
Activating conda environment ...
source: Error encountered while sourcing file “activate”:
source: No such file or directory
If I execute snakemake from bash, the same error occurs.
If I execute snakemake from bash via snakemake --overwrite-shellcmd realbash, I get the same error and end up in the bash shell that was opened by snakemake. Only after typing exit, snakemake completes (but unsuccessfully, of course).
If I execute snakemake from fish via snakemake --overwrite-shellcmd realbash, the same behaviour occurs.
I am confused by the behaviour of --overwrite-shellcmd, is there a way to make this work with my hack?
Otherwise, can I configure snakemake to call conda activate instead of source activate?
Or is there any other solution to this?
Apparently this was a bug in an older version of snakemake. The effects described in the question were produced with snakemake 4.3.1.
Running snakemake from within a conda environment where snakemake 5.17.0 is installed works perfectly fine with the setup as described in the question. No --overwrite-shellcmd or other changes are required.

Execute Shell file functions in Mac

I have the following shell file that contains this:
sh
nightlyTag() {
echo $1-alpha.$(date +%Y%m%d).$(($(date +%s%N)/1000000))
}
yarnPubCanaryVersion() {
if [ -z "$1" ]
then
echo "No version argument supplied, maybe you meant v1.0.0?"
return 1
fi
version=`nightlyTag $1`
yarn version --new-version $version --no-git-tag-version
npm publish --tag canary
git reset --hard HEAD
}
I make the file executable with chmod +x canary.sh, then I run it doing ./canary.sh then my terminal changes to sh-3.2$ then I try to run the functions in the terminal like this nightlyTag and I get
sh: nightlyTag: command not found
Same for yarnPubCanaryVersion.
I was looking at this SO question
You won't be able to run functions from the terminal after you run the script.
You need to source the script to do this:
source ./canary.sh
Or add the contents of the file to the .bashrc file or its equivalent, and then source it.
The source command is used to load any function file into the current shell.
Now once you call those functions you will get the expected output.
At the top of your sh file you need to include:
#! /path/to/bash
the path to the bash that you are using.

Basic Bash script results in "edge.sh: line 13: npm: command not found" found issue here but it didn't resolve

The following simple script is apparently not so simple.
The entire script appears to work properly until I get to the npm command.
I have looked at the numerous threads here, but none of the solutions fix the issue.
Each of the scripts is kicked off by a parent script.
Here is the parent:
#!/bin/bash/
authGogglesPath='/c/sandBox/amazon-sandbox/CraigMonroe/platform.shared.auth-goggles'
echo $'\nExecuting node commands for local running solution...\n'
#echo $(pwd)
# run the scripts
bash edge.sh ${edgePath} &
exec bash
I checked my path in the terminal and it's aware
I thought that it might be running as another associated profile so I tried the full path to npm, but the same results.
#!/bin/bash/
authGogglesPath='/c/sandBox/amazon-sandbox/CraigMonroe/platform.shared.auth-goggles'
echo $'\nExecuting node commands for local running solution...\n'
#echo $(pwd)
# run the scripts
bash edge.sh ${edgePath} &
exec bash
That calls edge.sh with a string path for arg (more for later)
edge.sh is another simple script
#!/bin/bash/
PATH=$1
#echo $PATH
if [ -z "${PATH}" ] ; then
"PATH is empty! Aborting"
exit 1
fi
cd "${PATH}"
echo $'\nExecuting Edge...\n'
npm run dev
Each time I run this I'm receiving:
$ bash edge.sh /c/sandBox/amazon-sandbox/CraigMonroe/platform.shared.auth-goggles/
Executing Edge...
edge.sh: line 13: npm: command not found
cmonroe#LP10-G6QD2X2 MINGW64 ~/cruxScripts
$
When in the terminal and manually navigating to the directory and running the command it works properly. Where the edge builds and starts.
Unless npm is in /c/sandBox/amazon-sandbox/CraigMonroe/platform.shared.auth-goggles/, doing PATH=$1 means your PATH only refers to that one folder.
No more /usr/bin or any other folders your bash session might need.
As commented, adding to the PATH should work
PATH="$1:${PATH}"

Why Can't I Set Env Variables By Running A BASH Script From An Npm Script?

I have a nodejs javascript project, but I would like to set a bunch of environment variables locally. created a bash file that just exports some variables:
#!/usr/bin/env bash
export waka=flaka
export fat=booty
When I use the dot to source and run the file from the command line it works fine:
. ./env.sh
And I can see the variable has been set
echo $waka # prints "flaka"
But then I try to take this command and make it an npm script by adding it to my package.json
scripts: {
"set-env": ". ./env.sh",
...
}
and then run it:
npm run set-env
The script is run but the environment variables are not saved:
echo $waka # prints undefined (assuming you didn't already run it from command line)
So, I'm wondering why it doesn't save the envrionment variables as an npm script and if it's possible to run the bash script from an npm script in a way such that the environment variables will be saved for the rest of the command prompt session. Thanks!
npm is not a shell command; it runs in a separate process that forks another shell in order to run the command specified by set-env. env.sh is executed, but then that shell immediately exits, at which point the changes are gone (and then npm itself exits).

Docker unable to start an interactive shell if the image has an entry script

My custom-made image ends with
ENTRYPOINT [ "/bin/bash", "-c", "/home/tool/entry_script.sh" ]
This is absolutely needed because at runtime, the first thing the user must do is to update an already cloned github project, and users will often forget to do it.
But then, when i try to launch using
docker run -it --rm my_image /bin/bash
i can see that the ENTRYPOINT script is being executed, but then the container exit.
I expect to have /bin/bash being executed and the shell to remain in interactive mode, due to -it flags.
What am I doing wrong?
UPDATE: I add my entry script
#!/bin/bash
echo "UPDATING GIT REPO";
cd /home/tool/cloned_github_tools_root
git pull
git submodule init
git submodule update
echo "Entrypoint ended";
Actually I've not kind of errors at runtime
When you set and entry point in a docker container. It is the only thing it will run. It's the one and only process that matters (PID 1). Once your entry_point.sh script finishes running and returns and exit code, docker thinks the container has done what it needed to do and exits, since the only process inside it exits.
If you want to launch a shell inside the container, you can modify your entry point script like so:
#!/bin/bash
echo "UPDATING GIT REPO";
cd /home/tool/cloned_github_tools_root
git pull
git submodule init
git submodule update
echo "Entrypoint ended";
/bin/bash "$#"
This starts a shell after the repo update has been done. The container will now exit when the user quits the shell.
The -i and -t flags will make sure the session gives you an stdin/stdout and will allocate a psuedo-tty for you, but they will not automatically run bash for you. Some containers don't even have bash in them.
I think the original question and answer are pretty good (thank you!). However I had the same exact problem but the provided solution did not work for me. I ended up wasting a lot of time figuring out what I was doing wrong. Hence I came up with a solution that should work all the time, if this could save time for others. In my docker entry point I'm sourcing a shell script file from Intel compiler and the received parameters $# are somewhat changed by the 'source' command. Then when ending the script with /bin/bash "$#" the original parameters are gone. Here is my updated version that would be safer for all use cases:
#!/bin/bash
# Save original parameters
allparams=("$#")
echo "UPDATING GIT REPO";
cd /home/tool/cloned_github_tools_root
git pull
git submodule init
git submodule update
echo "Entrypoint ended";
# Forward initial parameters
/bin/bash "${allparams[#]}"

Resources