Go newbie: how to run goroutines shell? - go

I tried running shell-basic but nothing happens. Here is what I tried:
To run this example, download and install it with go get:
go get goroutines.com/shell-basic
which finishes silently and I see it downloaded the shell basic script but when i execute shell-basic i get:
$ shell-basic
-bash: shell-basic: command not found
did I do something wrong, or am i missing something?
what i'm interested in is running go as scripts..

go get will fetch the source and put it in your Go path, try echo $GOPATH in the shell. This is what happens if go get finishes silently.
Then you want to go to that source:
cd $GOPATH/src/goroutines.com/shell-basic
aftwards, you must run go install inside the repo. (or you can run go install /path/to/the/code.
The source will then be put in $GOPATH/bin, and be executable.
Of course none of this will work if you don't have you GOPATH set up.

I think you not set GOBIN.
You can follow:
export PATH=$PATH:$GOPATH/bin
Or, try run $GOPATH/bin/shell-basic.Use your gopath replace $GOPATH.

Related

After installing go and setting my path, I am still getting an error

After installing golang according to the instructions on the golang website, I set the path as it said to by using export PATH=$PATH:/usr/local/go/bin and whenever I use the command $HOME/go it says bash: /home/ken/go: No such file or directory
I can verify go is installed and I even reset my computer to make sure the changes took place. Does anybody know what I can do to resolve this issue? Am I missing something?
As per the instructions on the Go installation page, you do need to manually create the go folder:
cd $HOME
mkdir go
cd go
Then create your first go program: https://gobyexample.com/hello-world
And run with go run hello-world.go. Should be good ;)

Where does go get install packages?

I've been given instructions to run go get <some-remote-git-repo> which seems to succeed, but it's not clear to me where the package was installed to so I can run an executable from it.
Per https://golang.org/doc/code.html#remote it seems it will be installed in $GOPATH/bin but $GOPATH isn't defined in my shell (though the go get command seems to work fine). Go is installed via Homebrew.
I found the missing clue by running brew info go, which says:
==> Caveats
A valid GOPATH is required to use the `go get` command.
If $GOPATH is not specified, $HOME/go will be used by default:
https://golang.org/doc/code.html#GOPATH
From that I found the executable in question at $HOME/go/bin.
go env
you can get the path from GOMODCACHE
I had a similar problem which is why I found your question. However, in my case I did not have an empty GOPATH but one with multiple directories. I worked out the issue and describe it here...
If you run go get and you already have the package it says nothing (even with the -v option). This is confusing if it's not in the first directory of your GOPATH. Ie you run go get , there is no error or any message but when you check the first directory of the GOPATH (which is where the doc says it should be) you can't find it.
I eventually found it, but since I have a large GOPATH this was rather tedious.
Even if you don't have a $GOPATH variable you can see what it uses by doing go env GOPATH.
Try this to see what your path is:
echo `go env GOPATH`/bin
Using go build
Try this with main.go. In your greeter directory, run the following command:
go build
In this case, you built your greeter application into an executable file that was added to your current directory. Check this by running the ls command:
ls
./greeter

compile: version "go1.9" does not match go tool version "go1.9.1"

