4

I wrote a simple C program that takes any number of text parameters and echos them out.

int main(int argc, char*argv[]){
  for (int i=1;i<argc;i++){
    for (int j=0;j<strlen(argv[i]);j++){
      printf("%c", argv[i][j]);
    }
  }
}

Running the code, it seems to be working as intended, such as

$./echo hello world
hello world

But if I add exclamation marks to the input, it goes haywire.

$./echo hello world!!
hello world./echothehelloworld

And the more exclamation marks I add at the end, it repeats to the output exponentially.

William Pursell
  • 204,365
  • 48
  • 270
  • 300
harshk0
  • 41
  • 1
  • 6
    `!` is a special character to your shell. See [**Which characters need to be escaped when using Bash?**](https://stackoverflow.com/questions/15783701/which-characters-need-to-be-escaped-when-using-bash) – Andrew Henle Feb 24 '21 at 15:11
  • Not related to the C program, see https://stackoverflow.com/questions/24980679/double-exclamation-in-bash-script/24980706 – interjay Feb 24 '21 at 15:12
  • https://www.gnu.org/software/bash/manual/html_node/History-Interaction.html – ilkkachu Feb 24 '21 at 16:22
  • 1
    @JohnBollinger, note that double-quotes _don't_ work to disable history expansion, that would still expand the last command within the double quotes. You need to use single quotes or backslashes instead. Or just `set +H` to get rid of the whole blasted thing for good. – ilkkachu Feb 24 '21 at 16:23

1 Answers1

3

You need to escape your arguments, an unquoted or double-quoted !! gets replaced by the shell with the last command you ran, if history expansion is enabled (it is by default in an interactive shell). Aside from quoting the ! to prevent history expansion for one command, you can disable it for the current shell with set +H.

A common use of !! is to run the last command with root privileges like this:

$ whoami
marco
$ sudo !!
root

Your C code is fine, this will work as intended (note the double quotes):

$ ./echo "hello world!!"
ilkkachu
  • 6,221
  • 16
  • 30
Marco
  • 7,007
  • 2
  • 19
  • 49
  • 1
    double-quotes don't work to stop history expansion, see e.g. [Bash's manual](https://www.gnu.org/software/bash/manual/html_node/History-Interaction.html): "When using the shell, only [backslash] and `'` may be used to escape the history expansion character," – ilkkachu Feb 24 '21 at 16:26