How can I make in-container tools like drush or typo3cms usable if they're not in the standard DDEV PATH? - ddev

I have a nonstandard composer layout, so some of my tools are in docroot/vendor/bin instead of the expected vendor/bin, so they're not in the $PATH inside the web container, and tools like ddev drush or ddev typo3cms don't work right because they can't find the tool. What can I do?

There are at least a couple of ways to solve this problem. The simplest is probably to just symlink your tool(s) into /usr/local/bin where they will easily be found. There are at least a couple of ways to do this. (Note that for most projects, the best long-term solution is to use a standard composer layout with the composer.json in the project root and the vendor directory in the project root, but we all know we can't fix everything. But vendor/bin is always in the $PATH.. so that's the usual easiest way to do this.)
Symlink in a post-start hook: We can add a post-start hook to symlink typo3cms (for example) into /usr/local/bin and ddev typo3cms will find the tool. Add something like this to .ddev/config.yaml
hooks:
post-start:
- exec: ln -s /var/www/html/docroot/vendor/bin/typo3cms /usr/local/bin
Symlink in a .ddev/web-build/Dockerfile: To add a symlink to drush, for example, in a nonstandard location and make ddev drush work, add this file as .ddev/web-build/Dockerfile:
ARG BASE_IMAGE
FROM $BASE_IMAGE
RUN ln -s /var/www/html/docroot/vendor/bin/drush /usr/local/bin
I'm sure there are many other ways to do this, by manipulating the $PATH inside the container (by adding .bashrc inside the homeadditions feature)

Related

How to run commands in any directory in macOS Terminal?

I have some Unix Executable Files in a paticular directory, say /Users/myUserName/Developer/sdcc/bin/.
I find I must get into this directory using cd before running that command, or it complains zsh: command not found.
But it can be of inconvenience. I know the commands can be used in any directory if it's installed by Homebrew. How can I do the same thing?
Homebrew usually links the necessary executables to /usr/local/bin directory, which should be in your $PATH. Thus, when you execute a command like sdcc, your shell will seek through the $PATH directories, and when it looks at /usr/local/bin, it will find sdcc, follow the link and execute it.
Some packages do not perform this linking, which means you cannot execute them without knowing where they are. You can ask Homebrew to tell you where a package is installed: brew --prefix <formula>, where <formula> is the package name (e.g. brew --prefix sdcc). The executable files will normally be under a bin subdirectory. For example, brew --prefix sdcc would likely tell you something like /usr/local/opt/sdcc; then you can invoke sdcc using /usr/local/opt/sdcc/bin/sdcc, without having to cd there. You could also put /usr/local/opt/sdcc/bin into your $PATH directly, though I do not recommend it. Another alternative is to create your own bin (mine is in $HOME/.local/bin), put it in $PATH, and link there (ln -s <source> $HOME/.local/bin/) any executables you wish your shell to easily find.
However, with Homebrew packages, I strongly suggest you do not try to imitate Homebrew by yourself, by installing things in Homebrew's domain. You can confuse Homebrew and create problems. Instead, let Homebrew do it.
If you need to install a package on a different OS than the one you are downloading at, you may need to first find out the bottle tag for the target (installation) computer. For example, for Big Sur, it is big_sur. See brew info --json <formula>, under bottle.stable.files you should find the bottle tags. Use --bottle-tag <tag> in step 1 and 2 to select the right OS.
Use brew fetch --deps <formula> to download (but not install) a package, including its dependencies. If you use the --verbose flag, Homebrew will tell you where it downloaded each of the files.
If you haven't used --verbose and still want to know where the downloaded files are: brew deps <formula> will list all the packages it depends on. If a package needs to be compiled, you may need to also use the --include-build option. brew --cache <formula> will show you where a package file is downloaded.
If you need to copy a package file to another computer, you should find out where the Homebrew would expect to find it: use brew --cache --force-bottle <formula> on the target computer, and copy the package file there. Don't forget to do that for each dependency package as well.
After that, brew install <formula> will install from cache.
The only part of this process that needs internet connection is the first step, brew fetch.
For Unix (which MacOS is a family member) and Unix-like (eg. Linux) operating systems the thing that controls this feature is the PATH environment variable.
To know which folders allow you to run programs without cd-ing into them or prefix ./ to your program name you can print out the value of PATH:
echo $PATH
On my machine it prints out:
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Users/slebetman/bin:/opt/homebrew/bin
There are two things to notice:
The string is a list of folder paths separated by :
There is a path listed as /opt/homebrew. Presumably this is where homebrew installs command-line programs.
Copying your program/script into any of the folders listed in PATH will allow you to use it like any installed/built-in command. This is what it means to install command-line programs on Unix. It's that simple.
There is another thing to notice: I have in my PATH the folder /Users/slebetman/bin. This is my own personal standard - probably not invented by me but one I adopted from my college days - for installing my own programs. I have this ~/bin folder on all my Unix and Linux machines. It is where I keep my personal collection of scripts that I've written or collected over a lifetime.
Having a personal ~/bin folder is nice because you don't need sudo permission to write to it. Also, if you buy a new PC/Mac you can just copy the folder to your new machine and all the scripts you've gotten used to now exist on the new machine. Better yet, you can manage the folder with git and sync it with github/gitlab/bitbucket to make it easy to keep all your computers updated.
Since PATH is a standard environment variable you can easily modify it to add your own folder. Just add the following in your .profile or .zshrc or .bashrc file (depending on your shell) to add your own bin folder to PATH:
export PATH=$PATH:$HOME/bin
The command above simply says add $HOME/bin to PATH and export it so that other programs will inherit the new PATH variable.
In your case you can even do something like:
export PATH=$PATH:/path/to/your/sdcc/bin
to have all your SDCC commands work like regular commands.