I am getting this error when I tried to run an example helloworld code I got onlie.
compile: version "go1.9" does not match go tool version "go1.9.1"
My computer has go1.9.1. What does the error mean and how can I fix this?
If you are installing using OSX homebrew you may need to set the $GOROOT in your .bashrc, .zshrc, etc:
export GOROOT=/usr/local/opt/go/libexec
I had the same error this morning when I updated from 1.9 -> 1.9.1 though according to several post the $GOROOT shouldn't have to be set and I had not set it until today. This may be a bug?
Edit: not a bug, for more details see answer below.
This is a mismatch between the GOROOT environment variable and the default path to your go command. One or the other needs to be changed; the one that needs to be changed depends on the specific setup on your computer. You could determine this by updating your Go to the latest version using your preferred method, running either which go (on Linux/macOS/BSD) or where go (on Windows), and then checking which of the files listed has the newer timestamp.
Linux/macOS/BSD
To change the GOROOT to match the default path of your go command, run type go and strip off the /bin/go part at the end to yield the directory path containing your Go installation. Then, add it to your .bashrc or other appropriate init file like this:
export GOROOT=/path/to/go-installation
To instead change the go command path to match your GOROOT, add this to the bottom of your init file:
export PATH="${GOROOT}/bin:${PATH}"
Windows
To change the GOROOT to match the default path of your go command, run where go take the first line of output, and strip off the \bin\go.exe part at the end. Then, go to "Edit the system environment variables" in Settings, click "Environment Variables...", find the "GOROOT" variable and edit to read the path you created earlier.
To instead change the go command path to match your GOROOT, first save the output of echo %GOROOT%\bin. Then, go to "Edit the system environment variables" in Settings, click "Environment Variables...", and find the
find the "Path" row in the bottom pane, click New, put in the path you created earlier, and finally click Move Up until it's at the top.
All
You'll need to open up a new command prompt to see the effects.
in case you are using mac with homebrew, just run:
brew cleanup
to clean all the legacy package, this fixed my problem.
In mac OS , if you downloaded and installed go package without brew, running brew update commands will cause this problem to occur
for fix this problem you can do :
brew uninstall --ignore-dependencies go
uninstalling go from brew will fix problem
This error happens when you forgot to delete previous golang install ... just delete its directory ... so identify go install location ... on linux issue
type go
typical output is
go is hashed (/usr/local/go/bin/go)
so just remove its grandparent directory ( go install dir not just the go binary )
sudo rm -rf /usr/local/go # NOTE this is not /usr/local/go/bin/go
now just install go and you'll be fine
For M1 Mac, the following steps helped me!
Check for which go from VSCode Terminal and check from system terminal.
from vscode terminal
user#mac % which go
/usr/local/go/bin/go
from my mac terminal
user#mac % which go
/opt/homebrew/bin/go
Whichever corresponds to the GOROOT shown go env, keep it and delete the other one
user#mac % go env GOROOT
/usr/local/go
in this case
rm -rf /opt/homebrew/bin/go
close and reload the vscode and terminal
For Windows delete the GOROOT System variables in the Enviroment Variables and restart the PC.
if you use VsCode, you just add this in setting.json.
"go.goroot": "/usr/local/Cellar/go/1.x.x/libexec",
For me, it's caused by GOROOT env, using gotip before, change to brew version.
# curret go env
cat "$(go env GOENV)"
# make sure this is correct
go env GOROOT
# unset GOROOT if setted before
go env -u GOROOT
you may also want to set a proper GOROOT to match the go version.
In my case, I had a scripts that look like this:
[[ -s "$HOME/.gvm/scripts/gvm" ]] && source "$HOME/.gvm/scripts/gvm"
Hanging around in my .bashrc/.zshrc file from a previous installation of go / trying to use gvm.
Removing this and restarting terminal solved it for me.
I had the same issue when I used getgo to update my Go version from 1.19 to 1.20. In my case, getgo created a .bash_profile and set its own export path w/c is not consistent with what's in my .bashrc.
#my .bash_profile;
export PATH=$PATH:/home/user/.go/bin
export PATH=$PATH:/home/user/go/bin
#my .bashrc;
export GOROOT=/usr/local/go/
export GOPATH=$HOME/go
export PATH=$PATH:$/home/user/go/bin:$GOROOT/bin:$PATH
SOLUTION:
I just replaced my export PATH in bashrc w/
export PATH=$PATH:$/home/user/.go/bin:$GOROOT/bin:$PATH
<Note the '.go' change w/c is now consistent to what's in my .bash_profile>.
So whether source is ~/.bashrc or ~/.bash_profile, it will always point to the same path for Go. Hope this helps. I'm also new to Go and Ubuntu. I know how painful it is to get these variables right on your own.
Took a simple approach(Linux), I had different versions of Go installed in my system.
$ whereis go
helped me to find the available go runnables, removed all, installed a fresh one and ensured to create a link for this new Go runnable in one of the $PATH folder to ensure below gives the correct version of what installed now.
$ go version

Golang equivalent of npm install -g

