[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Double quoted history expansion character cannot be escaped
From: |
ksitze |
Subject: |
Double quoted history expansion character cannot be escaped |
Date: |
Mon, 6 Aug 2012 16:37:22 -0700 (PDT) |
User-agent: |
G2/1.0 |
According to the bash man page, it appears that only backslash and single
quotes can escape the history expansion character ('!' by default). However,
bash refuses to escape the history expansion character when placed in double
quotes DESPITE acting as if it had actually done so.
The version of bash that I'm using:
$ bash --version
GNU bash, version 4.2.20(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Current behavior:
[1]$ mkdir ~/tmp
[2]$ cd ~/tmp
[3]$ touch hello\ world\!
[4]$ ls
hello world!
[5]$ ls hello\ world\!
hello world!
[6]$ ls "hello world!"
bash: !": event not found
[7]$ ls "hello world\!"
/bin/ls: cannot access hello world\!: No such file or directory
[8]$ touch "hello world\!"
[9]$ ls
hello world! hello world\!
[10]$ ls "hello world\!"
hello world\!
Expected behavior:
[1]$ mkdir ~/tmp
[2]$ cd ~/tmp
[3]$ touch hello\ world\!
[4]$ ls
hello world!
[5]$ ls hello\ world\!
hello world!
[6]$ ls "hello world!"
bash: !": event not found
[7]$ ls "hello world\!"
hello world!
[8]$ touch "hello world\!"
[9]$ ls
hello world!
[10]$ ls "hello world\!"
hello world\!
When using double quotes to protect word splitting after variable expansion if
the value of the variable contains the history expansion character there is no
way (other than to use `set +H`) to obtain the correct expanded value.
The alternative is to continue to treat backslash exactly as the shell does
currently; in that the backslash only escapes the double quote character (as in
"\""). In this case bash STILL displays incorrect behavior in that the
original example SHOULD have given the following results:
# [1]-[6] as in the first example...
[7]$ ls "hello world\!"
bash: !": event not found
[8]$ touch "hello world\!"
bash: !": event not found
[9]$ ls
hello world! hello world\!
[10]$ ls "hello world\!"
bash: !": event not found
I would argue against this interpretation of backslash behavior simply because
the inability to escape the history expansion character in double quotes
appears to me to be undesirable.
The only workaround I'm able to find for this bug is to extract the history
expansion character from the double quotes entirely:
[1]$ echo "hello world"\!
hello world!
As a side note, there also appears to be weird escaping in the history
expansion code as the following example illustrates (possibly related to the
above issue):
[1]$ echo "hello"
a
[2]$ echo "!e"
echo "echo hello"
echo hello
[3]$ echo " !e"
bash: !e": event not found
[4]$ echo "#!e"
bash: !e": event not found
[5]$ echo " #!e"
#!e
This is simply perverse and should be fixed as there doesn't seem to be any
reason for this behavior.
-kevin
- Double quoted history expansion character cannot be escaped,
ksitze <=