AppImageCommunity / pkg2appimage

Tool and recipes to convert existing deb packages to AppImage
http://appimage.org
MIT License
697 stars 216 forks source link

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

Open cyanlink opened 4 years ago

cyanlink commented 4 years ago

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/.mountblablablah/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 commented 4 years ago

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?

probonopd commented 4 years ago

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.

cyanlink commented 4 years ago

@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?

probonopd commented 4 years ago

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?

cyanlink commented 4 years ago

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 commented 4 years ago

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:

cyanlink commented 4 years ago

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!

probonopd commented 4 years ago

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" "$@"