If I had a compiled Golang program that I wanted to install such that I could run it with a bash command from anywhere on my computer, how would I do that? For example, in nodejs
npm install -g express
Installs express such that I can run the command
express myapp
and express will generate a file directory for a node application called "myapp" in whatever my current directory is. Is there an equivalent command for go? I believe now with the "go install" command you have to be in the directory that contains the executable in order to run it
Thanks in advance!
Update: If you're using Go 1.16, this answer still works, but go install has changed and is now the recommended method for installing executable packages. See Karim's answer for an explanation: https://stackoverflow.com/a/68559728/10490740
Using Go >= 1.11, if your current directory is within a module-based project, or you've set GO111MODULE=on in your environment, go get will not install packages "globally". It will add them to your project's go.mod file instead.
As of Go 1.11.1, setting GO111MODULE=off works to circumvent this behavior:
GO111MODULE=off go get github.com/usr/repo
Basically, by disabling the module feature for this single command, it will install to GOPATH as expected.
Projects not using modules can still go get normally to install binaries to $GOPATH/bin.
There's a lengthy conversation and multiple issues logged about this change in behavior branching from here: golang/go - cmd/go: go get should not add a dependency to go.mod #27643.
Starting with Go >= 1.16 the recommended way to install an executable is to use
go install package#version
For example, go install github.com/fatih/gomodifytags#latest.
Executables (main packages) are installed to the directory named by the GOBIN environment variable, which defaults to $GOPATH/bin or $HOME/go/bin if the GOPATH environment variable is not set. You need to add this directory to your PATH variable to run executables globally. In my case, I've added this line to my ~/.zshrc file. (if you are using bash, add it to the ~/.bash_profile file):
export PATH="$HOME/go/bin:$PATH"
Go team published a blog post about this change, here's the explanation quote:
We used to recommend go get -u program to install an executable, but this use caused too much confusion with the meaning of go get for adding or changing module version requirements in go.mod.
Refer to go install documentation for more details
As far as I know, there is no direct equivalent to npm install -g. The closest equivalent would not be go install, but go get. From the help page (go help get):
usage: go get [-d] [-f] [-fix] [-insecure] [-t] [-u] [build flags] [packages]
Get downloads and installs the packages named by the import paths,
along with their dependencies.
By default, go get installs binaries to $GOPATH/bin, so the easiest way to make those binaries callable from everywhere is to add that directory to your $PATH.
For this, put the following line into your .bashrc (or .zshrc, depending on which shell you're using):
export PATH="$PATH:$GOPATH/bin"
Alternatively, you could also copy or link the executables to /usr/local/bin:
ln -s $GOPATH/bin/some-binary /usr/local/bin/some-binary
Short solution for Linux users:
Use the go get command as usual
Add the following lines to .bashrc:
# This is the default GOPATH, you should confirm with the 'go env' command
export GOPATH=$HOME/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
Restart terminal or source it. Installed binaries will be available globally.
For Go v1.8+
go install package_name#latest
Caveat: this answer is outdated following the 2020 deprecation of go get. The solution presented here won't work with newer Go runtime installs.
The closest analogue of this in Go would be go get. By default, it will fetch a Go package from a supplied repository URL, and requires a $GOPATH variable to be set in your shell so that Go knows where to store the packages (and subsequently where to find them when compiling code depending on go get-ted packages).
Example syntax:
$ go get github.com/user/repo
The behaviour supplied by npm's -g flag is default, and packages installed using go get are normally available globally.
See go get --help for more information about the command.
As mentioned by #helmbert, adding your $GOPATH to your $PATH is useful if you're installing standalone packages.
if you are using zsh :
first: install your package using :
go install package#version
then , you edit your .zshrc file
nano ~/.zshrc
Add this line to the end of .zshrc file :
export PATH="$HOME/go/bin:$PATH"
last but not least :
source ~/.zshrc
then open a new terminal and execute your command :)
TL;DR at the bottom. I'm going to walk you through how I came to this conclusion, and why the more obvious solutions don't work.
Upon seeing this question, I thought "If I could set root's GOPATH=/usr, it would install things in /usr/bin/ and /usr/src!"
So I tried the obvious thing:
Add GOPATH=/usr to root's .bashrc.
And it worked!
Sort of.
Not really.
Turns out, sudo doesn't execute root's .bashrc. For "security" or something like that.
Do env_set or something in /etc/sudoers
Turns out, /etc/sudoers can only remove environment variables. There's no env_set directive.
(As far as I can find)
Dig through man sudoers.
Where does sudo get it's default set of environment variables from?
Well, the first one in the list is /etc/environment, so that's the one I used.
sudo echo "GOPATH=/usr" >> /etc/environment
sudo go get <repo>
Binaries will be put in /usr/bin, and sources will be put in /usr/src.
Running go as non-root will use GOPATH the "normal" way.
If you don't have go installed, you may use the gobinaries. it builds an on-demand binary of the project from github repo.
The command to install the go package would be:
curl -sf https://gobinaries.com/rakyll/hey | sh

Error "command not found" after installing go-eval

