I'm experiencing some weird permission denied errors that I have no idea where could be coming from.
$ go run .
Hello from go
$ make run
go run .
make: go: Permission denied
make: *** [Makefile:2: run] Error 127
$ make run2
echo "Make says hello" ; go run .
Make says hello
Hello from go
$ cat Makefile
run:
go run .
run2:
echo "Make says hello" ; go run .
$ cat main.go
package main
import "fmt"
func main() {
fmt.Println("Hello from go")
}
My terminal is bash running on Ubuntu 22.04.
What is the difference between my run target and running go directly that can cause a permission denied error?
What's the difference between run and run2 that allow it to work in one but not in the other?
EDIT: Running make with -d / --trace
$ make -d run
<...snip...>
No need to remake target 'Makefile'.
Updating goal targets....
Considering target file 'run'.
File 'run' does not exist.
Finished prerequisites of target file 'run'.
Must remake target 'run'.
go run .
make: go: Permission denied
make: *** [Makefile:2: run] Error 127
$ make --trace run
Makefile:2: target 'run' does not exist
go run .
make: go: Permission denied
make: *** [Makefile:2: run] Error 127
$ make --trace run2
Makefile:5: target 'run2' does not exist
echo "Make says hello"; go run .
Make says hello
Hello from go
This is due to a bug in GNU make (actually it's a bug in gnulib). It means that you have a directory named go, in some directory on your PATH (before the actual directory containing the go executable).
So if you have a directory /usr/bin/go/. and you have /usr/bin on your PATH, you'll see this issue.
You should check your PATH and make sure to remove any directories that contain such subdirectories. If you can't remove that directory from your PATH (it's unusual to need directories containing subdirectories on your PATH but I guess it's possible) and you can't rename the go directory to something else, you'll have to ensure that GNU make invokes a shell, by adding a special character. Just ; is good enough:
run:
go run . ;
The issue you're experiencing is likely due to different environment between your shell and shell executed by Makefile. If for example you have a shell alias for go this alias is not visible to Makefile or if you have a custom path in you're shell rc file it's not visible to Makefile. It's hard to guess where the difference might be.
You might want to try debug the issue by trying following in your Makefile:
echo $(PATH)
command -v go
and run the same commands in your shell and compare results.
Note that the default shell for Makefile is /bin/sh whereas you probably have bash or zsh.
Here's some handy defaults to configure your Makefile build:
LANG=en_US.UTF-8
SHELL=/bin/bash
.SHELLFLAGS=--norc --noprofile -e -u -o pipefail -c
Related
Consider the following Makefile.
install:
sudo rpi-install.py /dev/ttyUSB0 foo.bin
Note that I have deliberately not hardcoded a path to rpi-install.py because it is not in the same location on other people's machines, but I expect it to be in the PATH of everyone who uses my code.
Unfortunately, when I type make install, I get the following output.
sudo rpi-install.py /dev/ttyUSB0 larson.bin
sudo: rpi-install.py: command not found
make: *** [install] Error 1
When I type the exact same command on my shell, it works exactly as expected.
Additionally, when I remove the sudo from the Makefile, it successfully finds the binary and gets a permission denied error due to lack of root privileges.
How can I allow make to discover the programs that are in my PATH when they must be run with sudo?
For the sake of reproducibility, assume that the following contents are in rpi-install.py, and that it lives in the directory $HOME/bin. Additionally assume that PATH includes $HOME/bin.
#!/usr/bin/env python
print "Hello World!"
There was a combination of two fixes that resolved this problem.
I needed to set PATH in .profile instead of .bashrc because the default shell /bin/sh used by make did not pick up the correct path from .bashrc.
I needed to set the environment for the sudo command inside the makefile explicitly to be the external PATH, based on this answer to this question.
sudo env "PATH=$(PATH)" rpi-install.py /dev/ttyUSB0 larson.bin
I have a Jenkins server running and have a couple of builds that are all working. However, this morning when I tried to add another one it kept failing with the error -
[test.gov] $ /bin/sh -xe /tmp/hudson7055290339554583413.sh
+ ./opt/jenkins/build.sh
/tmp/hudson7055290339554583413.sh: line 2: /opt/jenkins/build.sh: No such file or directory
Build step 'Execute shell' marked build as failure
The shell script is at that path and has that name. If I make it ./opt/jenkins/build.sh it still fails with the same error. The command I have in the "Execute Shell" section in the "Command" text box is /opt/jenkins/build.sh. I tried ./opt/jenkins/build.sh as well.
The script is on a CentOS system btw.
This is the script I am trying to run -
echo "git pull"
cd /var/www/path/for/my_website/docroot/
git checkout master
git pull
echo "change ownership to apache"
chown -R apache:apache *
echo "running drush commands"
drush updb -y
#drush fra -y
drush cc all
Often the "build.sh: No such file or directory" error actually means that the shebang line within build.sh does not point to an executable file. Check the contents of build.sh to make sure that path exists.
Sometimes for your path in the shell command, a "." may not work. Instead, use the macro expression to get the workspace.
So for example: %WORKSPACE%/opt/jenkins/usda_gov_build.sh
This will give the shell command the exact path of the file in your jobs workspace.
I have created a simple script:
echo "the path of the current directory is `pwd`"
and saved it by the name pathinfo
then i have created a bin directory at my home page with path as
/home/vpnsadmin/bin
and copied my script(pathinfo) to that bin directory.
Now i want run this script as a command but it is showing error
-bash: /usr/bin/test2: No such file or directory
but if copy my script(pathinfo) to "/usr/bin/" then it runs as a command.
the PATH environment variable is set as-
PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/home/vpnsadmin/bin
My question is why does the shell not run it as a command when it is present in /home/vpnsadmin/bin.
or else
why does it only check for the binary at /usr/bin and not at /home/vpnsadmin/bin or at /bin
The shell that is to execute your command needs to have the correct PATH variable set at the time of execution and, depending on shell, might need to have created its own internal (hash)map of the available commands.
Assuming you are using bash, try the following with your script saved in /usr/bin:
$ PATH=/ test2
$ PATH=/usr/bin test2
In the first case you should get an expected "not found" error, in the second it should work. The third test to perform is left as an exercise...
And I have to say that the supplied error message looks a bit odd if you actually tried to do
$ test2
and not
$ /usr/bin/test2
before copying the command to /usr/bin.
Edit:
Also, avoid naming your scripts test, in any way shape or form. This causes so much confusion for beginners.
Hint:
man test
Did you have the path to bash at the top of your script and did you use backticks around pwd?
#!/bin/bash
echo "the path of the current directory is `pwd`"
Did you make the file executable?
chmod +x pathinfo
There is another script pathinfo somewhere in your path which contains a call to /usr/bin/test2
Try whereis pathinfo to see how many there are and which pathinfo to see which one your shell currently prefers.
I'm trying to build a software called Slicer3 on Windows 7 which features a "super build".
It's a All-in-one TCL Script to checkout and build Slicer3.
I ran CYGWIN and navigated til the correct directory, then ran the script and got:
$ ./Slicer3-svn/Scripts/getbuildtest.tcl
couldn't read file "./Slicer3-svn/Scripts/getbuildtest.tcl": no such file or directory
Obviously I am sure that the file exists and I gave it 777 permission. I'm running cygwin as admin.
The beginning of the tcl file's content is:
#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$#"
So I tried commenting out line 3 and running directly
$ tclsh ./Slicer3-svn/Scripts/getbuildtest.tcl
but got the same error.
Any idea?
I will try to help troubleshooting as much as I can:
Determine if you have tclsh installed and it is in the PATH:
$ tclsh
Determine if tclsh works for a simple script:
$ echo puts hello > hello.tcl; tclsh hello.tcl
Determine if the script exists and readable:
$ cat ./Slicer3-svn/Scripts/getbuildtest.tcl
$ cd ./Slicer3-svn/Scripts
$ cat getbuildtest.tcl
As far as line-ending (DOS CRLF vs. Unix LF):
$ cd ./Slicer3-svn/Scripts
$ sed 's/\r\n/\n/g' getbuildtest.tcl > getbuildtest_new.tcl
$ tclsh getbuildtest_new.tcl
This way, we can narrow down the problem, should any of the steps failed.
Description: TCLSH couldn't read file: no such file or directory.
Possible reason: TCLSH under CYGWIN does not resolve windows PATH's properly, and cannot find the files.
Workaround: move the script within the CYGWIN path.
just moving the script to a "simpler" path works for me. I'm not that sure about the reason, neither how to solve this misbehaviour.
Question: I get this error message:
export: bad interpreter: No such file or directory
when I execute this bash script:
#!/bin/bash
MONO_PREFIX=/opt/mono-2.6
GNOME_PREFIX=/opt/gnome-2.6
export DYLD_LIBRARY_PATH=$MONO_PREFIX/lib:$DYLD_LIBRARY_PATH
export LD_LIBRARY_PATH=$MONO_PREFIX/lib:$LD_LIBRARY_PATH
export C_INCLUDE_PATH=$MONO_PREFIX/include:$GNOME_PREFIX/include
export ACLOCAL_PATH=$MONO_PREFIX/share/aclocal
export PKG_CONFIG_PATH=$MONO_PREFIX/lib/pkgconfig:$GNOME_PREFIX/lib/pkgconfig
PATH=$MONO_PREFIX/bin:$PATH
PS1="[mono-2.6] \w # "
But the bash path seems to be correct:
asshat#IS1300:~/sources/mono-2.6# which bash
/bin/bash
asshat#IS1300:~# cd sources/
asshat#IS1300:~/sources# cd mono-2.6/
asshat#IS1300:~/sources/mono-2.6# ./mono-2.6-environment
export: bad interpreter: No such file or directory
asshat#IS1300:~/sources/mono-2.6# ls
download mono-2.4 mono-2.4-environment mono-2.6 mono-2.6-environment
asshat#IS1300:~/sources/mono-2.6# cp mono-2.6-environment mono-2.6-environment.sh
asshat#IS1300:~/sources/mono-2.6# ./mono-2.6-environment.sh
export: bad interpreter: No such file or directory
asshat#IS1300:~/sources/mono-2.6# ls
download mono-2.4-environment mono-2.6-environment
mono-2.4 mono-2.6 mono-2.6-environment.sh
asshat#IS1300:~/sources/mono-2.6# bash mono-2.6-environment
asshat#IS1300:~/sources/mono-2.6#
What am I doing wrong? Or is this a Lucid Lynx bug?
I did chmod + x
The first line, #!/bin/bash, tells Linux where to find the interpreter. The script should also be executable with chmod +x script.sh, which it appears you did.
It is highly likely that you created this file with a windows editor, which will place a <cr><lf> at the end of each line. This is the standard under dos / windows. OS X will place a <cr> at the end of each line. However, under Unix / Linux, the standard is to just put a <lf> at the end of the line.
Linux is now looking for a file called /bin/bash<cr> to interpret the file,
where <cr> is a carriage return character, which is a valid file character under Linux. Such a file doesn't exist. Hence the error.
Solution: Edit the file with an editor on Linux and get rid of the extra <cr>. One tool that usually works when the file is edited on Windows is dos2unix.
Could the script be using Dos newlines?
Try running dos2unix on it.
It looks like things have been configured to override the export builtin somehow. This can be done via an exported function or the enable builtin, for example. Try putting type export in the script to check. If you are setting BASH_ENV, you probably shouldn't.
If bash is called as sh, it enables POSIX mode and does not allow export to be overridden with a function, as required by POSIX. Likewise, most other shells installed as /bin/sh follow POSIX in this and/or do not allow the execution environment of a script to be messed up so strongly as through importing functions from the environment.
By the way, the script seems designed to be sourced, i.e. . ./mono-2.6-environment instead of ./mono-2.6-environment.
Had the same problem. Used brute force:
/bin/sh /full/path/to/configure --options
& this did the trick
(Of course I'd like to know why)
I encountered a similar error but in my case I forgot to add / before bin and I was encountering the bad interpreter error. Also tried to do
sudo apt-get install dos2unix -y package.
I was using this originally :
#! bin/bash ( i was missing / before bin )
Double check the path as well.
This could be a case of a shebang with homoglyphic unicode characters. In other words, you may have invisible or look-alike characters in the shebang which don't actually represent the string #!/bin/bash. Try looking at the characters in a hex editor.
what worked for me was when dos2Unix wasn't on the system I was working with:
sed -i s/{ctrl+v}{ctrl+m}// filename
This happens sometimes when file system goes funny.
Try to move or rename the file.
If you see "Stale file handle" error this is your problem.
e.g. happened us with CentOS docker
$ ./test.sh
-bash: ./test.sh: /bin/bash: bad interpreter: Invalid argument
$ ls -alstr test.sh
20 -r-xr-xr-x 0 omen omen 17874 Jun 20 01:36 test.sh
$ cp test.sh testcopy.sh
$ ./testcopy.sh
Happy Days
$ mv test.sh footest.sh
mv: cannot move ‘test.sh’ to ‘footest.sh’: Stale file handle
$ rm test.sh
rm: cannot remove ‘test.sh’: Stale file handle
You can copy the file and read it.
But not move it!
Nor remove it.
Some weird docker file-system thing maybe.
Solution: re-create the docker container OR maybe file system repair disk would help
OR of course format c: :-D :-o