0

I'm trying to create a desktop shortcut which launches a terminal app with commandline arguments which contains a path to a file with a randomly generated number in the filename.

I've tried everything i could think of but have not been able to find anything that works.

This is what the Exec line looks like now:

Exec=sudo nwipe --logfile=/home/admin/Documents/nwipe/Certificate{$((1 + $RANDOM % 99999))}.pdf

That line seems to work fine directly in a terminal window, but not when i'm trying to launch the desktop shortcut.

I'm not very familiar with terminal and bash, but in PowerShell i would do something like below:

sudo nwipe --logfile=/home/admin/Documents/nwipe/Certificate$(Get-Random -Maximum 99999).pdf
1
  • Write a wrapper shell script.
    – egmont
    Commented Jul 3 at 13:00

1 Answer 1

0

That line seems to work fine directly in a terminal window, but not when i'm trying to launch the desktop shortcut.

This is because in a terminal window you interact with a shell that interprets this $((…)) you used. The Exec key in a desktop file is not interpreted by a shell. Only some parsing is done similarly to what a shell would do (e.g. splitting to words).

If you want $((…)) to be expanded like in a shell then you need to run a shell. You tagged and the syntax you used works in bash, not necessarily in sh, so you need to run bash. There are at least two ways:

  1. Either put your command in an executable script with the right shebang, then let the desktop file run the script.

  2. Or run bash -c … directly from the Exec key, using the syntax (especially quoting rules) specific to the key:

    Quoting must be done by enclosing the argument between double quotes and escaping the double quote character, backtick character (`), dollar sign ($) and backslash character (\) by preceding it with an additional backslash character. […]

    Note that the general escape rule for values of type string states that the backslash character can be escaped as (\\) as well and that this escape rule is applied before the quoting rule. As such, to unambiguously represent a literal backslash character in a quoted argument in a desktop entry file requires the use of four successive backslash characters (\\\\). Likewise, a literal dollar sign in a quoted argument in a desktop entry file is unambiguously represented with (\\$).

    […] Literal percentage characters must be escaped as %%.

    This leads to the following:

    Exec=bash -c "exec sudo nwipe \\"--logfile=/home/admin/Documents/nwipe/Certificate{\\$((1 + RANDOM %% 99999))}.pdf\\"" my-special-bash
    

    Notes:

    • exec sudo … will make bash replace itself with sudo after processing the $((…)) part. The point is we don't need bash to stay as a parent of sudo. (I think Bash may optimize things and it might replace itself with sudo even if we didn't use the explicit exec; or it might not. With the explicit exec there is no doubt.) Ultimately it would be as if you run sudo directly from the desktop file (i.e. Exec=sudo …).
    • I added additional double-quotes, the whole --logfile=… snippet is double-quoted in the shell code. The additional quotes are not strictly needed in this case (unless your $IFS is strange), but in general they should be there. Treat them as examples of how to properly escape double-quotes that shall be seen by our bash -c.
    • Inside $((…)) a string like varname is expanded as if it was $varname, this applies to RANDOM as well. One less $ to escape.
    • You probably want Terminal=yes in the desktop file.
    • The trailing my-special-bash may be omitted here, but if you ever need to add positional parameters, then something should be there.

General note:

  • $RANDOM in Bash expands to a random integer between 0 and 32767, so $RANDOM % 99999 is equivalent to $RANDOM, 99999 is just to big to make a difference. My answer does not fix this; I decided to show how to properly escape this syntax in case anyone wants to use a lower number for which using % actually makes sense.
1
  • Wow thank you Kamil, your explanation was great. I learned alot and managed to do what i tried to do. I hope your answer will help others as well.
    – zyntrax
    Commented Jul 5 at 6:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .