How to let Bash script extends User's PATH? - bash

At command line, my command python3 -u jupterlab notebook works perfectly as python locates at /srv/conda/envs/notebook/bin/python3.
Next, I have a bash script, say /usr/local/share/python3-login, its content is
#!/bin/bash -l
echo $PATH
exec python3 -u "$#"
My problem is when I call the script, I encountered an error where python3 not found /usr/local/share/python3-login: line 3: exec: python3: not found
I tried to debug by adding echo $PATH at line 2, and turned out PATH is /opt/conda/condabin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/game, which python3 doesn't exist
How to let my bash script recognize /srv/conda/envs/notebook/bin/python3?
To add more context, I built a docker image with Ubuntu OS

You can just use the full path:
#!/bin/bash -l
echo $PATH
exec /srv/conda/envs/notebook/bin/python3 -u "$#"

To extend the user's path, modify the PATH environment variable.
export PATH=/srv/conda/envs/notebook/bin/python3:$PATH

-l Make bash act as if it had been invoked as a login shell
That means it will loads the various profile files as if you just logged in
Since /srv/conda/envs/notebook/bin does not look as a standard path one would see in an profile file, I suspect you do something more to get this in your $PATH in the first place.
solution 1: simply add whatever you do to get this path in your environment, into the script.
solution 2: simply don't use the -l argument in your shebang.

Related

Bash - Print the full path of a file from $PATH

Say I have ~/scripts in my $PATH and I have script.sh inside that path.
I can execute that script by typing script.sh directly in the terminal, but what if I want to print out the full path of that script without knowing the base path of the script (or added any function inside the script to print out its own path)? Are there any good ways to do this?
In bash, to locate a file (script) in the users path, you can use the which command: (https://ss64.com/bash/which.html), but as #Jetchisel says there are better alternatives for POSIX-compliant shells; see 'which' vs 'command -v' in Bash

Failing to run external Bash program — /usr/bin/bash: bad interpreter: No such file or directory

I'm trying to run a CLI tool in Linux (Mint) which allows me to edit subtitles. It is named subedit: github link. In order to run it, I've added executable permission with chmod +x and added it to the path in bash. However, when I run it, I get the following error message:
bash: /home/main/Documents/shellTools/subedit/subedit: /usr/bin/bash: bad interpreter: No such file or directory
I'm not very experienced with external bash programs and forgot to do something that would be obvious in hindsight.
When I do echo $PATH this is the output:
/home/main/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/main/Documents/shellTools/subedit/
Could somebody please help?
Assuming bash is installed, (it usually is), change the first line of subedit from:
#!/usr/bin/bash
to:
#!/bin/bash
Or if one would prefer not to edit subedit, try this one-liner covering what Al-waleed Shihadeh suggested:
ln -s "$(which bash)" /usr/bin/bash
It seems that you don't have bash installed, you can verify that by running
which bash
if the above command returns "bash not found", then you need to install it.
In case the above command returns a path, you can use the below command to add a symlink to the expected path
ln -s $(path from the above command) /usr/bin/bash
Use the command termux-chroot ONCE!
If you want to always run at the start of a session, be sure to check if it was never run before.
if [ -z $CHROOT ]; then
CHROOT=1
termux-chroot
fi

Configuring bash $PATH variable to find UNIX executable file

I have a custom command called git-feature, which is located in a Unix executable file with the same name. I'm trying to configure the $PATH variable in ~/.bash_profile so that it recognizes the Unix file. I updated the PATH variable to include the file's path:
export PATH=$PATH:~/Applications/MAMP/htdocs/code/git-shortcuts/
The echo $PATH command in my bash terminal produces the following result:
/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Users/myname/Applications/MAMP/htdocs/code/git-shortcuts/
But trying to call git-feature leads to the following error:
-bash: git-feature: command not found
There are a few similar questions on S.O., but none of the ones I found solved this specific type of issue. Do I need to change the PATH variable differently in order for my custom command to be recognized by bash?
You are modifying the PATH variable correctly.
Make sure that git-feature really is in that directory, that it has the executable bit (+x) set, and that the directories leading to it give you rights to execute it:
MYFILE=/Users/myname/Applications/MAMP/htdocs/code/git-shortcuts/git-feature
ls -l "$MYFILE"
chmod +x "$MYFILE"
[ -x "$MYFILE" ] && echo "File can't be executed, check directory rights"

Crontab Absolute Path Auto Fill In

Hi there I have a shell command that I need to put into crontab to run periodically.
I have test my script in the working directory, say my home directory, and it works fine. Something similar like:
python myscript.py <input >/tmp/output
As you can see the myscript.py and input file are located in my home directory and the output should go into the tmp folder.
I know I could use 'which' command to get the path of python and 'pwd' command to get the working directory while I am done with my test. However, I am wondering is there a tool or command to translate that into the complete version easily.
How could I easily replace every thing with the full path so I could put that 'full path version' into crontab and it could be recognized globally.
python myscript.py <input >/tmp/output
... magic ...
/usr/bin/python /home/myAccount/myscript.py </home/myAccount/input >/tmp/output
For bash you could do that easily with one command:
echo "$(type -P python) $HOME/myscript.py <$HOME/input >/tmp/output"
And that doesn't rely on external command like which or pwd. You can also place that on a script. Just add #!/bin/bash on the header.

difference in execution of a script in bash and korn

i have a script that reads a file line by line
the code is
FILE=commands.txt
while read CMD; do
echo "$CMD"
done < "$FILE"
This code is stored in a script file vxm_alarm.sh
In Korn shell, this loop works perfectly, when i run the command vxm_alarm.sh. In bash however i get the following error
vxm_alarm.sh: syntax error at line 4: `done' unexpected
In Bash I'm executing the script using the command sh vxm_alarm.sh. what am i doing wrong? And why can't we execute a script simply by doing this in bash
chmod +x filename.sh
filename.sh
Your code works on my machine using GNU bash 4.1.5
Try adding a shebang to the top:
#!/bin/sh
FILE=commands.txt
while read CMD; do
echo "$CMD"
done < "$FILE"
If you run sh vxm_alarm.sh you are most likely not running Bash. Try sh --version - If you get anything other than a version string, it's not Bash. Try running bash vxm_alarm.sh instead.
To be able to run a script without a path before it it has to be in one of the directories listed in the PATH variable. For example, if
echo "$PATH"
prints
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
you can put filename.sh in /usr/local/sbin, /usr/local/bin, /usr/sbin, /usr/bin, /sbin or /bin and run it as simply filename.sh. If you want your script to be run from a directory not in the path, you have three choices:
Modify $PATH to include the directory where the script resides.
Run it with a relative or absolute path.
Create an alias or function pointing to the relative or absolute path.
I'd like to answer this part of your question:
why can't we execute a script simply by doing this in bash
chmod +x filename.sh
filename.sh
As others already pointed out in part, there are several things required for that to work:
execution rights (You ensured that with your chmod command)
the shebang, so the system knows what shell/interpreter to use
#!/bin/bash
(it is important to say bash if you want bash and not sh)
make sure the command is found. This is the case when its directory is found in PATH. However what you'd rather do in this case is specify the directory. For the current directory you can do it like this
./name-of-the-script
In contrast to DOS and (IIRC) the various Windows Command line interfaces, Unix systems usually don't have the current directory on the PATH. It is possible to add it, but discouraged due to severe implications on security.

Resources