How can I prevent finding executable on $PATH? - linux

I am using a system with an incomplete installation of GNAT, the GNU Ada compiler. A script (in the gdb testsuite) is finding /usr/bin/gnatmake and assumes that it can run Ada compiles. These fail because a the linker can't find libgnat.so.
I don't have root access, so I can't install libgnat.so or remove /usr/bin/gnatmake.
Is there any way to prevent a script from finding gnatmake in /usr/bin? I clearly cannot remove /usr/bin from the path.

Can you install a private, working version of gnatmake?
If you can, then you can create a symlink to the working version of gnatmake in your $HOME/bin directory:
ln -s /path/to/real/gnatmake ~/bin/gnatmake
Then insert your own $HOME/bin directory into your $PATH:
export PATH="$HOME/bin:$PATH"
Now the shell will find your version of gnatmake before the one in /usr/bin.

Try sudoing the script as yourself (sudo -u you ./script). In case you're not allow to sudo, you can also try exec VAR=val ./script. A third way would be to add another directory to $PATH with 'fake' empty scripts to shadow the ADA files.

Related

How do I redirect from a built-in bin to execute an AppImage instead?

Scenario: the current version of Kate in Ubuntu 18LTS points at their customized version (which doesn't appear to support regex search capability). The bin is: /usr/bin/kate.
Desired solution: run the Kate AppImage (which has the regex search/replace functionality). The AppImage currently resides in ~/Downloads.
Question: how do I redirect the system to execute the AppImage version of Kate, instead of the built-in version?
Can I simply create a link to the AppImage in /usr/bin?
Yes, it appears you can... i.e. in my case I replaced the existing kate bin with a link that points to the appimage:
# 1st remove the existing kate binary
# (cp kate somewhere first if you want to keep a copy)
sudo rm /usr/bin/kate
# 2nd create a link in the system bin that points to the appimage
sudo link [directory where the appimage resides]/Kate.AppImage /usr/bin/kate
Done! The system will now execute the appimage when 'kate' is executed (e.g. via context menus).
=========================
UPDATE...
The above solution kinda works... it does run the appimage, however the parameters normally passed to kate (i.e. file to open) are lost in the hard link.
So... the better solution is to create a simple executable shell script (named 'kate' in the /usr/bin directory) to execute the appimage:
#!/bin/sh
exec [directory where the appimage resides]/Kate.AppImage "$#"
This passes any provided parms to the appimage.
You may want to keep (for whatever reasons) your system-installed Kate in /usr/bin/kate...
Then do not touch it. Instead create a directory in your $HOME named bin (it may already be present depending on the Linux distro you run).
Inside that directory, create a symlink:
ln -sf ~/Downloads/kate.AppImage ~/bin/kate
This may already work. If not, you have to move the ~/bin directory to the front of your path:
export PATH=${HOME}/bin:${PATH} # if you use Bash
To permanently modify this $PATH, add this same line into ${HOME}/.bashrc

Wrong executable path for python in linux

In linux bash, I need to run an application (HTSeq) which uses python. When I run the command I get this error:
-bash: /app/HTSeq-0.5.3p7/bin/htseq-count: /usr/bin/python26: bad interpreter: No such file or directory
The thing is that I do not have "python26" in my executable path. So in my /usr/bin/ path I have followings:
/usr/bin/python2.6
/usr/bin/python
I think sometimes I have manually changed something incorrectly. But how can I fix it?
Thanks in advance.
Try renaming "python2.6" to "python26" with sudo mv /usr/bin/python2.6 /usr/bin/python26
Well, since you don't have sudo rights, you could try this:
First create a symlink,
ln -s /usr/bin/python2.6 ~/Desktop/python26
and then adding the symlink dir to your PATH variable
export PATH=$PATH:/home/<your account>/Desktop

Enable native NTFS symbolic links for Cygwin

Recent NTFS and Windows implement symlinks:
NTFS junction point can be used as directory symlink since NTFS 3.0 (Windows 2000) using linkd or junction tools.
NTFS symbolic link can also be used as symlink (for both file and directory) since Windows Vista using mklink tool.
But on Cygwin 1.7 (installed on Windows 7), ln -s creates a text file.
on Cygwin:
$ ln -s -v target mylink
`mylink' -> `target'
on MinGW (or your favorite editor):
$ cat mylink
!<symlink>ÿþt a r g e t
Is it possible to tell Cygwing to use NTFS junction point or NTFS symbolic link?
other question: Is this available on MinGW?
⸻⸻  Short answer  ⸻⸻
Define environment variable:
CYGWIN=winsymlinks:nativestrict
As pointed out by mwm you may also have to go to the settings or to run bash as Administrator. See the Notes section.
⸻⸻  Long answer  ⸻⸻
Default Cygwin symlinks are just regular files
By default Cygwin creates text files as workaround for Windows symlink flaw.
These files are not really symlinks.
Almost all Windows programs do not considers these files as symlinks.
Native symlinks are available on recent Windows versions
Recent NTFS and Windows implement symlinks:
NTFS junction point can be used as directory symlink
since NTFS 3.0 (Windows 2000) using linkd or junction tools.
NTFS symbolic link can also be used as symlink
(for both file and directory) since Windows Vista using mklink tool.
Cygwin can create native NTFS symlinks
Simplified extract of the Cygwin documentation:
Symbolic links
[...]
Cygwin creates symbolic links potentially in multiple different ways:
The default symlinks are plain files containing a magic cookie
followed by the path to which the link points. [...]
The shortcut style symlinks are Windows .lnk [...] created
if the environment variable CYGWIN [...] is set to contain
the string winsymlinks or winsymlinks:lnk. [...]
Native Windows symlinks are only created on Windows Vista/2008 and later,
and only on filesystems supporting reparse points.
Due to to their weird restrictions and behaviour, they are only created
if the user explicitely requests creating them.
This is done by setting the environment variable CYGWIN
to contain the string winsymlinks:native or winsymlinks:nativestrict.
[...]
On the NFS filesystem, Cygwin always creates real NFS symlinks.
Configuring Cygwin
Cygwin User's Guide presents variable CYGWIN and option winsymlinks:
The CYGWIN environment variable is used to configure many global settings [...].
It contains the options listed below, separated by blank characters. [...]
[...]
[...]
[...]
[...]
winsymlinks:{lnk,native,nativestrict} -
if set to just winsymlinks or winsymlinks:lnk, Cygwin creates symlinks
as Windows shortcuts with a special headerand the R/O attribute set.
If set to winsymlinks:native or winsymlinks:nativestrict,
Cygwin creates symlinks as native Windows symlinks on filesystems
and OS versions supporting them. If the OS is known not to support
native symlinks (Windows XP, Windows Server 2003), a warning message
is produced once per session.
The difference between winsymlinks:native and
winsymlinks:nativestrict is this: If the filesystem supports native
symlinks and Cygwin fails to create a native symlink for some reason,
it will fall back to creating Cygwin default symlinks with
winsymlinks:native, while with winsymlinks:nativestrict
the symlink(2) system call will immediately fail.
CYGWIN=winsymlinks:native always creates a link but uses a Cygwin fall-back when target does not exists
on Cygwin:
$ export CYGWIN="winsymlinks:native"
$ ln -s -v target mylink
`mylink' -> `target'
$ echo content > target
on MinGW:
$ cat mylink
content
People using both Windows and Cygwin programs may have issues when a symlink is created as a dummy file (Cygwin fallback when target is missing)...
CYGWIN=winsymlinks:nativestrict always uses native-Windows symlink but fails when target does not exist
on Cygwin:
$ export CYGWIN="winsymlinks:nativestrict"
$ rm -f a b
$ ln -sv a b
ln: failed to create symbolic link `b': No such file or directory
$ touch b
$ ln -sv a b
ln: failed to create symbolic link `b': File exists
$ rm b
$ touch a
$ ln -sv a b
`b' -> `a'
Because nativestrict requires the target exists before the symlink creation, some commands/scripts may fail when creating a link.
Notes
Since Windows 10 build 14972, native NTFS symlinks are available in a non-elevated shell by enabling the Developer Mode in the Developer Settings.
Reference: https://blogs.windows.com/windowsdeveloper/2016/12/02/symlinks-windows-10/
In older versions, only administrators have the ability to create native NT symlinks
so under Windows UAC, the Cygwin terminal emulator (mintty)
should be run with elevated privileges
(right-click the shortcut and choose Run as Administrator
or set the mintty shortcut property, Advanced → Run as Administrator).
Special thanks to Guria, Spooky and Gene Pavlovsky for their contributions.
The accepted answer is right, two little side notes.
If you only care about the symlinks you create yourself on the command line, install cygutils-extra package, it includes a winln command, which has the same syntax as ln, but creates native Windows links. Create an alias: alias ln=winln (only works in interactive shell), or even replace the ln file with winln (works in shell scripts as well) - but it might get overwritten the next time coreutils package is updated.
I've only found out it's possible to use native symlinks when I already had Cygwin installed, and added some symlinks by myself as well. So after I set CYGWIN=winsymlinks:native as my system environment variable, I wanted to convert all the existing non-native links to native. Here's what I did.
Just in case, back up your entire Cygwin directory first.
Find all symlinks and save the list to /links file:
cd /; find . -regextype egrep -regex './(dev|proc|mnt|cygdrive)' -prune -o -type l -print >links
Review links.
Create a tar archive with all the links: tar c --files-from=links >links.tar
Extract the tar archive: tar x --files-from=links <links.tar
Since native symlinks are now enabled, tar will overwrite the old Cygwin's symlinks with native symlinks.
Clean up: rm -f links links.tar
P.S. At first I used CYGWIN=winsymlinks:nativestrict, but then I found out that in this mode, ln -s target link fails if target doesn't exist. By contrast, native will create a Cygwin (non-native) symlink link pointing to the nonexistent target - this matches the behavior of ln on UNIX systems. In rare cases, nativestrict can break some programs or scripts, for example Gentoo run-crons script uses a lockfile which is a symlink pointing to the PID of the running process. In nativestrict mode the script stopped working, because it could no longer create the lockfile. Note: run-crons is a crontab helper script on Gentoo Linux, adding support for cron.{hourly,daily,weekly,monthly}/ dirs, it works very well with Cygwin.
Since #olibre answer didn't work for me. I just created a shell function.
: '
mklink - Create NTFS (Windows) links that is usable by Windows and Cygwin
Usage: mklink [/D | /H | /J] <link-path> <target-path>
Options:
/D Directory Symbolic Link
/H Hardlink
/J Directory Junction (you should prefer /D)
With no options, it creates a NTFS file symlink.
'
mklink () {
if [ "$#" -ge "3" ]; then
cmd /c mklink "$1" "$(cygpath --windows --absolute "$2")" "$(cygpath --windows --absolute "$3")"
else
cmd /c mklink "$(cygpath --windows --absolute "$1")" "$(cygpath --windows --absolute "$2")"
fi
}
Do note you need administrator permissions (for Cygwin) to run the above without problems.
Note that I am unaware whether there's any difference between symlinking to an absolute path versus symlinking to a relative path using CMD's mklink. On Linux, those 2 have different behaviours if you ever decide to move the symlink or move the target file, or move both.
I guess the easiest way is to
grant SeCreateSymbolicLinkPrivilege from Local Group Policy editor (gpedit.msc, on path by default, non-home versions)
create script named ln on path (batch or bash), implementation
similar to above described shell function
profit
You were probably looking for a way to get to another destination in catalogue tree using MSYS. There is a way. You should create a shell script ("*.sh" file) which contains line:
cd "/drive_letter/SubCatalogue/SubFolder/..."

Cygwin path to /cygdrive/C/Program Files (x86)/GnuWin32 directory?

I am having trouble executing a program located in the "C:\Program Files (x86) directory in Windows from within Cygwin. Anyone know the trick to getting this to work?
jboss#QA024 /cygdrive/C/jboss/EAP-6.0.1/jboss-eap-6.0/bin
$ wgetexe="/cygdrive/C/Program Files (x86)/GnuWin32/wget.exe --help"
jboss#QA024 /cygdrive/C/jboss/EAP-6.0.1/jboss-eap-6.0/bin
$ bash $wgetexe
bash: /cygdrive/C/Program: No such file or directory
jboss#QA024 /cygdrive/C/jboss/EAP-6.0.1/jboss-eap-6.0/bin
$ bash "$wgetexe"
bash: /cygdrive/C/Program Files (x86)/GnuWin32/wget.exe --help: No such file or directory
Try this:
wgetexe="/cygdrive/C/Program Files (x86)/GnuWin32/wget.exe"
"$wgetexe" --help
Since it's an executable, you don't want to pass it as an argument to bash, which will try to execute it as a script. Since it has spaces in the path name, you need to quote the name so the shell doesn't try to execute cygdrive/C/Program with invalid arguments.
You should also be able to add the directory to your $PATH:
PATH="$PATH:/cygdrive/C/Program Files (x86)/GnuWin32"
Keep in mind that GnuWin32 programs are Windows executables, and any file paths they use will be interpreted using Windows syntax. Cywin executables (anything that uses cygwin1.dll) use Cygwin path syntax.
Better yet, install the Cygwin version of wget and just invoke it as wget --help.
For example, if you're using the GnuWin32 wget, you might use:
wget -O "C:\cygwin\home\yourname\output-file" "$url"
whereas with the Cygwin wget you might use:
wget -O "/home/yourname/output-file" "$url"
I've always found it easiest to use Cygwin executables from Cygwin whenever possible.
Try this, it always worked or me.
wgetexe="/cygdrive/C/Program\ Files\ \(x86)/GnuWin32/wget.exe"
"$wgetexe" --help

Path, /usr/bin/ and /usr/local/bin/

I installed watchr on OS X (10.8.3) using gem install watchr. And it's installed in /usr/bin/watchr
$ which watchr
/usr/bin/watchr
However, when I tried to call it $ watchr -v, the system couldn't find it.
$ watchr -v
-bash: /usr/local/bin/watchr: No such file or directory
I think this is related to how the path is set up on my machine. My questions:
What is the right way to fix it?
In general, what programs should go to /usr/bin/ vs. /usr/local/bin/?
When I do e.g. $ /usr/bin/watchr -e 'watch(./hello.txt) ...', are we looking at the hello.txt in the current directory or in /usr/bin/ i.e. the same directory as watchr?
The path to your command was cached with a bad value. Try to update the cached directory that bash has stored for the path.
hash -d watchr
I found the answer over here which ctags shows /usr/local/bin/ctags but when I run ctags it runs /usr/bin/ctags. How is this possible?
Is /usr/local/bin/watchr a broken symlink? That would make which watchr not include it but watchr would print this error:
-bash: /usr/local/bin/watchr: No such file or directory
I don't know why the gem that comes with OS X installs programs in /usr/bin/, but generally /usr/bin/ is meant for preinstalled programs, and package managers use something like /opt/local/bin/ or /usr/local/bin/.
I also have /usr/local/bin/ before other folders on the path, and I put most programs that I install or compile manually to /usr/local/bin/. I used to have a separate ~/bin/ folder, but it's easy to find non-Homebrew programs with something like find /usr/local/bin ! -lname '../Cellar/*'.
Related questions about /usr/local/bin/ in general:
https://unix.stackexchange.com/questions/8656/usr-bin-vs-usr-local-bin-on-linux
https://unix.stackexchange.com/questions/4186/what-is-usr-local-bin-came-across-it-in-an-script-installation-for-applescript
create a file called .profile in your home directory and add the following line.
export PATH=“/usr/local/bin:/usr/local/sbin:/usr/bin:$PATH”

Resources