shell - How do I handle multiple quotes in an alias (for bash or zsh)

07
2014-07
  • Tyler.Exposure

    I am using zsh, and I am trying to use python as a simple calculator. I'm very familiar with python, but can't seem to get the alias (or function) to work properly.

    So far I've got:

    pycalc() {
      python -c "print '$@'"
    }
    alias p=pycalc
    

    No matter what I do, it returns zsh: no matches found: 123*123 (123*123 being the math problem).

    Any ideas???

  • Answers
  • Bob J

    Bash
    Add the following to .bashrc

    pycalc() {
      python -c "print \"%f\" % float($@)"
    }
    alias p=pycalc
    

    You can append it with the echo command.
    One-line:

    echo -e 'pycalc() {\n  python -c \"print \\\"%f\\\" % float($@)\"\n}\nalias p=pycalc' >> .bashrc
    

    Multi-line:

    echo -e 'pycalc() {
      python -c \"print \\\"%f\\\" % float($@)\"
    }
    alias p=pycalc' >> .bashrc
    

    You can now use p

    $ pycalc 12+12
    24.000000
    $ pycalc 12*12
    144.000000
    $ p 12+12
    24.000000
    $ p 12*12
    144.000000
    

    As Michael Righi noted in his answer, if you have file like 12*12, it will be matched by the 12*12 so you may want to enclose it in double quotes. You can also enclose it in single quotes. His solution works for bash too.

  • Michael Righi

    zsh

    Add this to .zshrc:

    pycalc() {
      python -c "print $@"
    }
    alias p=pycalc
    

    In your Z shell, use it like this:

    $ p 12+12
    24
    $ p "12*12"
    144
    

    Notice you need the double quotes when the statement contains a globbing character such as the asterisk.

    Or, you could turn off globbing for that alias:

    pycalc() {
      python -c "print $@"
    }
    alias p='noglob pycalc'
    

    That eliminates the need for the double quotes when you use it:

    $ p 12+12
    24
    $ p 12*12
    144
    

  • Related Question

    shell - Bash/ZSH: Undoing 'disown'
  • nisc

    Is there a way to 'reattach' a process to the shells job table after it it has been 'disowned'?

    Edit: $SEARCHENGINE totally fails me. Doesn't look too good.


  • Related Answers
  • lornix

    Considering how linux jobs and process ownership works, I'm afraid it's not really possible to re-own a process, without help from the adopting process.

    A parent may 'disown' a child, which is then 'adopted' by the process named 'init'. System security prevents someone from grabbing someone else's processes. When you disown it, a process becomes someone else's (init's) to control. You as the 'user' could still kill the process, but you can't get it back. Attempting to coerce init to return your process is unlikely to work, as init doesn't even read mail.

    As mean as it sounds, it really boils down to the answer of "Don't do that!".

  • Thom

    While I assume this doesn't help anyone in the unfortunate situation of having disowned the wrong process, if you were to banish disown from your workflow and replace it with:

    https://github.com/nelhage/reptyr

    You would be able to reparent any process (i.e. move it inside screen).

  • Gilles

    Sorry, no. In principle, it would be possible, since disowning merely changes some shell internal state — it basically removes the process ID from a list, and it could be put back without too much hassle (you'd have to be a little careful in testing that the reattached pid is in the right session, but that's not insurmountable). But none of the usual shells (bash, ksh, tcsh, zsh) seem to have a way to re-add . (Though with zsh you can write to the jobstates, jobdirs and jobtext associative arrays; I don't know how much you can achieve that way.)

    If you want the shell to send signals to the disowned process as it does for its owned subprocesses, you can write a stub job that waits until it receives a signal and sends the same signal to the disowned process. You can send SIGSTOP and SIGCONT to the disowned process to simulate Ctrl+Z and bg. None of this will be quite as convenient as re-owning.

  • Scott

    What are the circumstances? If you just want to get your terminal back for a while, you could use GNU Screen instead. It doesn't quite detach the process from a terminal - Screen emulates one for the process's benefit - but you can attach and detach it from the real terminal that you're using. You can even detach a screen, log out, then log back in and re-attach to the same screen.