What is the use case of noop [:] in bash?

2019-01-21 02:09发布

I searched for noop in bash (:), but was not able to find any good information. What is the exact purpose or use case of this operator?

I tried following and it's working like this for me:

[mandy@root]$ a=11
[mandy@root]$ b=20
[mandy@root]$ c=30
[mandy@root]$ echo $a; : echo $b ; echo $c
10
30

Please let me know, any use case of this operator in real time or any place where it is mandatory to use it.

标签: bash shell noop
9条回答
放荡不羁爱自由
2楼-- · 2019-01-21 02:49

You would use : to supply a command that succeeds but doesn't do anything. In this example the "verbosity" command is turned off by default, by setting it to :. The 'v' option turns it on.

#!/bin/sh
# example
verbosity=:                         
while getopts v OPT ; do          
   case $OPT in                  
       v)        
           verbosity=/bin/realpath 
       ;;
       *)
           exit "Cancelled"
       ;;             
   esac                          
done                              

# `$verbosity` always succeeds by default, but does nothing.                              
for i in * ; do                   
  echo $i $($verbosity $i)         
done                              

$ example
   file

$ example -v
   file /home/me/file  
查看更多
趁早两清
3楼-- · 2019-01-21 02:50

Sometimes no-op clauses can make your code more readable.

That can be a matter of opinion, but here's an example. Let's suppose you've created a function that works by taking two unix paths. It calculates the 'change path' needed to cd from one path to another. You place a restriction on your function that the paths must both start with a '/' OR both must not.

function chgpath() {
    # toC, fromC are the first characters of the argument paths.
    if [[ "$toC" == / && "$fromC" == / ]] || [[ "$toC" != / && "$fromC" != / ]]
    then
        true      # continue with function
    else
        return 1  # Skip function.
    fi

Some developers will want to remove the no-op but that would mean negating the conditional:

function chgpath() {
    # toC, fromC are the first characters of the argument paths.
    if [[ "$toC" != / || "$fromC" == / ]] && [[ "$toC" == / || "$fromC" != / ]]
    then
        return 1  # Skip function.
    fi

Now -in my opinion- its not so clear from the if-clause the conditions in which you'd want to skip doing the function. To eliminate the no-op and do it clearly, you would want to move the if-clause out of the function:

    if [[ "$toC" == / && "$fromC" == / ]] || [[ "$toC" != / && "$fromC" != / ]]
    then
        cdPath=$(chgPath pathA pathB)   # (we moved the conditional outside)

That looks better, but many times we can't do this; we want the the check to be done inside the function.

So how often does this happen? Not very often. Maybe once or twice a year. It happens often enough, that you should be aware of it. I don't shy away from using it when I think it improves the readability of my code (regardless of the language).

查看更多
走好不送
4楼-- · 2019-01-21 02:54

I use it for if statements when I comment out all the code. For example you have a test:

if [ "$foo" != "1" ]
then
    echo Success
fi

but you want to temporarily comment out everything contained within:

if [ "$foo" != "1" ]
then
    #echo Success
fi

Which causes bash to give a syntax error:

line 4: syntax error near unexpected token `fi'
line 4: `fi'

Bash can't have empty blocks (WTF). So you add a no-op:

if [ "$foo" != "1" ]
then
    #echo Success
    :
fi

or you can use the no-op to comment out the lines:

if [ "$foo" != "1" ]
then
    : echo Success
fi
查看更多
等我变得足够好
5楼-- · 2019-01-21 02:58

One use is as multiline comments, or to comment out part of your code for testing purposes by using it in conjunction with a here file.

: << 'EOF'

This part of the script is a commented out

EOF

Don't forget to use quotes around EOF so that any code inside doesn't get evaluated, like $(foo). It also might be worth using an intuitive terminator name like NOTES, SCRATCHPAD, or TODO.

查看更多
孤傲高冷的网名
6楼-- · 2019-01-21 03:01

If you use set- e then || : is a great way to not exit the script if a failure happens (it explicitly makes it pass).

查看更多
趁早两清
7楼-- · 2019-01-21 03:01

Ignore alias arguments

Some times you want to have an alias that doesn't take any argument. You can do it using ::

> alias alert_with_args='echo hello there'

> alias alert='echo hello there;:'

> alert_with_args blabla
hello there blabla

> alert blabla
hello there
查看更多
登录 后发表回答