【问题标题】:Bash | pipe to bash function重击 |管道到 bash 函数
【发布时间】:2017-03-10 13:03:34
【问题描述】:

在尝试管道到 Bash 函数时,我写了这个:

example () {
    if [ -z ${1+x} ]; then local S=${@:-$(</dev/stdin)}; else local S="$1"; fi
    #echo "$S"
    echo "$S" | tr ' ' '_'
}
echo 'Moizès Júnior' | example
example 'Moizès Júnior'

Moizès_Júnior
Moizès_Júnior

但是,在另一种情况下,我收到了正确的输出以及以下错误消息:“Segmentation fault (core dumped)”。

尝试调试它我问我在函数内部编写代码以获取 STDIN 的方式是否有问题。

非常感谢。

【问题讨论】:

  • 谁是核心?重击?试试type &lt;core-dump-file&gt;
  • file 也应该给你文件名。
  • 请问,我在哪里使用file &lt;core-dump-file&gt;
  • 仅供参考 -- local var=$(something) 实际上是一个反模式,因为它的退出状态是 local(总是成功),而不是退出状态 something。最好local var; var=$(something)
  • 此外,仅查看 $1 是否为空但随后将所有 $@ 连接起来有点奇怪(无论如何,它没有定义分配给字符串的行为,由方式 - 在这种情况下使用 $* 代替)。如果要查看是否有任何参数,请查看$# -- 否则,example '' "hello" 将尝试从标准输入读取。

标签: linux bash function pipe stdin


【解决方案1】:

我不建议将整个标准输入读入一个变量。而不是:

#the main "worker" function always uses stdin/out
example_worker() { tr ' ' '_'; }

#the switcher
example() { if [[ -z "$1" ]]; then example_worker; else example_worker <<< "$1"; fi ; }

echo 'a b c' | example
example 'a b c'
#but also
example < multi_giga_file.txt

【讨论】:

  • 想象一下,我有很多函数,比如“example_worker1”、“example_worker2”、“example_worker3”、“example_worker4”......所有的行为都与你的“example_worker”相似。你会如何处理@jm666?
  • @Roger 不清楚您想要实现什么。想要连续呼叫多个工人(顺序 - 也就是像管道一样?)或一次只呼叫一个,但基于某些条件?在寻求帮助时,你需要清楚。这个问题已经得到了答案,所以最好用新的(更精确定义的)案例提出一个新问题,而且你的示例代码并没有试图调用“多个”工人......
【解决方案2】:

如果bash 负责核心转储,那肯定表明应该报告bash 中的错误。但是,您的函数可以更简单地编写为

example () {
    local S
    if (( "$#" == 0 )); then
        IFS= read -r S
        set -- "$S"
    fi
    echo "${1// /_}"
}

至少可以避免这个错误。

【讨论】:

  • 为什么说这个更简单(去掉tr ' ' '_'部分,这只是一个例子,它可以是别的)?你的代码效率更高吗?我觉得更难理解。特别是set -- "$S" 部分。
  • 它怎么不起作用,或者你在尝试example Moizès Júnior而不是example "Moizès Júnior"
  • 我的意思是emample 'Moizès Júnior'
  • @Roger, set -- "$S"$1 设置为等于"$S"。仅仅因为某件事不熟悉并不会使它复杂。 (旁白:Rich Hickey 的演讲“Simple Made Easy”很好地梳理了所有这些概念,以帮助人们分别思考它们......他建议使用“decomplecting”这个词的过程)。
  • @chepner, ...我可能在这里做的唯一更改是 IFS= read -r -d '' S || [[ $S ]] 或类似的,以便能够读取多行字符串。
猜你喜欢
  • 2012-07-12
  • 1970-01-01
  • 2019-02-16
  • 2015-07-14
  • 2017-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-16
相关资源
最近更新 更多