How does "which" work in osx? - macos

I'm trying to install a linter for sublime tex in OSX. It cannot be found in sublime. According to the docs, this is likely because the PATH is wrong. It says I should try this:
hash -r
which linter
but replace linter with the "linter executable". I tried
which standard
which sublimeLinter-contrib-standard
which fooBarBaz
but neither of them returns anything. Do I need to execute this in a particluar directory or is something else wrong?

which uses the value of PATH that it inherits. The fact that which returns nothing confirms that you need to add the appropriate directory to your PATH.

which command looks through the directories defined in your shell’s PATH variable, as well as any aliases you have defined in your ~/.bash_profile file, to find the location of the command given as an argument. This is useful when you want to find out exactly which version of a command is being used. Here’s an example:
$ which ls
/bin/ls
This tells you that when you use the ls command, it is /bin/ls that is run. This command will also tell you if a specific command is a shell builtin.

Related

How do I run ESLint from a saved Bash variable?

I am setting up a project initialization script and a git pre-commit hook for work on a project. We have the scripts I want to run for linting not in the root directory but in a sub-directory and I would like to keep it that way.
What I want to be able to do is to set the full relative path to the binary executables for eslint and phpcs to bash variables then be able to run them. I also want to be able to execute the composer.phar binary from the bash variables.
So here is what I did.
# Set tool paths
PHPCS_PATH=`./wp-content/themes/our-theme/vendor/bin/phpcs`
PHPCBF_PATH=`./wp-content/themes/our-theme/vendor/bin/phpcbf`
ESLINT_PATH=`./wp-content/themes/our-theme/node_modules/.bin/eslint`
SASSLINT_PATH=`./wp-content/themes/our-theme/node_modules/.bin/sass-lint`
COMPOSER_PATH=`./wp-content/themes/our-theme/composer.phar`
I was trying to test these paths locally from the project root directory and I keep getting errors.
I copy and paste one of those lines into my terminal, hit enter, then do one of the following:
${ESLINT_PATH} and command ${ESLINT_PATH} and "${ESLINT_PATH}" and $ESLINT_PATH all yield me...
zsh: command too long: eslint [options] file.js [file.js] [dir]\n\nBasic configuration...
eval "${ESLINT_PATH}" and eval $ESLINT_PATH and eval "$ESLINT_PATH" all yield me...
zsh: no matches found: [options]
zsh: command not found: Basic
zsh: command not found: --no-eslintrc
zsh: command not found: -c,
zsh: no matches found: [String]
Am I losing my mind? How in the world do I make the path executable? If I take the contents of the path and run it, it works just fine.
Example: ./wp-content/themes/swmaster/node_modules/.bin/eslint actually tells me to specify a path.
What am I doing wrong here?
Looks like your issue is in these assignments:
# Set tool paths
PHPCS_PATH=`./wp-content/themes/our-theme/vendor/bin/phpcs`
PHPCBF_PATH=`./wp-content/themes/our-theme/vendor/bin/phpcbf`
ESLINT_PATH=`./wp-content/themes/our-theme/node_modules/.bin/eslint`
SASSLINT_PATH=`./wp-content/themes/our-theme/node_modules/.bin/sass-lint`
COMPOSER_PATH=`./wp-content/themes/our-theme/composer.phar`
Those back-ticks are command substitutions. An easier to read way of writing this is would be:
PHPCS_PATH=$(./wp-content/themes/our-theme/vendor/bin/phpcs)
...
I don't think that is what you really want. A command substitution actually executes what is inside and is substituted by whatever goes to stdout. I think you were actually trying to do string assignments. This can be accomplished by simply removing the back-ticks because there are no spaces in the paths. But it is a good habit to get into to just double quote them anyway. Try this:
# Set tool paths
PHPCS_PATH="./wp-content/themes/our-theme/vendor/bin/phpcs"
PHPCBF_PATH="./wp-content/themes/our-theme/vendor/bin/phpcbf"
ESLINT_PATH="./wp-content/themes/our-theme/node_modules/.bin/eslint"
SASSLINT_PATH="./wp-content/themes/our-theme/node_modules/.bin/sass-lint"
COMPOSER_PATH="./wp-content/themes/our-theme/composer.phar"
Another method to solve your issue would be to add these directories to your PATH variable. For example, if you set your PATH to include the bin directory for phpcs and phpcbf, you would be able to execute those programs without specifying a full (or relative in this situation) path:
export PATH=$PATH:./wp-content/themes/our-theme/vendor/bin
# or export PATH=$PATH:/full/path/to/wp-content/themes/our-theme/vendor/bin
# Now you can just run the line below without a path...
phpcs
This morning I found what I was looking for in this gist: https://gist.github.com/rashtay/328da46a99a9d7c746636df1cf769675#file-pre-commit-eslint
My solution is now:
# Set tool paths
PHPCS="$(git rev-parse --show-toplevel)/wp-content/themes/our-theme/vendor/bin/phpcs"
PHPCBF="$(git rev-parse --show-toplevel)/wp-content/themes/our-theme/vendor/bin/phpcbf"
ESLINT="$(git rev-parse --show-toplevel)/wp-content/themes/our-theme/node_modules/.bin/eslint"
SASSLINT="$(git rev-parse --show-toplevel)/wp-content/themes/our-theme/node_modules/.bin/sass-lint"
This works from any directory in the repo because it ties to the repo base path. It is dynamic in that way.

