pkg2appimage icon indicating copy to clipboard operation
pkg2appimage copied to clipboard

When the executable entry point is a shell script, AppRun cannot find real executable correctly

Open cyanlink opened this issue 4 years ago • 8 comments

I was trying to build an appimage of wasabi wallet today. I think I found a bug. For now wasabi wallet's deb file still store binaries inside usr/local/bin so I moved them into usr/bin in the script section of wassabee.yml Now AppDir looks like this:

wassabee.AppDir ├── AppRun ├── usr │   ├── bin │   │   ├── wasabiwallet (real binaries inside) │   │   └── wassabee (shell script, ./wasabiwallet/wassabee is real executable) │   ├── lib │   ├── local │   │   └── bin │   └── share │   ├── applications │   └── icons ├── wassabee.desktop └── wassabee.png

For now, the wassabee script (and from local shell it works) is: ./wasabiwallet/wassabee Then I run the AppImage. It says "./wasabiwallet/wassabee: no such file or directory". I was confused. Then I tried to debug by adding "pwd && ls", then the result shows we are currently under /tmp/.mount_blablablah/usr/ directory! Then I had no choice but to edit the shell script like: ./bin/wasabiwallet/wassabee $@ to pretend that I am inside usr, it works. And of course, if I try to run wassabee script in local terminal, it cannot find the real executable. I noticed that other software use symlink for "redirect" purpose (e.g. VSCode).Is it a bug, or I am being dumb and missed something?

cyanlink avatar Mar 24 '20 07:03 cyanlink

Issue from AppImageKit Found this one, says AppImage runtime has to chdir to usr/, so it is not a bug but a feature lol. But it is dirty after all I think. What would be a better practice? Should I switch to linuxdeployqt now?

cyanlink avatar Mar 24 '20 07:03 cyanlink

It depends - which type of application do you want to package? Is the wasabiwallet script needed, and if yes, why doesn't it call the real executable using a path relative to itself?

You could also try union: true as described in https://github.com/AppImage/pkg2appimage/blob/master/YML.md#keys-that-enable-ability-to-relocate.

probonopd avatar Mar 24 '20 19:03 probonopd

@probonopd wasabiwallet is a directory, with all libs and bins inside. this software is multi-platform so they just generated the linux dist package in this way. I don't get how on earth union: true works though (from the description). Is it an option that "simulates" a / directory so that even hardcoded paths (e.g. /usr/bin/foobar) can work? And in this way we don't need the chdir hack introduced by binpatch?

cyanlink avatar Mar 25 '20 05:03 cyanlink

Yes.

But again: Why don't you write your script so that it calls the application at a relative path (relative to the script itself) rather than by an absolute path? Is your AppImage available for download so that I can have a look?

probonopd avatar Mar 25 '20 07:03 probonopd

I'm being dumb here, didn't write shell script for years... Thought ./ is related to the script's path. I should use the dirname $0 things.

cyanlink avatar Mar 25 '20 09:03 cyanlink

The shell special characters escape thing is nasty. Trying to echo the following into the file:

#!/bin/bash
full_path=$(realpath $0)
dir_path=$(dirname $full_path)
$dir_path/wasabiwallet/wassabee

So I wrote things like this inside wassabee.yml: script:

  • mv usr/local/bin/* usr/bin/
  • mv usr/share/applications/wassabee.desktop ./
  • echo -e "#!/bin/bash\nfull_path=$(realpath $0)\ndir_path=$(dirname $full_path)\n$dir_path/wasabiwallet/wassabee" > usr/bin/wassabee Yes, the echo works as intended in my terminal, but when it comes to pkg2appimage, the eval thing keeps reporting syntax error near unexpected token ('` error, adding escape characters here and there and it won't work.

cyanlink avatar Mar 25 '20 10:03 cyanlink

I gave up, just used a relative symlink instead... Could you tell me the correct way to write shell commands (with special characters like $, &, parenthesis) into a file? and it need to pass eval too, my script (echo "aaa" > bbb) works in terminal but won't pass a eval. Thanks!

cyanlink avatar Mar 25 '20 11:03 cyanlink

If you put this as AppRun into your AppDir, then it will run ./usr/bin/wassabee relative to its own location:

#!/bin/bash
HERE="$(dirname "$(readlink -f "${0}")")"
exec "${HERE}/usr/bin/wassabee" "$@"

probonopd avatar Apr 04 '20 10:04 probonopd