0

I have this function in my ~/.zshrc

async () {
    if ! [[ $# -gt 0 ]];then
        echo "Not enough arguments!"
    fi
    local busus="$IFS"
    export IFS=" "
    echo "$* &"
    command "$* &"
    export IFS="$busus"
}

and an alias

alias word='async "libreoffice --writer"'

The echo "$* &" line is used only for debugging. When I run word, libreoffice --writer & is shown on the screen (no extra spaces or newlines), but nothing happens. I also tried executing command libreoffice --writer & and it worked perfectly. (My current shell is zsh) What is wrong?

Thanks

1
  • Remove the extra quotes after command Commented Jun 4, 2022 at 9:07

2 Answers 2

3

Usually (especially in bash), the problem is that people aren't using enough double-quotes; in this case, it's the opposite: you're using too many double-quotes. The basic problem is that the command name and each of the arguments to it must be a separate "word" (in shell syntax), but double-quoting something will (usually) make the shell treat it as all one word. Here's a quick demo:

% echo foo
foo
% "echo foo"
zsh: command not found: echo foo

Here, the double-quotes make the shell treat " foo" as part of the command name, rather than as a delimiter and an argument after the command name. Similarly, when you use "$* &", the double-quotes tell the shell to treat the entire thing (including even the ampersand) as a single long word (and pass it as an argument to command). (BTW, the command isn't needed, but isn't causing any harm either.)

The standard way to do this is to use "$@" instead -- here the $@ acts specially within double-quotes, making each argument into a separate word. In zsh, you could omit the double-quotes, but that can cause trouble in other shells so I recommend using them anyway.

Also, don't mess with IFS. You don't need to, and it opens a can of worms that's best left closed. And if there are no arguments, you should return immediately, rather than continuing and trying to run an empty command.

But there's another problem: in the alias, you double-quote "libreoffice --writer", which is going to have pretty much the same effect again. So remove those double-quotes. But keep the single-quotes around the alias, so it'll be defined as a single alias.

So here's my proposed correction:

async () {
    if ! [[ $# -gt 0 ]];then
        echo "Not enough arguments!"
        return 1    # Do not continue if there's no command to run!
    fi
    echo "$* &"    # Here quoting is appropriate, so it's a single argument to echo
    "$@" &
}

alias word='async libreoffice --writer'
Sign up to request clarification or add additional context in comments.

Comments

1

Using "$@" directly is more reliable:

async () { [ "$#" -gt 0 ] && "$@" & }

alias word='async libreoffice --writer'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.