【问题标题】:Bash one-liner using ternary expressions使用三元表达式 Bash one-liner
【发布时间】:2014-03-20 23:21:37
【问题描述】:

我试图让这个 bash 脚本只写在一行中。主要是为了好玩。 该脚本基本上编译了一个.c 脚本if($1=0)。而if($1=1),它会检查lifemp 是否存在,如果不存在,则编译它,然后使用2nd - 5th 命令行参数运行lifemp。

这是带有正常 if 语句的工作脚本:

#!/bin/bash    
cd gol

if  [ $1 -eq 0 ]; then
    make clean
    make lifemp USE_FILE=$2
elif [ $1 -eq 1 ]; then

    if [ ! -f lifemp ]; then
        make lifemp
    fi
    ./lifemp $2 $3 $4 $5
fi

这是我仅在一行中提出的。 如果$1 = 0,则运行良好。当$1 = 1 时问题就来了。 我认为这与我有一个嵌套的三元表达式来检查 lifemp 文件是否存在有关。

#!/bin/bash
cd gol && eval `[[ $1 = "1" ]] && (echo [[ ! -f lifemp ]] && (echo  "make lifemp && ./lifemp $2 $3 $4 $5") || ("./lifemp $2 $3 $4 $5")) ||  (echo "make clean && make lifemp USE_FILE=$2")`

如果有人想和我一起绞尽脑汁想办法解决,我将不胜感激!

谢谢!

【问题讨论】:

  • bash 没有三元运算符。 &&|| 运算符链的优先级与 C 中的不太一样;只有a 成功,a && b || c 才会运行b,但a 成功并且b 随后失败,c 也会运行。

标签: bash ternary-operator ternary


【解决方案1】:

我终于明白了!

这是我想出的路线

cd gol && eval `[[ $1 = "1" ]] && ([[ ! -f lifemp ]] && (echo  "make lifemp && ./lifemp $2 $3 $4 $5") || (echo "./lifemp $2 $3 $4 $5")) ||  (echo "make clean && make lifemp USE_FILE=$2")`

我基本上改变了第二个三元表达式以摆脱[[之前的回声,而是在“./lifemp $2 $3 $4 $5”之前添加了一个回声。

【讨论】:

    【解决方案2】:

    在这里,我将您的 if 语句(减去缩进)粘贴到交互式 shell 中,然后点击向上箭头,使 bash 将其显示在一行上:

    if [ $1 -eq 0 ]; then make clean; make lifemp USE_FILE=$2; elif [ $1 -eq 1 ]; then if [ ! -f lifemp ]; then make lifemp; fi; ./lifemp $2 $3 $4 $5; fi
    

    eval 总是一个坏主意,尤其是对于用户提供的数据。您现在将把参数视为代码而不是数据,如果其中任何一个包含 shell 元字符(包括空格、撇号、美元符号和 glob 字符),这将以有趣和令人兴奋的方式打破。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-22
      • 2015-05-23
      • 1970-01-01
      • 2015-02-04
      • 1970-01-01
      • 2018-04-05
      • 1970-01-01
      • 2014-03-19
      相关资源
      最近更新 更多