help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: quote bashslash in a shell command


From: Pascal J. Bourguignon
Subject: Re: quote bashslash in a shell command
Date: Sun, 06 Jul 2014 18:22:49 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux)

William Xu <william.xwl@gmail.com> writes:

> The shell command is:
>   echo foo.bar | sed -e 's/\..*//'
>
> which will produce "foo" on bash.
>
> If i try to pass it to shell-command-to-string:
>   (shell-command-to-string "echo foo.bar | sed -e 's/\..*//'")
>       => "\n"

When you want to put a backslash in a string, you must double it.  Here
you are backslashing the first dot.

"\." = "." 

"\n" = "
"
"\\" = "\\" = a string containing a single character, a backslash.



> Then i find i need to quote the backslash in emacs once more:
>   (shell-command-to-string "echo foo.bar | sed -e 's/\\..*//'")
>       => "foo\n"

Yes.


> Is there a function or other way that can handle this kind of backslash
> quoting automatically?

No and yes.

In Common Lisp, you could define a reader macro to be able to read
strings with another syntax than the default one, where backslash in
strings wouldn't serve to escape the following character (or have
special meaning as in "\n").  

But emacs lisp doesn't provide (yet) reader macros, therefore the syntax
for string literals is fixed. 

Now of course, there are many ways to generate strings.
For example, you could use format:

   (format  "echo foo.bar | sed -e 's/%c..*//'" ?\\)

But you will say that it doesn't help because:

1- you still have to type a format string,

2- in addition to have to be careful about backslash in the format
   string, you have to be careful about the string specifier characters,
   namely ?%:

     (format "echo %%%s%%" "hello") --> "echo %hello%"

3- the syntax for single characters still provides a special meaning to
   backslash, so it still has to be duplicated in ?\\ --> 92 = the code
   of the backslash character.



What you'd want to do, is to define a DSL, a domain specific language,
to build shell command strings.  So you could write something as:

   (pipe (echo foo.bar)
         (sed -e s/\..//))
         

But we have still the same problem, because in symbols, some special
characters need to or may be escaped, including the backslash which is
used to escape them!

   '(pipe (echo foo.bar)
          (sed -e s/\..//))
   --> (pipe (echo foo\.bar) (sed -e s/\.\.//))

There's no backspace in this sexp!

Again, what we want here, are reader macros that would let us redefine
the syntax for symbols when reading a shell sexp.




Introducing a readtable to implement reader macros in emacs lisp would
not be too complex.  I've implemented the Common Lisp reader in Common
Lisp.  Porting it to emacs lisp wouldn't be too hard.  Some refactoring
(or surgical amputation) of the emacs lisp reader, implemented in C
would be required.

-- 
__Pascal Bourguignon__
http://www.informatimago.com/
"Le mercure monte ?  C'est le moment d'acheter !"


reply via email to

[Prev in Thread] Current Thread [Next in Thread]