terminal icon indicating copy to clipboard operation
terminal copied to clipboard

No way to run a shellscript in terminal from the GUI

Open thomasdn opened this issue 5 years ago • 27 comments

Problem

As far as I can tell there is no way in ElementaryOS to create a shellscript that is executable in a terminal by the user clicking or doubleclicking on it.

I have tried making a shellscript executable via POSIX file permissions but double clicking it does not make it run. There is an option to right click and then click "Run", but this does not seem to run the script in a terminal. Nor does it run the script in the folder in which the script is located.

Proposal

I would expect a way to run a shellscript (or other program) from the GUI with the script running in the folder where it is located.

I see several possible solutions:

  1. If make a script that is marked as executable run in a terminal when doubleclicking it. (with CWD set to the folder in which the script resides)

or

  1. Provide an option on the right click menu to run the script in a terminal (with CWD set to the folder in which the script resides)

or

  1. Associate shell scripts (ending in .sh or similar - and being marked as executable) with Terminal application and then have the user doubleclick them to execute in the current folder. (I believe this is how it works on Mac OS X)

Prior Art

I think most modern Linux Desktop Environments support this feature. Here is an example of how this is done in Gnome: https://www.cyberciti.biz/faq/run-execute-sh-shell-script/

Mac OS X implements the third option above.

Windows famously allows this automatically for all .bat files: You just doubleclick it and it runs in a terminal.

I would like ElementaryOS to obey the execution bit on the file permissions.

thomasdn avatar Nov 12 '20 15:11 thomasdn

I think this issue probably belongs in the Files project as that is the most likely GUI to use to laumch a script. It would be possible to add a "Run in Terminal" action to the context menu I guess.

jeremypw avatar Nov 12 '20 16:11 jeremypw

Oh yeah, I think you are right that it belongs in Files. What do I do now? Should I copy this issue and create it in Files? Or can I move it somehow?

thomasdn avatar Nov 12 '20 16:11 thomasdn

@jeremypw hm wouldn't it be better to associate script mimetypes in Terminal rather than hardcode terminal launching in Files?

danirabbit avatar Nov 12 '20 19:11 danirabbit

@thomasdn we can move the issue for you once we figure out where to put it :)

danirabbit avatar Nov 12 '20 19:11 danirabbit

Would all scripts need to be run in a Terminal? Also scripts are themselves executables rather than a content type to opened in another application. To execute in Terminal you have to specify a flag. I am not sure it can be done without some Files involvement but I may be wrong.

jeremypw avatar Nov 12 '20 19:11 jeremypw

Well the default association for any code files is to open them in Code. We intentionally don't run treat scripts as executables in Files because of security, so it would only be an option present in "Open With >"

danirabbit avatar Nov 12 '20 20:11 danirabbit

@danrabbit "Open With" might work. However, it is critical that the script be executed with CWD set to the current folder open in Files. Also, I think that a general "Execute" option would be OK on all files with the executable bit set. Because it might be both shellscripts, python programs as well as binaries that need to be executed from time to time.

thomasdn avatar Nov 12 '20 20:11 thomasdn

In that case I think we will need another desktop file analagous to open-pantheon-terminal-here.desktop for folders. That is how Terminal shows up in the "Open in ..." submenu when right clicking on a folder. That would not involve Files code. If the required CWD is the same as one where the script is actually located? In which case Terminal can obtain that from the script url passed to it.

Probably not worth addressing this until https://github.com/elementary/terminal/pull/461 and https://github.com/elementary/terminal/pull/477 are merged.

jeremypw avatar Nov 13 '20 16:11 jeremypw

Unfortunately, this sounds like something that won't be implemented any time soon.

Is there any workaround I can use in order to let my users execute scripts in the folder they via the Files UI. Maybe even by creating a .desktop sidecar file for each script or something like that? This is a really critical thing for most of what we do as it is used for automation of tasks for non-technical users. Without the ability to run scripts from the UI, we might have to go back to using a different OS.

Med venlig hilsen/Kind regards Thomas

Den fre. 13. nov. 2020 kl. 17.05 skrev Jeremy Wootten < [email protected]>:

In that case I think we will need another desktop file analagous to open-pantheon-terminal-here.desktop for folders. That is how Terminal shows up in the "Open in ..." submenu when right clicking on a folder. That would not involve Files code. If the required CWD is the same as one where the script is actually located? In which case Terminal can obtain that from the script url passed to it.

Probably not worth addressing this until elementary/terminal#461 https://github.com/elementary/terminal/pull/461 and elementary/terminal#477 https://github.com/elementary/terminal/pull/477 are merged.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/elementary/granite/issues/438#issuecomment-726848288, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA4TRK3ZKVZ4VZEMGLPDM7DSPVKLTANCNFSM4TTOMTOQ .

