bug-bash
[Top][All Lists]
Advanced

[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


reply via email to

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