newville / pyshortcuts

create desktop shortcuts to python scripts on Windows, Mac, or Linux
MIT License
103 stars 15 forks source link

Create shortcut for executable file (not python script) on Linux #30

Open DotBow opened 4 years ago

DotBow commented 4 years ago

Hi!

I'm trying to make a shortcut for an application executable file. It is working perfect for Windows. However, on Linux it adds additional text to 'Exec=' row in .desktop file.

So, instead of this:

Exec='/home/oleg/Blender Builds/daily/blender-2.83-be7c51d076be-linux64/blender'

I got this:

Exec='/home/oleg/Blender Builds/daily/blender-2.83-be7c51d076be-linux64/blender' /home/oleg/Repositories/Blender-Launcher/source

Or even this one:

Exec=/usr/bin/python3 '/home/oleg/Blender Builds/daily/blender-2.83-be7c51d076be-linux64/blender'

How can I fix it? Thanx!

newville commented 4 years ago

attach script or command-line arguments.

DotBow commented 4 years ago

https://github.com/DotBow/Blender-Launcher/blob/master/source/widgets/library_widget.py#L217-L236

Maybe I am a bit confused about using script and executable arguments in a proper way?..

newville commented 4 years ago

@DotBow Please create a small, standalone script that demonstrates the problem, and show the output you get, and state clearly what you expect instead.

DotBow commented 4 years ago

Ok, after an hour of testing I found out that the problem was in spaces inside path and name of shortcut. For path I escaped spaces with '\', but if name contains any of them it doesn't work. Can't find any workaround rather than making an ugly name with - or _.

So, here is working script:

from pyshortcuts import make_shortcut

exe_path = "/home/oleg/Blender Builds/daily/blender-2.90-55a2682348df-linux64/blender"
name = "Blender 2.9"

make_shortcut(
    name=name.replace(' ', '-'),
    script=exe_path.replace(' ', r'\ '),
    startmenu=False,
    executable="!/bin/bash",
)

It produces following Blender-2.9.desktop file:

[Desktop Entry]
Name=Blender-2.9
Type=Application
Comment=Blender-2.9
Terminal=true
Icon=/home/oleg/.local/lib/python3.7/site-packages/pyshortcuts/icons/py.ico
Exec=!/bin/bash /home/oleg/Blender\ Builds/daily/blender-2.90-55a2682348df-linux64/blender

And this script will not produce a working shortcut since there is spaces in name and path:

from pyshortcuts import make_shortcut:

exe_path = "/home/oleg/Blender Builds/daily/blender-2.90-55a2682348df-linux64/blender"
name = "Blender 2.9"

make_shortcut(
    name=name,
    script=exe_path,
    startmenu=False,
    executable="!/bin/bash",
)
newville commented 4 years ago

@DotBow OK, thanks, I think I now understand the problem: spaces in the path of the script name are not escaped in the Exec field. Yeah, that's believable.

We should do that check and escaping on the script argument in make_shortcut. Are you willing to make a Pull Request for this? If not, I can try to fix this.

FWIW, I'm 99% certain that it is OK to have spaces in the Name.

DotBow commented 4 years ago

Well, it is a bit tricky. As far as I know, not all Unix systems support escaping with '\' (on Debian it is probably different). It also might be better to just wrap paths with quotes. Need a proper tesing. At least for now I'm ok with proper behaviour on Ubuntu.

As for name - I might be wrong, will look into it later.

newville commented 4 years ago

All the linux variants should be the same on this behavior. Certainly, Debian and Ubuntu are the same. What might be different is the shell environment is used to run that command string. I think that the Desktop run system can do some escaping of the 'Exec' string, but I'm not sure of the details. I would not be surprised if it forced the use of "sh", but it might use "$SHELL". In all the shells I'm aware of, spaces in paths need to be escaped with a backslash.

I suggest replacing ' ' with '\ ' as that will fix the immediate problem. If we need to alter or change that later for some other problem, that's OK.