thomasdn avatar Nov 16 '20 07:11 thomasdn

Is there any workaround I can use in order to let my users execute scripts in the folder they via the Files UI.

There seems to be a word missing. Could you confirm that in Files you are clicking on the script itself - so the required folder is the one where the script itself is situated? It is not obvious how you could run a script located in one folder with a different working directory using the FIles UI. Could you give an example of such a script?

jeremypw avatar Nov 16 '20 11:11 jeremypw

The command-line io.elementary.terminal -w <path-to-working-directory> -x <command-to-execute> does work so you may be able to create a desktop file for the script that takes a folder mimetype and executes such a command line (?). But this would mean using the "Open with" context menu on a folder and choosing the script you want to run there.

jeremypw avatar Nov 16 '20 11:11 jeremypw

Is there any workaround I can use in order to let my users execute scripts in the folder they via the Files UI.

There seems to be a word missing. Could you confirm that in Files you are clicking on the script itself - so the required folder is the one where the script itself is situated? It is not obvious how you could run a script located in one folder with a different working directory using the FIles UI. Could you give an example of such a script?

Sorry, It should have been:

Is there any workaround I can use in order to let my users execute scripts in the folder they are located in via the Files UI.

The script that the user runs via Files should be executed in the folder which the script itself i situated. And the output of the script should be shown in a terminal.

I am sorry if my previous replies were confusing. I do not think that the script should be executed in a different folder than the one in which it is located. The reason I specify that CWD should be set to the folder the script is in is in order to avoid having someone implement a way to execute the script without specifying the CWD. Because in that case it might just be executed in ~ or something like that. And this is not analogue to how the shell would work: If you execute a shellscript in a shell using ./, it is executed in that folder.

What I suggest is the same behavior as most other modern OS.

For example Windows:

  1. Create a file called "c:\tmp\test.bat" with the following two lines contents:

    echo My current working direcotry is: %cd% pause

  2. Open the folder C:\tmp in Windows Explorer.

  3. Doubleclick test.bat

  4. Notice that the script will print:

    C:\tmp>echo My current working direcotry is: C:\tmp My current working direcotry is: C:\tmp

    C:\tmp>pause Press any key to continue . . .

I hope this clears up any confusion.

thomasdn avatar Nov 16 '20 11:11 thomasdn

The command-line io.elementary.terminal -w <path-to-working-directory> -x <command-to-execute> does work so you may be able to create a desktop file for the script that takes a folder mimetype and executes such a command line (?). But this would mean using the "Open with" context menu on a folder and choosing the script you want to run there.

I tried doing this:

(run-script.desktop)

[Desktop Entry]
Type=Application
Name=Execute Myscript
Exec=io.elementary.terminal -w . -x myscript.sh
Terminal=True
MimeType=application/x-desktop

This does not seem to give me an option to run in a terminal.

I am likely misunderstanding what do to here.

thomasdn avatar Nov 16 '20 12:11 thomasdn

I wasn't sure whether that Exec line would work in a desktop file - but it did work for me when run from a terminal (other than Terminal). I'll see whether I can come up with something. I think myscript.sh would have to be in your PATH if you do not give the full path and I am not sure whether desktop files interpret .

jeremypw avatar Nov 16 '20 15:11 jeremypw

This desktop file allows a script to run in the terminal.

[Desktop Entry]
Name=Terminal
TryExec=io.elementary.terminal
Exec=io.elementary.terminal -x %u
Icon=utilities-terminal
Type=Application
StartupNotify=true
X-GNOME-Gettext-Domain=io.elementary.terminal
NoDisplay=true
MimeType=application/x-shellscript;

Save in /usr/share/applications as run-in-terminal.desktop and run sudo update-desktop-database. This could also be achieved with a contractor file.

I do not think it is possible to pass in the desired working directory explicitly with a desktop or contractor file. Some modification of the Terminal app is required. One way would be to have the terminal to change the current working directory to that of the supplied script by default. Alternative an additional flag could be implemented to cause this to happen.

jeremypw avatar Nov 16 '20 17:11 jeremypw

If have pushed a commit to https://github.com/elementary/terminal/pull/477 that makes the above desktop file work as desired - i.e. the Terminal opens at the folder containing the script when opened with Files. i.e. terminal gets the working directory from the path of the command if possible, if it is not overridden using the -w flag.

jeremypw avatar Nov 16 '20 19:11 jeremypw

This contract file will also work after merging elementary/terminal#477:

