16

How is this possible?

bash: /usr/local/phantomjs/bin/phantomjs: No such file or directory
bash-4.3# cd /usr/local/phantomjs/bin
bash-4.3# ls
phantomjs
bash-4.3#

The content of /usr/local/phantomjs/bin is the phantomjs file but when I try to execute it, it looks like it does not exist.

FYI, I'm on Alpine linux 3.3

Update1

bash-4.3# ls -lF /usr/local/phantomjs/bin/phantomjs
-rwxr-xr-x    1 root     root      67932064 Jan 25  2016 /usr/local/phantomjs/bin/phantomjs*
bash-4.3# lf -lF /usr/local/phantomjs/bin
bash: lf: command not found
bash-4.3# ls -lF /usr/local/phantomjs/bin
total 66340
-rwxr-xr-x    1 root     root      67932064 Jan 25  2016 phantomjs*

Update2

bash-4.3# file /usr/local/phantomjs/bin/phantomjs
bash: file: command not found
bash-4.3# head -n1 /usr/local/phantomjs/bin/phantomjs
ELF>xvA@`�
Q�t/lib64/ld-linux-x86-64.so.2GNUGNU����!�`�L`�L^|��������h�TT@T@DD`��`�L`�P�tddB�dB�dB��g

Update3

bash-4.3# echo $PATH
/usr/local/phantomjs/bin:/usr/local/ruby/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
bash-4.3# ruby -v
ruby 2.1.10p492 (2016-04-01 revision 54464) [x86_64-linux]

Update4

bash-4.3# strace /usr/local/phantomjs/bin/phantomjs
execve("/usr/local/phantomjs/bin/phantomjs", ["/usr/local/phantomjs/bin/phantom"...], [/* 13 vars */]) = -1 ENOENT (No such file or directory)
writev(2, [{"strace: exec: No such file or di"..., 39}, {"\n", 1}], 2strace: exec: No such file or directory
) = 40
writev(2, [{"", 0}, {NULL, 0}], 2)      = 0
getpid()                                = 12
exit_group(1)                           = ?
+++ exited with 1 +++

Thanks

  • Let's see the output of ls -lF /usr/local/phantomjs/bin/phantomjs as well as lf -lF /usr/local/phantomjs/bin. Please edit. – user Feb 7 '17 at 13:12
  • 1
    Oops. Yes, I really did mean ls -lF. Sorry for the confusion! Can we also see the output of file /usr/local/phantomjs/bin/phantomjs please, and if that says anything like "text" or "script", also head -n1 /usr/local/phantomjs/bin/phantomjs. I have a hypothesis, and that would potentially confirm or falsify it (or at the very least point us in the right direction). – user Feb 7 '17 at 13:50
  • 1
    Okay, not what I expected, but helpful. Since you have ls but not file immediately available, I now suspect that your $PATH is not fully populated. Let's see echo $PATH to confirm that; I suspect it will include /bin but not /usr/bin, for starters. It's also possible that other parts of your environment (such as $LD_LIBRARY_PATH) are incomplete for the same reason that causes $PATH to be incomplete, but $PATH is easy to verify at a glance. Looking at en.wikipedia.org/wiki/Alpine_Linux, Alpine's minimalism might be a factor here. – user Feb 7 '17 at 13:59
  • see Update3. FYI ruby works as expected. The issue is only with phantomjs. – Sig Feb 7 '17 at 14:03
  • Okay, this is actually odd. Hopefully someone will be able to take the details thus found and actually describe the behavior seen, because I am running out of ideas to try at the moment. – user Feb 7 '17 at 14:48
6

The shell will report an ambiguous "No such file or directory" for an executable when the shell cannot find a dependency for that executable.
The missing dependency is typically a required shared library or a dynamic loader.

Use the strace command to explicitly view the open() syscall that fails during the execution request (e.g. strace /usr/local/phantomjs/bin/phantomjs).

Addendum

execve("/usr/local/phantomjs/bin/phantomjs", ["/usr/local/phantomjs/bin/phantom"...], [/* 13 vars */]) = -1 ENOENT (No such file or directory)

The evecve syscall returned the error code ENOENT, which the man page describes as "the file filename or a script or ELF interpreter does not exist, or a shared library needed for file or interpreter cannot be found."

Usually I've seen strace provide better resolution of the missing file.
The next step is to examine the executable file for its dependencies.
Use the strings command to extract the dynamic linker/loader, shared libraries, and entry-points listed at the beginning of the executable file.

strings /usr/local/phantomjs/bin/phantomjs | less

For each filename that you can identity in this list, you then have to verify that the file is installed in your root filesystem.

$ file modetest
modetest: ELF 32-bit LSB  executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.10.0, stripped

$ strings modetest | less
/lib/ld-linux-armhf.so.3    <=
libdrm.so.2    <=
drmModeFreeObjectProperties
drmModeFreePlaneResources
_ITM_deregisterTMCloneTable
 ...
libpthread.so.0    <=
pthread_join
pthread_create
__errno_location
 ...
libc.so.6    <=
strcpy
exit
mmap64
 ...

From your previous Update2, the first file would be /lib64/ld-linux-x86-64.so.2.


| improve this answer | |
  • 1
    @macsig -- See addendum. – sawdust Feb 8 '17 at 21:10
  • Thanks for your detailed answer. I have solved the issue by installing an Alpine specific PhantomJS version (found after googling for a while) instead of from the "standard" version. – Sig Feb 9 '17 at 10:18
  • For some reasons It doesn't work on alpine. I used this command / repo : curl -Lo phantom.tgz https://github.com/DarthHater/docker-phantomjs2/releases/download/2.1.1/dockerized-phantomjs.tar.gz | tar xf -C / then you can use /usr/local/bin/phantomjs – Boop Sep 11 '18 at 15:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.