Fish shell - Interpolation in nested quotes

Viewed 974

I'm trying to write a fish function to display a notification after long commands have completed running. I have it working, but I'd like to know if there is a nicer way to get interpolation working with nested quotes.

function record_runtime --on-event fish_postexec
    set text \"$argv took $CMD_DURATION\"
    set command "display notification $text"
    if [ $CMD_DURATION -gt 60000 ]
        osascript -e "$command"
    end
end

I was hoping for a one liner like osascript -e 'display notification "$argv took $CMD_DURATION"' but could not find a combination that worked.

1 Answers

So, what you want to do is execute osascript with one argument, that contains the command "display notification" and the value of $argv, the word "took" and the value of $CMD_DURATION. That means you want fish to expand these variables.

Importantly, fish does not expand variables in single-quotes (''), which is why your other attempt failed. Variables are only expanded in double-quotes or outside of quotes entirely.

Now I don't have a macOS machine to test, but if osascript also allows single quotes, this is simple:

function record_runtime --on-event fish_postexec
    if [ $CMD_DURATION -gt 60000 ]
        osascript -e "display notification '$argv took $CMD_DURATION'"
    end
end

the single-quotes inside the double-quotes have no special meaning, so the $argv and $CMD_DURATION are expanded.

If osascript needs double-quotes here, you have to escape the inner double-quotes:

function record_runtime --on-event fish_postexec
    if [ $CMD_DURATION -gt 60000 ]
        osascript -e "display notification \"$argv took $CMD_DURATION\""
    end
end
Related