[Contractor Entry]
Name=Run in Terminal
Description=Run the selected script in the terminal
MimeType=application/x-shellscript
Exec=io.elementary.terminal -x %f
Gettext-Domain=io.elementary.terminal

This file should be put in ~/.local/share/contractor or usr/share/contractor and named e.g. "run-in-terminal.contract"

jeremypw avatar Nov 16 '20 19:11 jeremypw

This desktop file allows a script to run in the terminal.

[Desktop Entry]
Name=Terminal
TryExec=io.elementary.terminal
Exec=io.elementary.terminal -x %u
Icon=utilities-terminal
Type=Application
StartupNotify=true
X-GNOME-Gettext-Domain=io.elementary.terminal
NoDisplay=true
MimeType=application/x-shellscript;

Save in /usr/share/applications as run-in-terminal.desktop and run sudo update-desktop-database. This could also be achieved with a contractor file.

I do not think it is possible to pass in the desired working directory explicitly with a desktop or contractor file. Some modification of the Terminal app is required. One way would be to have the terminal to change the current working directory to that of the supplied script by default. Alternative an additional flag could be implemented to cause this to happen.

I just tried doing this. It does make a "Terminal" option available in "Open with". However, actually running it causes it to run the script in a new tab in terminal but alas without the correct CWD set. So the script fails. (tries to run in ~ instead of the folder in which it is located)

As I understand what you write, this is expected to fail without a change to Terminal. Is this correct?

Would it be possible to execute it with "xterm" (or some other terminal) instead and then have it use the correct CWD?

thomasdn avatar Nov 17 '20 09:11 thomasdn

As I understand what you write, this is expected to fail without a change to Terminal. Is this correct?

Yes, at the moment you would have to build and install the aforementioned branch yourself to get the correct CWD. I have put in review request to the elementary desktop developers but I do not know when a stable release containing this fix will be released. Hopefully it will be in elementary 6.0.

jeremypw avatar Nov 17 '20 11:11 jeremypw

Would it be possible to execute it with "xterm" (or some other terminal) instead and then have it use the correct CWD?

You could try it - you would need to check the documentation of the terminal you are using to see what form of commandline is required to launch a script and then modify the desktop or contract file accordingly.

jeremypw avatar Nov 17 '20 11:11 jeremypw

As I understand what you write, this is expected to fail without a change to Terminal. Is this correct?

Yes, at the moment you would have to build and install the aforementioned branch yourself to get the correct CWD. I have put in review request to the elementary desktop developers but I do not know when a stable release containing this fix will be released. Hopefully it will be in elementary 6.0.

OK. When is 6.0 release planned? Is there a public roadmap / release schedule somewhere?

thomasdn avatar Nov 17 '20 11:11 thomasdn

Further information can be found here: https://blog.elementary.io/updates-for-july-2020/

Terminal code is no longer buildable on elementary 5 (with the default libraries) I am afraid. There isn't a fixed release schedule as a lot of the work is done by volunteers when they have time. You can get a pre-release copy of elementary 6 but it is not production ready (I run it in a virtual machine).

jeremypw avatar Nov 17 '20 11:11 jeremypw

Further information can be found here: https://blog.elementary.io/updates-for-july-2020/

Terminal code is no longer buildable on elementary 5 (with the default libraries) I am afraid. There isn't a fixed release schedule as a lot of the work is done by volunteers when they have time. You can get a pre-release copy of elementary 6 but it is not production ready (I run it in a virtual machine).

Is there anything I can do at this time to enable a user to run a script in a terminal from the GUI? Either by creating a desktop file or something else? Maybe even "installing" my script as some kind of application?

thomasdn avatar Dec 04 '20 15:12 thomasdn

Sorry, I cannot think of a way to get an arbitrary script to run in the current working directory simple by clicking on it in Files without an amendment to either FIles or Terminal (and in both cases the next stable release will be in elementary 6.0). There may be a clever way for the script itself to determine what the appropriate directory is from environment variables. What Terminal does in elementary/granite#477 is get the directory from command_line.getenv ("PWD") where command_line is the GLib.ApplicationCommandLine used to invoke terminal. Perhaps you can do something similar in your script?

jeremypw avatar Dec 04 '20 17:12 jeremypw

You could make the script into an "application" that takes a folder as a parameter but then you would have to use the "Open with ..." option in the background context menu to launch it.

jeremypw avatar Dec 04 '20 17:12 jeremypw

Will the next release of Elementary OS include a way to run shellscripts from the GUI?

thomasdn avatar Jul 15 '21 11:07 thomasdn

Related to #482 and maybe #311

jeremypw avatar Nov 17 '21 10:11 jeremypw