Where does the mac shell (terminal) look for the instructions for commands such as ls, cd, etc

I believe the title says it all, I know that some of these commands can be found in places like /usr/bin but I'd like to know the details of all the folders than can be found in, or what the process of locating them is.
If you want to know where a specific command is being found, enter:
which command
For example:
which ls
And as CJK mentioned, echo $PATH shows you all the directories that are being searched (in the order they are searched) for commands.
A few commands, such as cd, are built into the shell, and don't need to be found anywhere, although there might be a program implementation as well. The command "type", as in:
type -a cd
...will specifically tell you that a command is built in.
More info here: https://unix.stackexchange.com/questions/116955/where-is-cd-located
There is no such thing as a mac shell, and the correct answer depends on the shell which you are actually using. But if you just used the default settings, your shell will be bash, and in this case, the type command will do the trick, for example:
type ls
However, if you really have bash, you need to be careful with aliases: If you have an alias foo and an executable foo,
type foo
will report the alias, but inside a non-interactive context (shell script), aliases are not expanded, and the executable foo is used.
If you follow the advice given in the answer from #kshetline, i.e. to use
type -a foo
you find all places where foo would be found, in search order. For instance, in my bash
type -a ls
outputs
ls is aliased to `ls --color=auto'
ls is /usr/bin/ls

Terminal commands can not be found OSX

A majority of terminal commands don't work, for example .
ls
sudo
vi
with the error -bash: ls: command not found my path is echo $PATH
“/Users/username/usr/local/bin I get the feeling that “ should not be there but not sure how edit it.
What should the path be and how do I get the path to stay the same?
You need to add more paths to your $PATH variable. Try running whereis ls and check where is the binary of the command.
You can add more paths like this: export PATH=$PATH:NEW_PATH
I had a similar experience recently where a lot of my terminal commands were not being found despite being clearly saved in my bash_profile. After lengthy process of elimination I realised that the issue was caused when I tried to export a new path. The error that I had made was putting a space in the command. So I had to change
export SOMETHING = /path/to/something.apk to
export SOMETHING=/path/to/something.apk
So I would recommend you check all your path declarations to ensure you don't have any white spaces. Also don't forget to source your bash_profile or what ever type of command line shell you use.

Ubuntu Shellscript Path Variable

I have the following Shellscript that I call from my crontab, which works fine until it calls php code that involves shell commands like wget or find.
#!/bin/sh
PATH=/opt/server/php/bin:/usr/bin/wget:/bin/egrep:/usr/bin/find
cd /opt/server/apache2/htdocs/webapp/
php oil refine job:handler
For each Command I did a which command to look up the path, then I added it to the Path Variable. Nevertheless it does not find the commands and I get messages like these:
sh: wget: not found
sh: find: not found
How would I fix this? I know that this is a common problem, but I didn't find a good explanation for this here on stackoverflow. Also: I know that calling the script from bash versus crontab might result in different enviroment settings, but eitherway I get these Errors.
Good sir, the PATH is a string that describes the directories that contain executables, not the executables themselves.
Perhaps use something like this
PATH=/opt/server/php/bin:/usr/bin:/bin

Using a #! comment in ruby running in Ubuntu

I am new to programming and am trying to follow an example which uses #! comment in ruby.
I am consistently get the message:
bash: matz.rb: command not found
I am using this comment:
#! /usr/bin/env ruby
I have tried it with and without the space after ! as well as with and without the env.
when I use the
$ which ruby
ruby is in: /usr/bin/ruby
I have also gone into the operating system and changed the permissions on the file matz.rb to rwx for all users w/ no effect. Am I doing something wrong or do I have my system set up incorrectly?
The /usr/bin/env part is fine. You need to give bash the path to matz.rb when you run it. If you're in the directory with matz.rb, type "./matz.rb". The directory "." means the current directory - bash doesn't look there by default when running programs (like Windows does).
The env program (/usr/bin/env) searches the executable search path - the PATH environment variable - for the ruby program as if you typed it at the command prompt, and runs that program. The shebang comment doesn't do this. If you want to give your script to other people who might not have ruby installed in the same place as you, then you should use the "#!/usr/bin/env ruby" comment so that it will work as long as they can run ruby by typing "ruby".
If you're in the same directory as the matz.rb file, be sure to run it as
$ ./matz.rb
and not just
$ matz.rb
Here's a shell session demonstrating this working:
$ ls -la m*
-rwxr-xr-x 1 gareth gareth 32 8 Jan 08:46 matz.rb
$ cat matz.rb
#!/usr/bin/env ruby
puts "Matz"
$ matz.rb
-bash: matz.rb: command not found
$ ./matz.rb
Matz
Your file wasn't created on Windows was it? If it has \r\n line endings, that will upset bash. You can open it with Vim and check:
vi matz.rb
:set ff=unix
:wq
If when you tab-complete the "ff=" part it says dos, then it has the wrong file format. Alternatively, run dos2unix and try to run the file again:
apt-get install sysutils
dos2unix matz.rb
It sounds like you're on a Unix/Linux system and just typing matz.rb on the command line. If you're trying to execute a command in the current directory, you need to call it like ./matz.rb. The "./" tells it to look in the current directory rather than just /usr/bin and friends.
I failed to see any answer indicating you to change the executable mode of the file, so you might wanna try and do
chmod +x matz.rb
before you go and try doing
./matz.rb
Also it might be better not to attach a .rb extension to the file, such is the case for normal ruby / rails scripts e.g. script/generate, script/console etc.
You can use the 'shebang' line with either:
#!/usr/bin/ruby
#!/usr/bin/env ruby
But the script needs to be executable (you indicated it is) and in your shell $PATH.
echo $PATH
Put the script in one of those directories, or modify your path, otherwise specify the full path to it, for example:
export PATH=$PATH:/home/user/bin
or one of these:
./matz.rb
/home/user/bin/matz.rb
You can also run the Ruby interpreter passing the script filename as an argument, and it will be executed. This is particularly useful if you have another version of Ruby installed on your system (say, for testing, like Ruby Enterprise Edition, REE):
/usr/bin/ruby matz.rb
/opt/ree/bin/ruby matz.rb
Have you tried the ShaBang as following to directly point to ruby?
#! /usr/bin/ruby
Then you call the script from the commandline as
./matz.rb
Under Unix/Linux systems the dot in front of a command to search for the command in the current directory. If you give a path like /usr/bin/ruby, it will search in the current directory for a directory called usr...
A command without a dot/ in front is searched in locations specified by the path variable of the environment.
A command with a / on the beginning is searched exactly from root following the specified path.
Inside your ShaBang, you want to specify the exact path to the interpreter so "/usr/bin/ruby" is the correct one. On the commandline, where you want your script to be executed, you need to call the script with "./matz.rb" otherwise the bash will search a command like /usr/bin/matz.rb what leads to your errormessage.

Resources