3

Linux Mint LMDE5 is a Debian derivative. On the desktop you can create launchers p.e. via GUI, with which you can not only link something, but also store smaller bash code in it. After creating, the launcher can moved to other folder.

Location of the follow .sh file and launcher:

/home/user_name/desktop/a/b/c

With the following code you can print the path to a bash file when you execute it.

Content of the .sh file:

#!/bin/bash
script_path=$(dirname "$(readlink -f "$0")")"/"
echo "$script_path"
sleep 100

Output of the .sh file:

/home/user_name/desktop/a/b/c

The not working launcher "solution":

Content of the launcher file:

bash -c 'launcher_path=$(dirname "$(readlink -f "$0")")"/"; echo "$launcher_path"; sleep 100'

Output of launcher by terminal:

/home/user_name/ # but that should be: /home/user_name/desktop/a/b/c

What does "launcher" mean:

This is a .desktop file, which is common on Linux Mint and LMDE. The file has similarities in structure and tasks to a ".lnk" file under Windows.

Two How too`s for creating "launcher" by Linux Mint GUI:

Sample content of a "launcher" (.desktop file):

[Desktop Entry]
Name=test
Exec=bash -c 'xed /home/user/desktop/sample_file.txt'
Comment=
Terminal=true
Icon=cinnamon-panel-launcher
Type=Application
Name[de_DE]=Sample for a launcher file, which open a textfile, which is located on desktop.

Concretization:

Only a suitable modification of the following command line of the launcher is searched:

bash -c 'launcher_path=$(dirname "$(readlink -f "$0")")"/"; echo "$launcher_path"; sleep 100'

It is not looking for any additional scripts or modifications of the operating system.

Alfred.37
  • 110
  • 1
  • 19
  • If you have a working solution, what's the question? Does the script need to be a one-liner? – GChuf Apr 04 '23 at 07:44
  • Dont have a working solution. The output of the starter "solution" isn't the wanted one. Please read the question again. – Alfred.37 Apr 04 '23 at 08:07

1 Answers1

2

If you want to know the directory that contains the running script you shouldn't use bash -c, instead you can symlink your script to a user owned directory that contains executable files (commonly ~/.local/bin and ~/bin), and use it the Exec key of your .desktop file. Since you're using Bash you can also replace $0 with the better alternative ${BASH_SOURCE[0]}. (see this answer)

$ pwd
/home/user_name/desktop/a/b/c
$ cat mylauncher.sh
#!/bin/bash
script_path=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/
echo "$script_path"
$ ./mylauncher.sh
/home/user_name/desktop/a/b/c/

Adding the symbolic link to ~/bin:

$ pwd
/home/user_name/desktop/a/b/c
$ mkdir -p ~/bin
$ PATH=$HOME/bin:$PATH
$ ln -rs ./mylauncher.sh ~/bin
$ cd
$ pwd
/home/user_name
$ mylauncher.sh
/home/user_name/desktop/a/b/c/

Now you can use Exec=mylauncher.sh in your .desktop file. Some systems already include a check for ~/bin and ~/.local/bin in the .profile file. If not you can add this to it:

if [ -d "$HOME/bin" ]; then
    PATH=$HOME/bin:$PATH
fi

if [ -d "$HOME/.local/bin" ]; then
    PATH=$HOME/.local/bin:$PATH
fi

GNU ln supports the -r option which allows using relative paths with ease. See ln(1).


Another option would be using the special field %k in the Exec setting as an argument. This field expands to the location of the running .desktop file. Note that according to the spec it may be an URI or a path.

[Desktop Entry]
Version=1.0
Name=Test
Exec=bash -c 'desktop_file=${1#*://}; dir=$(dirname "$(readlink -f "$desktop_file")"); echo "$dir"; sleep 1000' -- %k
Terminal=true
Type=Application

${1#*://} strips the protocol part in case %k expands to a file:// URI.

don_aman
  • 1,353
  • 3
  • 9
  • @Eddy763 Your suggested edit came up in review. Please keep in mind that the purpose of SE sites is not to get help just for the person asking the question. Don_aman's answer contains solution for you, _but_ it also contains a _lot_ of information that can be relevant to other people. As your suggested edit would make the answer much less useful, I rejected it. As this resolves your issue, you should accept the answer as-is. – Peregrino69 Apr 05 '23 at 16:16
  • @don_aman Wow. The follow one "bash -c 'desktop_file=${1#*://}; dir=$(dirname "$(readlink -f "$desktop_file")"); echo "$dir"; sleep 1000' -- %k" are looks working fine on boot test machines. You can improve your answer by remove the non asked Part. Thats all above the last 10 lines. THX – Alfred.37 Apr 07 '23 at 21:03
  • @Eddy763 as pointed out by Peregrino, the first alternative may be of use to other people. next time _concretize_ from the beginning – don_aman Apr 07 '23 at 22:34
  • @don_aman The last 10 lines fit the question. Removing the other one will improve the answer. – Alfred.37 Apr 10 '23 at 14:30