7

I could not find any documentation that would explain the syntax below. What does it do inside a bash script? Is it a test?

: ${foo:=bar}; export foo
toliveira
  • 1,373
  • 14
  • 27
  • 1
    Have you put it into a bash script and tested it? – Almo May 08 '15 at 14:20
  • 3
    Not quite a duplicate of that question since that doesn't cover the parameter expansion bit here (though which part of this exactly is being asked is unclear). – Etan Reisner May 08 '15 at 14:24
  • 1
    See this: http://stackoverflow.com/questions/7444504/explanation-of-this-use-of-the-colon-operator – tolanj May 08 '15 at 14:25
  • 1
    @trojanfoe Yep definite duplicate of the second link –  May 08 '15 at 14:27
  • Yeah, much better duplicate that second time. Though (and I'm clearly somewhat biased) I think my answer here is better. =) – Etan Reisner May 08 '15 at 14:32
  • @trojanfoe Strictly speaking, you are right. It is a duplicate because, since I hadn't noticed that the first and the second colon are not related one to the other, I asked just about the first one. Anyway, reading the second link I could not understand how it would apply to my question, since I couldn't not see the different roles of the two colons: they seemed to me as part of just one fixed syntax. I suggest not to mark this question as a duplicate. Other users may benefit from it if they first regard that line as I did. – toliveira May 08 '15 at 14:45
  • 1
    @toliveira It takes 5 votes to close a question, as a duplicate, or for any other reason. Often questions are mis-user-moderated on this site and the 5-vote system often stops incorrect closing of questions. My duplicate vote is nothing more than a comment, therefore, unless 4 others agree it's a duplicate. – trojanfoe May 08 '15 at 14:50
  • I've edited the preexisting question, of which I agree this is a duplicate, to have a more useful title. Perhaps the (indeed, much better) answer given here should be copied over there? – Charles Duffy May 08 '15 at 15:49
  • @CharlesDuffy, it is a duplicate if you know already that the two colons are not part of one syntax, but of two different ones, for each you should look for an explanation separately. In other words, it is a duplicate once you know half of the answer. – toliveira May 08 '15 at 21:48
  • 1
    @toliveira, well, that's part of why we mark things as duplicate and keep them in the knowledge base, instead of deleting them: When you have 5 different ways of asking the same question (depending on how much information is/isn't known), it would be wasteful to throw those away, since people who also only know the same subset of background might ask it again in the same way. Thus, your question stays in the knowledge base, even though it's closed, as a pointer to the single place being used as a source for canonical answers. – Charles Duffy May 08 '15 at 21:52
  • 1
    (Indeed, while many kind of closed questions have an option for folks with enough reputation to vote to delete them, that's not even an option [except to elected moderators and staff] for items closed as duplicates with positive reputation, because those duplicate questions are *useful* as long as they ask the question in a different enough way that someone who otherwise wouldn't be able to find the existing entry in the knowledge base could be pointed where they need to be). – Charles Duffy May 08 '15 at 21:56
  • @CharlesDuffy, thanks, now I got it. – toliveira May 08 '15 at 22:01

1 Answers1

7

The : command is the null utility:

This utility shall only expand command arguments. It is used when a command is needed, as in the then condition of an if command, but nothing is to be done by the command.

Also Bourne Shell Builtins:

Do nothing beyond expanding arguments and performing redirections. The return status is zero.

The ${foo:=bar} syntax is a special Parameter Expansion:

${parameter:=[word]}

Assign Default Values. If parameter is unset or null, the expansion of word (or an empty string if word is omitted) shall be assigned to parameter. In all cases, the final value of parameter shall be substituted. Only variables, not positional parameters or special parameters, can be assigned in this way.

Bash Reference manual entry:

${parameter:=word}

If parameter is unset or null, the expansion of word is assigned to parameter. The value of parameter is then substituted. Positional parameters and special parameters may not be assigned to in this way.

So the command line in your question:

: ${foo:=bar}; export foo

Is two commands:

  1. : ${foo:=bar}
  2. export foo

The first of which expands the variable foo and if it is empty or unset assigns it the value bar.

The second of which then exports the foo variable for sub-shells and other processes.

Community
  • 1
  • 1
Etan Reisner
  • 73,512
  • 8
  • 94
  • 138
  • Now I got the the two ":"s are independent, and that's why I couldn't find any document about them. Is the first one needed in this case? – toliveira May 08 '15 at 14:48
  • 1
    `:` at the start is the null command. `;` is a command separator. The `:` in the expansion is part of the expansion syntax and means "or empty". See the table a little ways down in [this section](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02) for some examples. – Etan Reisner May 08 '15 at 14:56
  • Thanks, I got it. But is the null command needed? "It is used when a command is needed, as in the then condition of an if command", but it is not the case here, is it? – toliveira May 08 '15 at 15:02
  • 3
    It is. The expansion `${foo:=bar}` will either expand to the value of `foo` or the string `bar`. `bar` is not likely to be a valid command and the contents of `foo` could be *anything*. Without the null command the shell would try to execute the result of the expansion. And, at best, it would error. At worst it would erase your entire system (i.e. if `foo='rm -rf /'`). – Etan Reisner May 08 '15 at 15:06