BASH:如何将参数传递给别名:CANNOT USE A FUNCTION - Bash 条件句法 [英] BASH: how to pass in arguments to an alias: CANNOT USE A FUNCTION - syntax of Bash conditionals

查看:17
本文介绍了BASH:如何将参数传递给别名:CANNOT USE A FUNCTION - Bash 条件句法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题的不同之处在于经典的使用函数"答案将不起作用.向现有别名问题添加注释相当于向 Yahoo 发送建议电子邮件.

我正在尝试编写宏来绕过 BASH 可怕的 IF 语法.你知道的,[, [[, ((...BASH: 流控制的 PHP...只需添加另一个括号.我还在等待 "(((((((")) 形式.不太确定为什么 BASH 没有重新使用(",因为("在 if 语句中没有真正的语义.

I am trying to write macros to get around BASH's horrendous IF syntax. You know, the [, [[, ((...BASH: the PHP of flow control...just add another bracket. I'm still waiting for the "(((((((" form. Not quite sure why BASH didn't repurpose "(", as "(" has no real semantics at the if statement.

我们的想法是为 [、[[ 和 ((特设!),祝你好运尝试谷歌[[".

The idea is to have named aliases for [, [[ and (( , as each one of these durned test-ish functions has a frustratingly different syntax. I honestly can never remember which is which (how COULD you? It's completely ad hoc!), and good luck trying to google "[[".

然后,我将使用名称作为助记符,并使用别名来消除间距要求方面完全可怕的差异.示例:"whatdoyoucallthisIf" 代表 "((","shif" (代表 shell if),"mysterydoublesquarebacketif" 代表那个糟糕的 [[ 似乎与 [ 做同样的事情,只是它没有.

I would then use the names as a mnemonic, and the alias to get rid of the completely awful differences in spacing requirements. Examples: "whatdoyoucallthisIf" for "((", "shif" (for shell if), "mysterydoublesquarebacketif" for that awful [[ thing which seems to mostly do the same thing as [, only it doesn't.

因此,我必须有以下形式:

别名 IFREPLACEMENT="if [ $@ ]; then"

alias IFREPLACEMENT="if [ $@ ]; then"

但显然不是 $@,它只会将当前参数列表固定到运行别名的 shell.

But obviously not $@, which would just cement in the current argument list to the shell running the alias.

函数将在这种情况下起作用,因为函数:

Functions will not work in this case, as the function:

function IFREPLACEMENT {
    if [ $@ ]; then
}

是非法的.

在 CSH 中,您可以说别名 abc blah blah!*!1 等等. BASH 中是否有类似的东西(不,!* 在 BASH 中不起作用)?

In CSH, you could say alias abc blah blah !* !1, etc. Is there ANYTHING in BASH that is similar (no, !* doesn't work in BASH)?

或者是 [我只是运气不好"];?

Or am [ "I just out of luck" ]; ?

顺便说一句,这里有一些涉及 BASH 中的测试函数的令人沮丧的差异,我试图通过使用人们必须使用的明确定义的别名来避免这些差异,而不是选择错误的[[","[" 或 "((":

As an aside, here are some of the frustrating differences involving test-ish functions in BASH that I am trying to avoid by using well-defined aliases that people would have to use instead of picking the wrong "[[", "[" or "((":

  • "((" 真是令人毛骨悚然...如果一个变量包含另一个变量的名称,它会根据需要被引用到尽可能多的级别)
  • "((" 不需要像'['和'[['这样的空格
  • "((" 不需要 "$" 来取消引用变量
  • ['s "-gt" 是数字或死亡.[[似乎有任意限制.
  • '[' 和 '[[' 使用 ">" (等)作为 LEXICAL 比较运算符,但它们具有令人沮丧的不同规则,这使得它们看起来像是在进行数字比较,而实际上并非如此.
  • 对于变量:a=""(空值),[ $a == 123 ] 是语法错误,但 (( a == 123 )) 不是.

推荐答案

更新:根据@konsolebox 的反馈,现在建议始终使用[[...]] 既简单又性能好(原始答案推荐 ((...)) 用于数值/布尔测试).

Update: Based on feedback from @konsolebox, the recommendation is now to always use [[...]] for both simplicity and performance (the original answer recommended ((...)) for numerical/Boolean tests).

@Oliver Charlesworth 在对该问题的评论中提出了 not 试图隐藏底层 bash 语法的理由 - 我同意.

@Oliver Charlesworth, in a comment on the question, makes the case for not trying to hide the underlying bash syntax - and I agree.

您可以使用以下规则简化事情:

  • 始终使用 [[ ... ]] 进行测试.
    • 仅在必须兼容 POSIX 时才使用 [ ... ].如果可用,[[ ... ]] 始终是更好的选择(惊喜更少,功能更多,速度几乎是原来的两倍[1]).
    • 使用双引号,$-前缀变量引用 - 以实现稳健性和简单性(不过,双引号会带来轻微的性能损失1) - 例如,"$var";请参阅下面的 ===~ 的 RHS 例外情况.
    • Always use [[ ... ]] for tests.
      • Only use [ ... ] if POSIX compatibility is a must. If available, [[ ... ]] is always the better choice (fewer surprises, more features, and almost twice as fast[1]).
      • Use double-quoted, $-prefixed variable references - for robustness and simplicity (you do pay a slight performance penalty for double-quoting, though1) - e.g., "$var"; see the exceptions re the RHS of == and =~ below.
      • 总是在条件句的初始分隔符之后和结束分隔符之前放置一个空格(无论是 [[/(( 还是 ]]/)))
      • 切勿在变量 assignments 中的 = 周围放置空格.
      • ALWAYS put a space after the initial delimiter and before the closing delimiter of conditionals (whether [[ / (( or ]] / )))
      • NEVER put spaces around = in variable assignments.

      为了简化,这些规则比它们需要的限制更多.

      These rules are more restrictive than they need to be - in the interest of simplification.

      提示和陷阱:

      • 请注意,对于 numeric[[ ... ]] 比较,您必须使用 -eq-gt-ge-lt-le,因为<代码>==、<<=>>=用于词法比较.
        • [[ 110 -gt 2 ]] &&回声是
        • Note that for numeric comparison with [[ ... ]], you must use -eq, -gt, -ge, -lt, -le, because ==, <, <=, >, >= are for lexical comparison.
          • [[ 110 -gt 2 ]] && echo YES
          • [[ 'abc' == 'a'* ]] &&回声是
          • [[ 'abc' =~ ^'a'.+$ ]] &&回声是
          • re='^a.+$';[[ 'abc' =~ $re ]] &&echo YES # *unquoted* 使用 var.$re

          [[ ... ]]替代方案,用于纯数值/布尔测试,是使用算术评估,((...)),其性能与 [[ 相当(约慢 15-20%1);算术评估(参见 man bash 中的 ARITHMETIC EVALUATION 部分):

          An alternative to [[ ... ]], for purely numerical/Boolean tests, is to use arithmetic evaluation, ((...)), whose performance is comparable to [[ (about 15-20% slower1); arithmetic evaluation (see section ARITHMETIC EVALUATION in man bash):

          • 允许 C 风格的算术(整数)运算,例如 +-*/**, %, ...
          • 支持赋值,包括递增和递减操作(++/--).
          • 变量引用不需要$前缀.

          • Allows C-style arithmetic (integer) operations such as +, -, *, /, **, %, ...
          • Supports assignments, including increment and decrement operations (++ / --).
          • No $ prefix required for variable references.

          • 警告:在 2 种情况下,您仍然需要 $:
            • 如果您想指定一个数字基数执行预先的参数扩展,例如删除前缀:
              • var=010;(( 10#$var > 9 )) &&echo YES # 任务编号以 10 为基数
              • var=v10;(( ${var#v} > 9 )) &&echo YES # 去掉首字母'v'
              • Caveat: You still need the $ in 2 scenarios:
                • If you want to specify a number base or perform up-front parameter expansion, such as removing a prefix:
                  • var=010; (( 10#$var > 9 )) && echo YES # mandate number base 10
                  • var=v10; (( ${var#v} > 9 )) && echo YES # strip initial 'v'
                  • ((...) 奇怪的是,递归地扩展了没有 $ 的变量名,直到它的值不再是现有变量的名称:
                  • var1=10;变量2=变量1;(( var2 > 9 )) &&回声是
                  • var2 扩展为 10(!)
                  • ((...), curiously, expands a variable name without $ recursively, until its value is not the name of an existing variable anymore:
                  • var1=10; var2=var1; (( var2 > 9 )) && echo YES
                  • var2 expands to 10(!)

                  有更宽松的空格规则.

                  您甚至可以将算术表达式(包括赋值)塞入基于数字运算符的 [[ 条件中,但这可能会更加混乱;例如:

                  You can even cram arithmetic expressions, including assignments, into [[ conditionals that are based on numeric operators, though that may get even more confusing; e.g.:

                  v1=1 v2=3; [[ v1+=1 -eq --v2 ]] && echo TRUE # -> both $v1 and $v2 == 2
                  

                • 注意:在这种情况下,引用"是指对整个字符串进行单引号或双引号,而不是 - 转义未包含在任何一个字符串中的单个字符单引号或双引号.

                  Note: In this context, by 'quoting' I mean single- or double-quoting an entire string, as opposed to -escaping individual characters in a string not enclosed in either single- or double quotes.

                  1:以下代码(改编自 @konsolebox 的代码)用于性能测量:

                  1: The following code - adapted from code by @konsolebox - was used for performance measurements:

                  注意:

                  • 结果可能因平台而异 - 数字基于 OS X 10.9.3 和 Ubuntu 12.04.
                  • [[ 的速度几乎是 [ 的两倍(大约 1.9 倍)基于:
                    • [[ 中使用 不带引号的$-前缀变量引用(使用双引号变量引用会稍微减慢速度)
                    • The results can vary by platform - numbers are based on OS X 10.9.3 and Ubuntu 12.04.
                    • [[ being nearly twice as fast as [ (factor around 1.9) is based on:
                      • using unquoted, $-prefixed variable references in [[ (using double-quoted variable references slows things down somewhat)
                      #!/usr/bin/env bash
                      
                      headers=( 'test' '[' '[[/unquoted' '[[/quoted' '[[/arithmetic' '((' )
                      iterator=$(seq 100000)
                      {
                      time for i in $iterator; do test "$RANDOM" -eq "$RANDOM"; done
                      time for i in $iterator; do [ "$RANDOM" -eq "$RANDOM" ]; done
                      time for i in $iterator; do [[ $RANDOM -eq $RANDOM ]]; done
                      time for i in $iterator; do [[ "$RANDOM" -eq "$RANDOM" ]]; done
                      time for i in $iterator; do [[ RANDOM -eq RANDOM ]]; done
                      time for i in $iterator; do (( RANDOM == RANDOM )); done
                      } 2>&1 | fgrep 'real' | { i=0; while read -r line; do echo "${headers[i++]}: $line"; done; } | sort -bn -k3.3 | awk 'NR==1 { baseTime=substr($3,3) } { time=substr($3,3); printf "%s %s%%
                      ", $0, (time/baseTime)*100 }' | column -t
                      

                      输出时间从最快到最慢,较慢的时间也表示为最快时间的百分比.

                      Outputs times from fastest to slowest, with slower times also expressed as a percentage of the fastest time.

                      这篇关于BASH:如何将参数传递给别名:CANNOT USE A FUNCTION - Bash 条件句法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