Configuring bash $PATH variable to find UNIX executable file - macos

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"

Related

How to let Bash script extends User's PATH?

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.

ROS installation: no such file or directory

According to ros wiki, to set up environment,
I typed
echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc
source ~/.bashrc
The error is
/opt/ros/kinetic/setup.bash:.:8: no such file or directory: /home/pikashun/setup.sh
In ~/.bashrc file, there is the source /opt/ros/kinetic/setup.bash line.
I use Ubuntu on WSL.
How can I improve?
Thank you!
I had the exact same issue. The problem is not due to setup.bash either ~/.bashrc but the shell that you are using. It turned out that you may be using a different shell than bash (i.e., zsh). When you are executing the setup.bash of ROS, zsh interprets the following command (whici is in /opt/ros/kinetic/setup.bash) differently:
_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)
It is setting the _CATKIN_SETUP_DIR to your user directory. That is why you are getting error, cause you using the wrong path:
/home/user/setup.bash instead of /opt/ros/kinetic/setup.bash
To check whether this is the issue of your problem, you can check the shell that you are using by execute the following in the terminal:
echo $0; echo $SHELL
It may return something like:
zsh
/bin/zsh
To switch from zsh to bash, use:
exec bash
Once done this, you can use source without any problem.
And to switch back to your previous shell (assuming that is zsh), just use:
exec zsh
The file /opt/ros/kinetic/setup.bash does nothing but loading /opt/ros/kinetic/setup.sh from the same directory. I might be that you are not running bash (check which terminal you run), or that WSL has some different behavoiour than expected.
However, your can just alter your append command like so:
echo "source /opt/ros/kinetic/setup.sh" >> ~/.bashrc
or in your case, since the entry exists already in your ~/.bashrc, edit the line source /opt/ros/kinetic/setup.bash to source /opt/ros/kinetic/setup.sh
The packages or files were not actually downloaded from the "http://wiki.ros.org/melodic/Installation/Ubuntu". To overcome this error first open terminal
check your directory pwd. If your directory is like /home/'Your PC Name' it won't actually work.
Change the directory : Type cd /
Continue the installation process from start which mentioned in "http://wiki.ros.org/melodic/Installation/Ubuntu"
melodic can change to kinetic or other version if you wish

How to call a command without giving its full path?

I installed a text editor under /usr/share/my-editor/editor-executable.
When I want to launch the editor in terminal I have to write the complete path:
# /usr/share/my-editor/editor-executable file-to-open
I would create a command for the editor so I can simply digit:
# my-editor file-to-open
How can I do?
The reason you couldn't launch your executable is because the shell look for the command in any of the paths defined in the PATH environment variable (known paths from now).
You can check those known paths with:
echo $PATH
As you can see, /usr/bin is defined there as well as other paths.
Anyway, you can get what you want in several ways.
Note below that when I use the ~ directory, the command will be only available for the current user.
Creating an alias my-editor
This is my favourite when you want to run a command which is not found in the known paths. It would be a good idea for you too. In bash you can place the alias in ~/.bash_aliases.
echo alias my-editor=/usr/share/my-editor/my-editor-executable >> ~/.bash_aliases
Creating a link to your file in some of the known paths
It's the way you have done it and just to clarify, if you had created the link in any of the known paths, it would have worked too.
ln -s /usr/share/my-editor/my-editor-executable /usr/bin/my-editor
Defining a function with name my-editor
I think it's too much due to your needs but it's up to you if want to give it a try. It can be useful for other purposes.
You must define it in a file read by your shell. e.g. ~/.bashrc in bash. Shell files invocation.
cat >> ~/.bashrc << "EOF"
function my-editor() {
/usr/share/my-editor/my-editor-executable "$#"
}
EOF
Adding /usr/share/my-editor/ to the PATH
You can add a new path to the PATH variable. In Ubuntu, the PATH variable is generally set in /etc/environment and if you modify this file, the new path will be accesible for all users.
However, if you want to be the only one who has access to the new path, you can set it in one of the personal shell files. e.g. in bash: ~/.bashrc. Shell files invocation.
echo 'export PATH="$PATH:/usr/share/my-editor/"' >> ~/.bashrc
[bash] Entering a command into the hash table
A singular way to get the same result in bash is adding my-editor into the shell hash table. Again, you must add the command in some file read by bash (~/.bashrc).
echo 'hash -p /usr/share/my-editor/my-editor-executable my-editor' >> ~/.bashrc
Moving the executable to a known path
Finally, if you don't need the file (my-editor-executable) in his current directory anymore, you can simply move it to a known path.
mv /usr/share/my-editor/my-editor-executable /usr/bin/my-editor
I answer by myself:
I created a link to executable file under /usr/bin :
# ln -sF /usr/share/my-editor/my-editor-executable /usr/bin/my-editor
Now it is possible to run the application "my-editor" via terminal everywhere in the file system

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.

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