I'm trying to run Go in an interactive mode.
I want to use go-eval for that, I followed their README instructions:
I ran go get github.com/sbinet/go-eval/ successfully
I ran go-eval which resulted in -bash: go-eval: command not found
Some more information:
echo $PATH returns: /usr/local/go/bin:...
echo $GOPATH returns: $HOME/golang
running whereis go-eval returns no output
running go install go-eval returns:
can't load package: package go-eval: cannot find package "go-eval" in any of:
/usr/local/go/src/go-eval (from $GOROOT)
$HOME/golang/src/go-eval (from $GOPATH)
You'll need to add GOPATH/bin to PATH.
PATH="$GOPATH/bin:$PATH"
Update [Go 1.8 and above]: GOPATH will default to $HOME/go. The above will not work if GOPATH is not explicitly set.
To set both, add this to your .profile file:
export GOPATH="$HOME/go"
PATH="$GOPATH/bin:$PATH"
Ran into this issue while using export PATH="~/go/bin:$PATH".
Seems the ~ was causing problems and changing to the full path worked.
Try something like this instead, which won't use a tilde:
export PATH="$HOME/go/bin:$PATH"
Is the binary go-eval in $GOPATH/bin? Are you running the command with $GOPATH/bin/ as your working directory? If not, thats likely the problem.
go get & go install installs go binaries (if any) in $GOPATH/bin
Check $GOPATH/bin for the go-eval binary. If its there, try running it from $GOPATH/bin with ./go-eval. If that works, you're good.
In future, if you wish to run go binaries found in $GOPATH/bin from anywhere in your shell, add the following to your .bashrc or profile:
export PATH=$PATH:$GOPATH/bin
Then restart your terminal or run . ~/.bashrc or . /etc/profile
When running go install go-eval I get:
can't load package: package go-eval: cannot find package "go-eval" in any of:
/usr/local/go/src/go-eval (from $GOROOT)
$HOME/golang/src/go-eval (from $GOPATH)
You get the above error because go-eval is not in $HOME/golang/src/go-eval. Running go get github.com/sbinet/go-eval/ will download the source to $GOPATH/src/github/sbinet/go-eval/. If you want to run go install go-eval, you have to specify the package name relevant to its position in the directory hierarchy in $GOPATH/src.
e.g.
go install github/sbinet/go-eval
I'd like to add this in addition to the answers given.
As a helpful tip, uou can always test your commands with the which command.
Such as: which go
If the command is not found, you know you have a PATH problem you need to address first.
Then you can focus on finding the command with the find command.
Such as: find / -name "go" -print 2>/dev/null
The first slash is the directory to start the search, the argument to the -name is the command you're looking for and the -print gets a good results look. the 2>/dev/null sends results of directories that are not accessible to neverland (null) so that you do not need to see a bunch of errors.
Using this process helps you quickly find the command in question and then you can add it to your PATH env variable and it becomes accessible as stated in the other answers.
All above answers are self explaining. Over and above those I would like to add that by default you can access only those commands from terminal without path to binary whose bin folder is added to the environment variable, be it linux, mac or windows.
Else you will have to specify the path to bin folder of that software followed by the binary name. For instance in your case <path_to_bin_folder>/go-eval.
This is the most common reason that you are not able to execute that command directly from the command line. Please remember this and try this before searching for answers online because this will most probably solve your issue. All you have to know is the installation path.
So, write the following into the rc or profile file for your terminal and save, example for zsh it is ~/.zshrc, for bash it is ~/.bash_profile or ~/.bash_rc.
export GOPATH="$HOME/go"
export PATH=$PATH:$GOPATH/bin
Now although the file is saved but the changes will not reflect immediately. You have to source the profile file as mentioned above. For this type source ~/.zshrc. You should now be able to run the command directly from command line now. Even if the problem still persists try quit the terminal session and logging off and then logging in.
In case you want to add path to bin folder for other packages, you can append it to the $PATH environment variable using :. So for example if you want to add path to java binary as well, then just do
export PATH=$PATH:$JAVA_HOME/bin
Also it is a good practice to define the path to root folder of a package in its separate environment variable(example $GOPATH="$HOME/go"). In case if the installation path changes in future then you'll just have to update the environment variable related to that binary (example just update, $GOPATH="newpath") and your command will work as previously, since the change in $GOPATH will reflect in $PATH.
add those line in to ~/.zshrc
export GOPATH="$HOME/go"
export PATH=$PATH:$GOPATH/bin
run source ~/.zshrc

Resources