什么是空操作,用例[:]在bash?(What is the use case of noop [:

2019-06-28 08:20发布

我搜索了在bash(:)空操作,但无法找到任何有用信息。 这是什么经营者的具体目的或用途的情况下?

我试过以下,它的工作是这样对我来说:

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

请让我知道,这个运营商实时或者它是强制性使用它的任何地方的使用情况。

Answer 1:

它的存在,更由于历史的原因。 内置冒号:是完全等同于true 。 这是传统的使用true无限循环,当返回值是很重要的,例如:

while true; do
  echo 'Going on forever'
done

这是传统的使用:当shell语法需要一个命令,但是你什么都没有做。

while keep_waiting; do
  : # busy-wait
done

:内置日期一路回汤普森壳 ,它是目前在Unix的V6发动机 。 :是为汤普森外壳的标签指示goto语句。 标签可以是任何文字,所以:弯了腰为注释指示器(如果没有goto comment ,然后: comment是一个有效的注释)。 在Bourne shell中没有goto但保留:

使用一个常见的成语:: ${var=VALUE}这台varVALUE如果是取消设置并做什么,如果var已被设置。 该构建体只存在于一个变量替换的形式,并且该变量替换需要以某种方式的命令的一部分:一个无操作命令提供很好。

又见什么用途结肠内置的服务? 。



Answer 2:

我用它的if语句,当我注释掉所有代码。 例如你有一个测试:

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

但你想暂时注释掉一切包含在内:

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

这导致的bash给一个语法错误:

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

Bash可以没有空块(WTF)。 所以你添加一个空操作:

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

或者您可以使用无操作注释掉行:

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


Answer 3:

你可以使用:以供应成功,但并不做任何事情的命令。 在这个例子中“冗长”命令默认关闭,通过将其设置到: 。 该“V”选项,打开它。

#!/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  


Answer 4:

如果你使用set- e然后|| : || :是,如果失败发生在没有退出脚本(它明确地使它通过)的好方法。



Answer 5:

忽略alias参数

有时您想拥有的是不带任何参数的别名。 你可以用做:

> alias alert_with_args='echo hello there'

> alias alert='echo hello there;:'

> alert_with_args blabla
hello there blabla

> alert blabla
hello there


Answer 6:

其中一个用途是作为多行注释,或通过结合使用它与这里的文件中注释掉的用于测试目的代码的一部分。

: << 'EOF'

This part of the script is a commented out

EOF

不要忘了使用引号EOF让里面的任何代码不会得到评估,如$(foo) 。 它也可能会使用一个直观的终结名字一样值得NOTESSCRATCHPAD ,或TODO



Answer 7:

我的两位。

嵌入POD评论

一个相当时髦的应用:是嵌入的bash脚本POD的意见 ,使手册页可以快速生成。 当然,最终会重写整个剧本在Perl ;-)

运行时函数结合

这是一种代码模式在运行时绑定的功能。 网络连接,有一个调试功能只做如果某标志设置的东西:

#!/bin/bash
# noop-demo.sh 
shopt -s expand_aliases

dbg=${DBG:-''}

function _log_dbg {
    echo >&2 "[DBG] $@"
}

log_dbg_hook=':'

[ "$dbg" ] && log_dbg_hook='_log_dbg'

alias log_dbg=$log_dbg_hook


echo "Testing noop alias..."
log_dbg 'foo' 'bar'

你得到:

$ ./noop-demo.sh 
Testing noop alias...
$ DBG=1 ./noop-demo.sh 
Testing noop alias...
[DBG] foo bar


Answer 8:

有时无操作子句可以使代码更易读。

这可能是见仁见智,但这里有一个例子。 让我们假设你已经创建,通过采取两台Unix路径工作的功能。 它计算一个路径需要cd到另一个“改变路径”。 你把你的函数的限制,该路径必须同时启动一个“/”或两者绝不能。

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

一些开发商将要删除的任何操作,但是这将意味着否定条件:

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

现在-in我的意见 - 它不是那么清楚从if子句中,你要跳过做功能的条件。 为了消除空操作,这样做显然,你会想如果 - 子句搬出功能:

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

这看起来更好,但是我们不能做很多次这样的; 我们要检查的功能内进行。

那么,如何往往会出现这种情况? 不经常。 也许一次或两次。 这种事往往不够,你应该意识到这一点。 当我认为它提高了我的代码的可读性(无论使用何种语言),我不使用它,避而远之。



Answer 9:

有些涉及到这样的回答 ,我觉得这是无操作相当方便破解通晓多国语言的脚本。 例如,在这里既可以让bash和vim脚本有效的评论:

":" #    this is a comment
":" #    in bash, ‘:’ is a no-op and ‘#’ starts a comment line
":" #    in vimscript, ‘"’ starts a comment line

当然,我们可能已经使用true一样好,但:作为一个标点符号标志,而不是一个无关紧要的英文单词清楚地表明,这是一个语法标记。


至于为什么会有人做这样一件棘手的事情写一个脚本通晓(除了它是凉):它在那里我们通常会写一些脚本文件在几种不同的语言,有文件证明的情况下有用的X指的是文件Y

在这种情况下,这两个脚本在一个单一的,多语种的文件结合避免了任何工作X确定路径Y (那简直是"$0" )。 更重要的是,它可以更加方便走动或分发程序。

  • 一个常见的例子。 有一个著名的,长期与shebangs问题:大多数系统(包括Linux和Cygwin)只允许一个要传递给解释的说法。 下面的家当:

     #!/usr/bin/env interpreter --load-libA --load-libB 

    将触发以下命令:

     /usr/bin/env "interpreter --load-libA --load-libB" "/path/to/script" 

    而不是预期的:

     /usr/bin/env interpreter --load-libA --load-libB "/path/to/script" 

    因此,你最终会写一个包装脚本,如:

     #!/usr/bin/env sh /usr/bin/env interpreter --load-libA --load-libB "/path/to/script" 

    这是polyglossia进入阶段。

  • 更具体的例子。 我曾经写过一个bash脚本,除其他事项外,调用Vim的。 我需要给Vim的额外的设置,这可能与该选项来完成--cmd "arbitrary vimscript command here" 。 然而,该设置是相当大,因此,在一个字符串内联这本来是可怕的(如果有的话可能)。 因此,更好的解决方案是把它写在extenso在一些配置文件,然后使Vim读取该文件-S "/path/to/file" 。 因此,我结束了一个多语种的bash / vim脚本文件。



文章来源: What is the use case of noop [:] in bash?
标签: bash shell noop