What is the purpose of the : (colon) GNU Bash builtin?

前端 未结 12 706
梦如初夏
梦如初夏 2020-11-22 14:01

What is the purpose of a command that does nothing, being little more than a comment leader, but is actually a shell builtin in and of itself?

It\'s slower than inse

相关标签:
12条回答
  • 2020-11-22 14:08

    Two more uses not mentioned in other answers:

    Logging

    Take this example script:

    set -x
    : Logging message here
    example_command
    

    The first line, set -x, makes the shell print out the command before running it. It's quite a useful construct. The downside is that the usual echo Log message type of statement now prints the message twice. The colon method gets round that. Note that you'll still have to escape special characters just like you would for echo.

    Cron job titles

    I've seen it being used in cron jobs, like this:

    45 10 * * * : Backup for database ; /opt/backup.sh
    

    This is a cron job that runs the script /opt/backup.sh every day at 10:45. The advantage of this technique is that it makes for better looking email subjects when the /opt/backup.sh prints some output.

    0 讨论(0)
  • 2020-11-22 14:10

    It's similar to pass in Python.

    One use would be to stub out a function until it gets written:

    future_function () { :; }
    
    0 讨论(0)
  • 2020-11-22 14:12

    You could use it in conjunction with backticks (``) to execute a command without displaying its output, like this:

    : `some_command`
    

    Of course you could just do some_command > /dev/null, but the :-version is somewhat shorter.

    That being said I wouldn't recommend actually doing that as it would just confuse people. It just came to mind as a possible use-case.

    0 讨论(0)
  • 2020-11-22 14:16

    Historically, Bourne shells didn't have true and false as built-in commands. true was instead simply aliased to :, and false to something like let 0.

    : is slightly better than true for portability to ancient Bourne-derived shells. As a simple example, consider having neither the ! pipeline operator nor the || list operator (as was the case for some ancient Bourne shells). This leaves the else clause of the if statement as the only means for branching based on exit status:

    if command; then :; else ...; fi
    

    Since if requires a non-empty then clause and comments don't count as non-empty, : serves as a no-op.

    Nowadays (that is: in a modern context) you can usually use either : or true. Both are specified by POSIX, and some find true easier to read. However there is one interesting difference: : is a so-called POSIX special built-in, whereas true is a regular built-in.

    • Special built-ins are required to be built into the shell; Regular built-ins are only "typically" built in, but it isn't strictly guaranteed. There usually shouldn't be a regular program named : with the function of true in PATH of most systems.

    • Probably the most crucial difference is that with special built-ins, any variable set by the built-in - even in the environment during simple command evaluation - persists after the command completes, as demonstrated here using ksh93:

      $ unset x; ( x=hi :; echo "$x" )
      hi
      $ ( x=hi true; echo "$x" )
      
      $
      

      Note that Zsh ignores this requirement, as does GNU Bash except when operating in POSIX compatibility mode, but all other major "POSIX sh derived" shells observe this including dash, ksh93, and mksh.

    • Another difference is that regular built-ins must be compatible with exec - demonstrated here using Bash:

      $ ( exec : )
      -bash: exec: :: not found
      $ ( exec true )
      $
      
    • POSIX also explicitly notes that : may be faster than true, though this is of course an implementation-specific detail.

    0 讨论(0)
  • 2020-11-22 14:16

    I saw this usage in a script and thought it was a good substitute for invoking basename within a script.

    oldIFS=$IFS  
    IFS=/  
    for basetool in $0 ; do : ; done  
    IFS=$oldIFS  
    

    ... this is a replacement for the code: basetool=$(basename $0)

    0 讨论(0)
  • 2020-11-22 14:18

    If you'd like to truncate a file to zero bytes, useful for clearing logs, try this:

    :> file.log
    
    0 讨论(0)
提交回复
热议问题