I get "laravel: command not found" on Ubuntu 20.04

I did a fresh install of Ubuntu 20.04 LTS (Focal Fossa), installed Apache, PHP, MySQL and PHP Composer seemingly without issue. However, I still cannot get laravel -V to give me a version number.
I have looked at a multitude of YouTube videos and tried my interpretation of the recommendations found here on Stack Overflow. How can I fix it?
Here's the output on my shell $PATH.
You must add PHP Composer binaries folder to your $PATH if you'd like to call the binaries globally.
A) Make sure you have the latest Laravel installer:
composer global require laravel/installer
B) Add composer bin folder to your $PATH:
Edit your .bashrc file: gedit $HOME/.bashrc
Add the following line: export PATH="$PATH:$HOME/.config/composer/vendor/bin"
C) Use the source command to force Ubuntu to reload your .bashrc file:
source $HOME/.bashrc
D) Try to output Laravel installer's version:
laravel -V
Additional explanations as requested:
To execute a command from the Linux terminal, you need to tell Linux where the program is located.
For example, you could have launched Laravel installer using the full path: $HOME/.config/composer/vendor/bin/laravel -V
But instead, you wanted to be able to call the laravel -V command directly because you don't want to type the full path every time.
Since you are on Ubuntu, the default shell program is Bash. You need to tell Bash where to look when you type a command. In this case, you want Bash to look in the $HOME/.config/composer/vendor/bin/ folder.
The configuration file for Bash is a hidden file called .bashrc located in the user home folder. Bash stores the list of special folders in a variable called $PATH. To add a new folder, we simply added it to the $PATH variable.
If you type echo $PATH in your terminal, Bash will output the content of the $PATH variable and you will see a list of folders.
Now you may ask: "Why did I have to do this? I usually don't have to mess with my Bash configuration". Yes, this is because you usually install Ubuntu packages and they are configured to work out of the box. In this case, you installed a composer package in your home directory and it's therefore up to you to configure it the way you want.
You may need to do source $HOME/.bashrc every time you open u a new terminal windows and then do laravel -v

need to manually create symlinks every time i install something

