Is this a bug in GNU Bash?

I found this while trying to reinforce my scripts for string security:

$ echo '!!' !! $ echo "$(echo '!!')" echo "$(echo 'echo '!!'')" #<~ the console echoes the line with expanded history here echo !! #<~ the result 

It seems to me that the innermost quotation, which is single, should not expand anything, a variable, subshell or otherwise, but in this case it expands !! to the last line entered. Looks like he shouldn't do that.

I ask you: is this a bug in Bash, and if you can use the quotation mark extension of a subitem that displays an exclamation point?

(Using Bash 4.1.007 on Linux)

Edit:

If the above is not a mistake, why does it behave as expected?

 $ foo='some value' $ echo "$(echo 'neither $foo nor `this subshell` should expand here')" neither $foo nor `this subshell` should expand here 
+4
source share
3 answers

I agree.

 $ echo "$(echo '!!')" echo "$(echo 'echo $(echo '!!')')" echo $(echo !!) 

must do the same as

 $ echo $(echo '!!') !! 

I don’t see how to explain the difference based on the documentation for expanding the story .

It is also strange how the story extension documents are completely separate from the rest of the shell extension documentation .

zsh echoes !! for both, at least with my setup.

+2
source

It may be a mistake, but set +H will disable it (by default it is by default in scripts).

Here are the relevant sections on the manual page:

Enclosing characters in double quotation marks preserves the literal meaning of all characters inside quotation marks, except for $, `, \ and when the story extension is turned on !! The $ and `characters retain their special meaning in double quotes. The backslash retains a special meaning, followed by one of the following characters: $, `,", \ or <newline>. The double quote can be specified in double quotes preceding it with a backslash. If enabled, the history extension will be executed if only! appears in double quotes. using backslash. Backslash preceding! is not removed.

and

The extension of the story is performed immediately after the completion of the full line; read before the shell breaks it into words .... The extension of the story introduces the appearance of the character of the extension of the story that is! from by default. Only a backslash (\) and single quotes can indicate the history of an extension character.

+1
source

If you put your two bangs in a variable, you will get the expected results (and even greater string security).

 ( #set -xv twobangs='!!' echo "${twobangs}" echo "$(echo "${twobangs}")" echo "$(echo 'echo "${twobangs}"')" echo "$(echo "echo "${twobangs}"")" echo "$(echo "echo ""${twobangs}")" #set -xv ) 

In a similar note, you can sometimes use the concatenation of an embedded shell string and simply place a character such as '!' in single quotes to prevent shell interpretation.

 ( set -H echo "Hello, world"'!' (sleep 10) & #trap "echo exit; kill -TERM $!" EXIT HUP INT QUIT TERM # troublemaker #trap "echo exit; kill -TERM $"'!' EXIT HUP INT QUIT TERM trap "echo exit; kill -TERM $"'!'"; echo killed" EXIT HUP INT QUIT TERM sleep 5 ) 
+1
source

Source: https://habr.com/ru/post/1339568/


All Articles