How to Recreate Brew Aliasing, Without Brew? - bash

Due to a security update in my organisation, I can no longer use brew to tap into my organisation's repo to install a package. I can, however, manually download the .jar files that brew was installing.
So previously I did:
brew tap <repo>
brew install <package>
<package> # Run the package from anywhere
And I could run the package from anywhere, just by typing in terminal. Easy peasy.
Normally Brew installs in usr/local/Cellar/<package>/some/internal/structure/<package.exe>. But somewhere along the way it does something with aliases and symlinks and $PATH [which I am confused by] so that I can run the given package from /usr/local/bin, which is in my $PATH, by just typing <package> anywhere in terminal.
I am trying to recreate this behaviour. I was able to manually download the jar files and put them in a folder /usr/local/bin/<package>. And if I run java -jar /usr/local/bin/<package>/<package.exe> then everything runs fine.
How do I get it so that I can run <package> from anywhere in terminal, like with Brew? Also, just to be 100% clear, I want to choose the alias; I want to be able to type "abc" to run the jar files.

/usr/local/bin/ is likely in your PATH variable already. If you want to check, print it to the terminal with echo "$PATH". If it isn't, you can pick one of the other directories in there or add it to. If you want to add that directory to your PATH variable, you want to add this to the relevant dot file (likely ~/.bashrc):
export PATH="/usr/local/bin:$PATH"
PATH is a colon separated list of directories where your system will look for executables.
Now, you can just write a short script to run java for you. For example, if we have a jar file called foo.jar, you could make a short script that runs java with the full path of foo.jar like this:
/usr/local/bin/foo:
#!/bin/bash
java -jar '/path/to/foo.jar' "$#"
sneaky edit: Make sure you give this file executable permissions:
chmod +x /usr/local/bin/foo
Now, on the terminal, if I run foo without a full path, it will run this script.
The "$#" is just going to pass any arguments you sent to this script along into the java program.
This isn't the only option to achieve this. You mentioned aliases as well. You could write an alias to your .bashrc that does the same thing:
alias foo='java -jar "path/to/foo.jar"'
A symlink wouldn't really be the best option here. This would be okay if your jar file was not in the PATH and you wanted it there. BUT, the PATH variable is really only for files that can be executed directly. As you already know, jar files cannot.

Related

Installing without package manager, why does executable binary fail with "command not found" unless I make the commands start with "./"?

I'm learning to use GNU/Linux and I want to know how to install programs that cannot be installed with the package manager.
I downloaded the tarball with the Linux 64-bit Binaries (including one called "haxelib"), extracted it, changed directory in the terminal to their location (~/Downloads/things/haxe_20201231082044_5e33a78aa/), and used chmod to make them executable.
If I try a command such as haxelib list, then the terminal returns
haxelib: command not found
If I try ./haxelib list (the same command but with ./ at the start) instead, then the command works as expected.
Why can't I use it without the ./? Programs installed with the package manager can be used without the ./.
Edit: I should probably also ask: where should I put the files from the tarball? Should they all go together in the same place? I have a feeling that a folder named "things" in my Downloads folder is not the best place for them.

Set executable permission on script installed with Homebrew

I wrote my first tap, so I'm still not sure how it works. I wrote this small formula:
class Konversation < Formula
desc "Konversation is a tool to generate rich and diversified responses to the user of a voice application."
homepage "https://github.com/rewe-digital-incubator/Konversation/"
url "https://github.com/rewe-digital-incubator/Konversation/releases/download/1.0.0/konversation-cli.jar"
sha256 "6123d126278faae2419f5de00411a1b67ae57e0cf2265a5d484ed6f9786baaca"
def install
prefix.install "#{buildpath}/konversation-cli.jar"
File.write("#{buildpath}/konversation", "java -jar #{prefix}/konversation-cli.jar $#")
bin.install "#{buildpath}/konversation"
system "chmod", "+x", "#{bin}/konversation"
end
end
However I cannot run my tool since the "konversation" executable has no x permission. I tried to fix that with a system chmod, however I see that my x flag is removed after the installation by brew as some kind of cleanup:
==> Cleaning
Fixing /home/linuxbrew/.linuxbrew/opt/konversation/bin/konversation permissions from 777 to 444
How can I set the file permissions correctly?
Please note that I don't want to host the shell script itself somewhere, since I see no advance in packaging the shell script and the jar file in another zip file for destitution.
If you want to try it yourself try this command:
brew install rekire/packages/konversation
Shell scripts need to have a shebang line, otherwise the postinstall cleaner will set its permissions as though it were not an executable. In this specific case, I suggest:
use bin.write_jar_script instead -- this will set up the correct environment for JAR scripts
install .jars to libexec instead of prefix -- to avoid polluting the prefix with unnecessary files.
Example formula from Homebrew/homebrew-core

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

configure command not found cygwin

This question has been asked many time but I am not able to resolve the problem from them so I am asking
I had installed Cygwin a few days ago.I tried using ./configure command but it says
-bash: ./configure: No such file or directory
I tried using
where configure
but I got the output
INFO: Could not find files for the given pattern(s).
then I tried grep configureand I got this output
/etc/bash_completion.d/configure
/usr/i686-pc-cygwin/sys-root/usr/share/libtool/libltdl/configure
/usr/share/ELFIO/configure
/usr/share/libtool/libltdl/configure
I tried to export the path and then run the ./configure but it also didn't worked.
I find no executable file named as configure in my cygwin bin directory.
Does it mean that I have to add configure file manually?How can I correct it?
NOTE :- I had also tried sh configure but it also didn't worked
If a software project is set up to be built using autoconf, that tool generates a script canonically called configure. It queries the system for various parameters that are subsequently used in the build, and is specific to the software package to be built. Different software projects have different configure scripts. They are all called configure, but their contents are not the same.
So, to actually build such a software project once that script was set up (usually done by the maintainers when packaging the source tarball for distribution), you call:
tar xzf <tarball>.gz # or xjf <tarball>.bz2 or whatever
cd <sourcedir> # the one you just untarred
./configure
make
make install
Note the prefix ./, which means "located in this directory" (i.e. the top directory of that project's source tree).
Actually, the better procedure is the so-called "out-of-tree build", when you set up a different directory for the binaries to be built in, so the source tree remains unmodified:
tar xzf <tarball>.gz # or xjf <tarball>.bz2 or whatever
mkdir builddir
cd builddir
../<sourcedir>/configure
make
make install
So, there is supposed to be no configure executable in your PATH, you are supposed to call the script of that name from the source tree you are trying to build from.
If I correctly understood...
Configure is not an application that should be installed on your system, but script that should be delivered with source code to prepare for make command. File named configure should be in the main directory of source code.
I understand that this is an old question. However many might find this solution helpful.
Normally we use the make command to compile a downloaded source in cygwin. In many cases it contains a autogen.sh file. Running that file with
bash autogen.sh
will in many case solve the problem. At least it solved my issue and i could then use the make command

Resources