For example, I'm trying to install pipenv using the following commands:
$ pip3 install --user pipenv
$ cd ~/Documents/myproject
$ pipenv install requests
zsh: command not found: pipenv
It seems that the issue can be resolved if I run sudo ln -s ~/.local/bin/pipenv /usr/bin. Is this a safe thing to do? I've also been having this issue with several other packages, like tensorboard and xflux. Is there something wrong with my system that makes it such that I need to manually create a symlink every time? How can I change things so that packages can install normally without me having to do this every time?
The problem you are having is that the tools you are installing are being installed in non-standard locations and are not being included in your PATH. One way to resolve this would be to include the paths in your PATH environment variable. In order for these programs to be in your path every time you login, do this (assuming you are using zsh as your shell):
1) Open ~/.zshrc using vim or any other editor:
vim ~/.zshrc
2) Append the following to this file:
export PATH=$PATH:/path/to/dir/containing/pipenv
Remember to replace /path/to/dir/containing/pipenv with the appropriate path.
3) Source your ~/.zshrc so that the path is included in your current session:
source ~/.zshrc
4) Now everytime you login, the paths should be available in your environment and you won't need to create symlinks.

npm command not found after restart

The npm command keeps becoming unrecognised after a computer restart:
-bash: npm: command not found
The node command still works fine, it's just npm that's not working. I have to reinstall Node.js from the main site to get it working again.
~/bin is added to my $PATH in my .bash_profile with:
export PATH="$HOME/bin:$PATH"
Edit: I'm also using the full mathiasbynens/dotfiles which manages its own version, I wonder if there's a conflict here.
According to nvm readme file, try to run this once:
nvm alias default stable
This will set a default Node version to be used in any new shell.
I have no explanation, but a few pointers:
As #LaurentPerrin states, node (via its official installer package) installs to /usr/local/bin.
(Why do you mention ~/bin?)
Note that different rules apply if you use user-level installs via node.js version manager nvm, in which case [symlinks to] executables are placed in ~/.nvm/v{version}/bin
Thus, the node executable should be /usr/local/bin/node.
Is this (only) what you see when you run which -a node?
The node executable is placed directly in /usr/local/bin, whereas npm is merely a symlink that points to /usr/local/lib/node_modules/npm/bin/npm-cli.js, which is an executable node script with shebang line #!/usr/bin/env node.
When you run
ls -l /usr/local/bin/npm
you should see something like
lrwxr-xr-x 1 root wheel 38 Dec 13 11:52 /usr/local/bin/npm -> \
../lib/node_modules/npm/bin/npm-cli.js
See if the symlink exists and points to the right file.
If that still doesn't work, try to invoke npm-cli.js directly and see what happens (this should show npm's command-line help):
/usr/local/lib/node_modules/npm/bin/npm-cli.js help
On OSX, node is installed to /usr/local/bin, which needs to be in your path. Edit /edit/paths as root (sudo nano /etc/paths) and make sure it is on the first line. It should look like this:
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
Then you can force bash to refresh paths by running: source /etc/profile.
I was having the same problem (on OSX). Not sure if this is the solution for you, but I ended up finding npm here:
.nvm/v0.10.22/bin
or, based on your version
.nvm/v0.10.21/bin
Then I just printed my working directory and added that to my path. So for me, when I opened terminal:
cd .nvm/v0.10.22/bin
pwd
>> /path/to/.nvm/v0.10.22/bin
Hope that helps.
I use nvm to install node.js. I solve it by adding $HOME/.nvm/v0.10.25/bin to $PATH. So the problem is that the path can not be found.
I have the same problem. My solution is use sudo .... My guess this is because of the permission problem.

install command in makefile

Iam getting some error while installing executable in /usr/local/bin thru makefile:
install -m 755 my_execble /usr/local/bin
install: cannot create regular file /usr/local/bin/my_execble: Permission denied
If use sudo before 'install' command ..
then it will work .. but is there other way of installing without using sudo?
The OP ask long time ago, but I will guess it can be useful for others.
Since your make install command try to install files in directory requiring root privileges (ex: /usr/local/bin) you can either:
Become root before launching your command (as you stated in your description: using sudo for example)
OR
Install it in another directory that do not require specific privilege. For this purpose you can use a specific parameter named 'DESTDIR' that is usually supported in makefile, so that your command looks like:
make DESTDIR=/home/myuser/my_dest_dir install
This is named Staged Installs.
You can either tweak the Makefile (or use a configure script) to have it install the program in your home directory... or become root.

Resources