【问题标题】:Define function in unix/linux command line (e.g. BASH)在 unix/linux 命令行中定义函数(例如 BASH)
【发布时间】:2023-03-12 14:54:01
【问题描述】:

有时我会为某项特定任务重复多次,但可能永远不会以完全相同的形式再次使用它。它包括我从目录列表中粘贴的文件名。介于两者之间并创建一个 bash 脚本,我想也许我可以在命令行中创建一个单行函数,例如:

numresults(){ ls "$1"/RealignerTargetCreator | wc -l }

我尝试了一些方法,例如使用 eval、使用 numresults=function...,但没有偶然发现正确的语法,并且到目前为止还没有在网络上找到任何东西。 (接下来的一切都只是关于 bash 函数的教程)。

【问题讨论】:

  • 告诉我目录$1/RealignerTargetCreator中的文件数。
  • 您缺少最后的分号。 ... ; }

标签: linux bash shell unix


【解决方案1】:

在 Ask Ubuntu 上引用 my answer 的类似问题:

bash 中的函数本质上是命名的复合命令(或代码 块)。来自man bash

Compound Commands
   A compound command is one of the following:
   ...
   { list; }
          list  is simply executed in the current shell environment.  list
          must be terminated with a newline or semicolon.  This  is  known
          as  a  group  command. 

...
Shell Function Definitions
   A shell function is an object that is called like a simple command  and
   executes  a  compound  command with a new set of positional parameters.
   ... [C]ommand is usually a list of commands between { and },  but
   may  be  any command listed under Compound Commands above.

没有给出任何理由,只是语法。

尝试在wc -l 后面加分号:

numresults(){ ls "$1"/RealignerTargetCreator | wc -l; }

【讨论】:

  • 嗯,这很简单! (我的意思是分号)。同样,深入了解 shell 的工作原理总是好的。
  • 分号是必需的,因为} 不是控制字符并且不会终止命令。注意echo } 只是输出文字字符串。
  • @chepner 这只是将问题推低了一层。那些创建语法的人可以使} 专用于函数。例如zsh 对foo () {echo foo} 没有问题。
  • 我描述的是,而不是可能是
  • @chepner 我说这不是必要的,它只是语法的方式。
【解决方案2】:

你可以得到一个

bash: syntax error near unexpected token `('

如果您已经有一个与您尝试定义的函数同名的alias,则会出错。

【讨论】:

    【解决方案3】:

    不要使用ls | wc -l,因为如果文件名中有换行符,它可能会给你错误的结果。你可以改用这个函数:

    numresults() { find "$1" -mindepth 1 -printf '.' | wc -c; }
    

    【讨论】:

    • 谢谢。加深一个人的 bash 技能总是好的!只是好奇,文件名中怎么会有换行符?
    • 您可以使用touch $'file\nwith\nline' 来创建带有换行符的文件名
    • @abalter 是的。这就是为什么它是一个口头禅:Don't parse ls output.
    【解决方案4】:

    最简单的方法可能是回显您想要返回的内容。

    function myfunc()
    {
        local  myresult='some value'
        echo "$myresult"
    }
    
    result=$(myfunc)   # or result=`myfunc`
    echo $result
    

    无论如何here,您可以找到用于更高级目的的好方法

    【讨论】:

      【解决方案5】:

      您也可以计算没有find 的文件。使用数组,

      numresults () { local files=( "$1"/* ); echo "${#files[@]}"; }
      

      或使用位置参数

      numresults () { set -- "$1"/*; echo "$#"; }
      

      为了匹配隐藏文件,

      numresults () { local files=( "$1"/* "$1"/.* ); echo $(("${#files[@]}" - 2)); }
      numresults () { set -- "$1"/* "$1"/.*; echo $(("$#" - 2)); }
      

      (从结果中减去 2 以补偿 ...。)

      【讨论】:

      • 第一个隐藏文件函数可以使用dotglob,因为它无论如何都在使用数组。
      • 嗯,由于某种原因,我记得 dotglob 也匹配 ...,但它没有。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-14
      • 2011-04-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多